From: Jacob Fugal Date: 2006-08-03T01:11:35+09:00 Subject: Re: I thought this was the one that worked? On 8/2/06, Chad Perrin wrote: > On Wed, Aug 02, 2006 at 10:59:15PM +0900, Pit Capitain wrote: > > If I understand you correctly, then the > > following two blocks should be exactly the same, shouldn't they? > > > > blk1 = Foo.new.bar > > blk2 = Foo.new.bar > > > > But they aren't the same, as can be seen from the following code: > > > > eval "self", blk1 # => # > > eval "self", blk2 # => # > > > > As you can see, each block remembers at least the value of "self", when > > it was created. You can get at this value even if the "self" object goes > > out of scope, as you can see from my code above. There's no explicit > > reference to the two instances of Foo. From this it follows (at least > > for me), that each block in Ruby is a closure. [snip] > I think you're > pointing out memory addresses for those objects, not something internal > to them. Please correct me if I'm wrong. self is not just a memory address (well, not any more than any other object reference). You're seeing the memory address because that's the default #inspect output for an object, but it's not really relevant here. self is an object reference just like any other variable would be. Let's replace the contents of the evals with a method call instead: # using the same definition of Foo as referenced earlier foo1, foo2 = Foo.new, Foo.new foo1.object_id # => 1742734 foo2.object_id # => 1742684 blk1, blk2 = foo1.bar, foo2.bar eval "object_id", blk1 # => 1742734 eval "object_id", blk2 # => 1742684 I also captured the Foo objects themselves so we can see that the object_id method call is being sent to the foo object rather than the block itself. Jacob Fugal