[Q] How far does a closure reach?

I was trying to understand how Ruby’s finalizers work, or, in this case,
why they weren’t working as I expected. I found a solution, short and
sweet, at this Wiki page:

http://www.rubygarden.org/ruby?ObjectsNotGetFinalized

I want to make sure I understand why the finalizer in the first
example doesn’t work:

 class Test
   def initialize
     ObjectSpace.define_finalizer(self,
                                  Proc.new{ puts "finalizing" })
   end
 end

The Proc doesn’t have any explicit reference to self, and that’s what
threw me at first. But am I correct that because the Proc acts as a
closure, it has a “hidden” reference to self from the enclosing scope?

If the answer to that question was “yes”, then the follow-up question is
"How far does the scope of a closure reach?". Does it more-or-less
follow the same kinds of block-scoping rules as, say, C/C++?

I was trying to understand how Ruby’s finalizers work, […]

 class Test
   def initialize
     ObjectSpace.define_finalizer(self,
                                  Proc.new{ puts "finalizing" })
   end
 end

[…] But am I correct that because the Proc acts as a
closure, it has a “hidden” reference to self from the enclosing scope?

Yes. the “puts” is actually sent to “self” so obviously the proc needs
to keep a reference to self.

If the answer to that question was “yes”, then the follow-up question is
“How far does the scope of a closure reach?”. Does it more-or-less
follow the same kinds of block-scoping rules as, say, C/C++?

Here’s the rule. Any free variables in the body of the proc are bound
in the environment where the proc is created. self is probably a
special case, since it doesn’t appear explicitly, but is is needed for
any method called without an explicit receiver.

···

On Fri, 2003-03-28 at 09:19, Lyle Johnson wrote:


– Jim Weirich jweirich@one.net http://w3.one.net/~jweirich

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)