This post originated from an RSS feed registered with Ruby Buzz
by Red Handed.
Original Post: Counting At The Cloak 'N' Bind
Feed Title: RedHanded
Feed URL: http://redhanded.hobix.com/index.xml
Feed Description: sneaking Ruby through the system
Here’s how it works: the index accessor is added to the Proc. And
each time we loop, the accessor is incremented.
It takes some glue, though. Proc#bind (from Rails, originally cloaker)
is used to turn the block into a method of itself! Then with_index adds an incrementing wrapper over it.
The Method#to_proc happens when you amp it into each.
# from activesupport
class Proc
def bind(object)
block, time = self, Time.now
(class << object; self end).class_eval do
method_name = "__bind_#{time.to_i}_#{time.usec}"
define_method(method_name, &block)
method = instance_method(method_name)
remove_method(method_name)
method
end.bind(object)
end
end
# there are three interesting variables here:
# blk:: the block you've passed in.
# bound:: the same block, but now a method of itself.
# wrap:: the wrapper proc which does the counting.
def with_index(&blk)
class << blk
attr_reader :index
def even; @index % 2 0 end
def odd; @index % 2 1 end
end
i = 0
bound = blk.bind(blk)
wrap = proc do |a|
blk.instance_variable_set(’@index’, i)
x = bound[a]
i += 1
x
end
wrap
end
However, 1.9’s Enumerator#with_index
is definitely less boggling and sloppy. If you have instance variables inside the block, they’ll be lookin in the
block object for a home.