Skip to content

Instantly share code, notes, and snippets.

@canton7
Created March 21, 2012 13:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save canton7/2146783 to your computer and use it in GitHub Desktop.
Save canton7/2146783 to your computer and use it in GitHub Desktop.
Enumerable#with_props

Enumerable#with_props

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment