On 4 =C9=EF=FD=ED, 21:02, Robert Klemme <shortcut... / googlemail.com> 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
> =A0 =A0def new_each
> =A0 =A0 =A0stack =3D (Thread.current[:__item__] ||=3D [])
>
> =A0 =A0 =A0each do |x|
> =A0 =A0 =A0 =A0stack.push x
> =A0 =A0 =A0 =A0begin
> =A0 =A0 =A0 =A0 =A0yield
> =A0 =A0 =A0 =A0ensure
> =A0 =A0 =A0 =A0 =A0stack.pop
> =A0 =A0 =A0 =A0end
> =A0 =A0 =A0end
>
> =A0 =A0 =A0self
> =A0 =A0end
>
> private
> =A0 =A0def item
> =A0 =A0 =A0stack =3D Thread.current[:__item__] or
> =A0 =A0 =A0 =A0raise "Not in new_each"
> =A0 =A0 =A0stack.last
> =A0 =A0end
> end
>
> a =3D %w{a b c}
> b =3D [1, 2, 3]
>
> a.new_each do
> =A0 =A0printf "%-20s: %p\n", 'outer 1', item
>
> =A0 =A0b.new_each do
> =A0 =A0 =A0printf "%-20s: %p\n", 'inner', item
> =A0 =A0end
>
> =A0 =A0printf "%-20s: %p\n", 'outer 2', item
> end
>
> This approach
> - does not change 'self'
> - is thread safe
> - is nesting safe
>
> Kind regards
>
> =A0 =A0 =A0 =A0 robert
>
> --
> remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestp=
ractices.com/