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:
“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)