```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
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.

```