From: Matt Maycock Date: 2004-08-12T05:56:02+09:00 Subject: Re: FirstEachLast, an extension to the Enumerable module. I think the best solution would be to create some sort of objects to handle being checked for position. This way, you can change the appropriate methods based on your enum (sure, a little more work, but you can avoid O(N^2) work for last operations if you're smart...) Here's what I envisioned: ---- Enumerable Hack ---- module Enumerable class PositionVariable attr_reader :index, :enum def initialize(idx, enum) @index, @enum = idx, enum end def === (p) meth = "index_#{p}?".intern @enum.send(meth, @index) end def inspect "#{@index.inspect} : #{@enum.inspect}" end def is?(index_check) index_check.is?(self) end end def Enumerable.make_index_const(namestr) o = Object.new o.instance_eval {@name = namestr} class << o def ===(positionVar) self.is?(positionVar) end def to_s @name end def is?(positionVar) positionVar === self end end o end def each_with_pos fail "A block is needed for Enumerable#each_with_pos." unless block_given? self.each_with_index {|e, i| yield e, PositionVariable.new(i, self) } end end ---- end Enumerable Hack ---- then, in my program, I have somethnig like this: module Enumerable FIRST, LAST, PRIME, EVEN, ODD = *%w{first last prime even odd}.map {|str| Enumerable.make_index_const(str) } def index_first?(idx) idx == 0 end def index_last?(idx) self.size == idx + 1 end def index_even?(idx) idx % 2 == 0 end def index_odd?(idx) !index_even?(idx) end def index_prime?(idx) # standard prime test algorithm of your choice. end end and then you can have something like this: myenum.each_with_pos {|e, pos| case pos when Enumerable::FIRST then ... when Enumerable::LAST then .... when ... end if pos.is?(Enumerable::FIRST) then ... else ... end } it might be to `cluttery' for the enum namespace, though - but it's also just dependent on you filling stuff out for the enums - or just deciding to accept some defaults (like index_first? ...) (and overriding the bad defaults when it comes time to...) -- There's no word in the English language for what you do to a dead thing to make it stop chasing you.