On 04.06.2011 16:19, Michael Sokol wrote:
> Actually it would be possible, although very ugly.
>
> You need to evaluate in the context of the current instance
> (instance_eval) - not yield - the block you pass to the each method
> of your object (an array in this case).
>
> Then you can define a print method that behaves like a coroutine
> (check out ruby fibers) and returns each element of your array.

There is another approach which does not suffer from the side effect of 
changing self which can be disastrous: create a thread local which holds 
a stack of values and make item peek at the top element of it:

class Object
   def new_each
     stack = (Thread.current[:__item__] ||= [])

     each do |x|
       stack.push x
       begin
         yield
       ensure
         stack.pop
       end
     end

     self
   end

private
   def item
     stack = Thread.current[:__item__] or
       raise "Not in new_each"
     stack.last
   end
end

a = %w{a b c}
b = [1, 2, 3]

a.new_each do
   printf "%-20s: %p\n", 'outer 1', item

   b.new_each do
     printf "%-20s: %p\n", 'inner', item
   end

   printf "%-20s: %p\n", 'outer 2', item
end

This approach
- does not change 'self'
- is thread safe
- is nesting safe

Kind regards

	robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/