Skip to content

Instantly share code, notes, and snippets.

@bdkosher
Created September 16, 2014 13:42
Show Gist options
  • Save bdkosher/13dfdc5d27a8f8b2f952 to your computer and use it in GitHub Desktop.
Save bdkosher/13dfdc5d27a8f8b2f952 to your computer and use it in GitHub Desktop.
Metaprogramming approaches to exposing "last"-ness within a traditional for loop. Pretty useless, but a good launching point for exploring metaprogramming. TODO: dynamically applied traits, mixins?, ExpandoMetaClass to override iterator() method? See http://stackoverflow.com/questions/25852346/identify-last-element-of-an-array-in-groovy-for-stat…
import groovy.transform.TupleConstructor
// approach 1. Custom subtype coercion
@TupleConstructor
class LastAwareIterator<T> implements Iterator<T> {
Iterator itr
boolean hasNext() {
itr.hasNext()
}
void remove() {
itr.remove()
}
T next() {
T obj = itr.next()
boolean last = !itr.hasNext()
obj.metaClass.isLast << { -> last }
obj
}
}
class LastAwareList<T> extends ArrayList<T> {
Iterator<T> iterator() {
new LastAwareIterator(super.iterator())
}
}
def list = [1,2,3,4,2] as LastAwareList
for (ai in list) {
if (ai.last) {
print 'and '
}
print "$ai "
} // prints: 1 2 3 4 and 2
// approach 2: dynamic traits
// ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment