From: Ilias Lazaridis Date: 2011-06-05T14:15:26+09:00 Subject: Re: CORE - Altering Behaviour of "each do" (default param "item") On 4 Éïŭí, 21:02, Robert Klemme wrote: > 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 endhttp://blog.rubybestpractices.com/