On Oct 18, 2006, at 6:56 PM, Morton G. wrote:
That outer block that ends on end returns the lambda made inside
expensive) lambdas. Boggle. Am I missing something?
irb(main):069:1> end
lambdas get nested by the inject (at the position of ‘blk’) with
the first one innermost, which is why they get called in reverse
order (and ‘block’ last of all). Is that right?
Regards, Morton
Yes thats essentially it. Maybe this helps clear it up a bit. Lets
forget about the with_scope AR stuff for a minute and just mock this
out:
class Scoper
def self.with_block(hsh={}, &block)
p hsh.merge( {:klass => name})
block.call
end
end
class Foo < Scoper
end
class Bar < Scoper
end
class Baz < Scoper
end
def set_scopers(klasses=[Foo, Bar, Baz], &block)
hash = {:test => ‘test’}
klasses.inject(block) do |blk, klass|
lambda { klass.with_block hash, &blk }
end.call
end
puts set_scopers { puts ‘done’}
outputs
{:test=>“test”, :klass=>“Baz”}
{:test=>“test”, :klass=>“Bar”}
{:test=>“test”, :klass=>“Foo”}
done
Now if you comment out the block.call line in the Scoper.with_block
method:
class Scoper
def self.with_block(hsh={}, &block)
p hsh.merge( {:klass => name})
#block.call
end
end
puts set_scopers { puts ‘done’ }
#ouput
{:test=>“test”, :klass=>“Baz”}
nil
and run the same code again it only calls the last lambda that gets
made. It is a twisty little mess of block and wrappers that is hard
to follow. But essentially inject is chaning those lambda’s together
and the final .call calls the chain which calls the final &blk in the
end.
nil
Cheers-
– Ezra Z.
– Lead Rails Evangelist
– [email protected]
– Engine Y., Serious Rails Hosting
– (866) 518-YARD (9273)