This is a little monkey-patch to add a new method to Enumerable, #with_props
.
You use it something like this:
[1, 2, 3, 4].each.with_props do |element, props|
puts "First? #{props.first?}"
puts "Last? #{props.last?}"
puts "Index: #{props.index}" # Or props.idx or props.i
puts "Even?: #{props.even?}"
puts "Odd?: #{props.odd?}"
end
With more ado, here's the code:
class EnumProps
attr_reader :index
alias_method :idx, :index
alias_method :i, :index
def initialize
# Index is incremented before first use
@index, @last = -1, false
end
def next; @index += 1; self; end
def last; @last = true; self.next; end
def first?; @index == 0; end
def last?; @last; end
def even?; @index.even?; end
def odd?; @index.odd?; end
def to_s
"#<EnumProps first?=#{first?} last?=#{last?} index=#{index}>"
end
end
class Enumerator
def with_props
props = EnumProps.new
current_val = self.next
next_val = self.next
loop do
yield current_val, props.next
current_val, next_val = next_val, self.next
end
yield next_val, props.last
rescue StopIteration
yield current_val, props.last if current_val
end
end