# \`finalize' method?

**URL:** <https://rubytalk.org/t/finalize-method/22772>\
**Category:** ruby-talk\
**Created:** [25 November 2005 13:17 UTC](https://rubytalk.org/t/finalize-method/22772 "2005-11-25T13:17:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daniel\_Schierbeck](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@Daniel\_Schierbeck](https://rubytalk.org/u/Daniel_Schierbeck)\
**Post date:** [25 November 2005 13:17 UTC](https://rubytalk.org/t/finalize-method/22772/1 "2005-11-25T13:17:27Z")

</div>

Yeah, it's me again, your friendly neighbourhood power-suggester!

I'm wondering why there isn't a `finalize' method classes can define, that will be called immediately before instances of that class are garbage collected? I'm aware of ObjectSpace.define_finalizer, but it seems un-OO, and it doesn't seem to work when being called from within the instance methods. It also seems as if the Proc sent to `define\_finalizer' isn't called until \*after\* the object has been destroyed.

&nbsp;&nbsp;&nbsp;class Klass  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# finalize something  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

A use case (the best I can come up with at the moment):

&nbsp;&nbsp;&nbsp;class Contact  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize(filename)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@filename = filename  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parse\_xml\_file(@filename)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;save\_as\_xml(@filename)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

Cheers,  
Daniel

---

<div class="post-metadata">

**Author:** ![Jim\_Weirich](https://avatars.discourse-cdn.com/v4/letter/j/f4b2a3/32.png) [@Jim\_Weirich](https://rubytalk.org/u/Jim_Weirich)\
**Post date:** [25 November 2005 13:25 UTC](https://rubytalk.org/t/finalize-method/22772/2 "2005-11-25T13:25:18Z")

</div>

dasch wrote:

> Yeah, it's me again, your friendly neighbourhood power-suggester!
> 
> I'm wondering why there isn't a `finalize' method classes can define,  
> that will be called immediately before instances of that class are  
> garbage collected? I'm aware of ObjectSpace.define\_finalizer, but it  
> seems un-OO, and it doesn't seem to work when being called from within  
> the instance methods. It also seems as if the Proc sent to  
> `define\_finalizer' isn't called until \*after\* the object has been  
> destroyed.

That's correct, it prevents problems like the following code:

&nbsp;&nbsp;class Klass  
&nbsp;&nbsp;&nbsp;&nbsp;def finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$global\_reference = self  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Peter\_C\_Verhage](https://avatars.discourse-cdn.com/v4/letter/p/a88e4f/32.png) [@Peter\_C\_Verhage](https://rubytalk.org/u/Peter_C_Verhage)\
**Post date:** [30 November 2005 14:42 UTC](https://rubytalk.org/t/finalize-method/22772/3 "2005-11-30T14:42:25Z")

</div>

Hi,

How about making self a WeakRef in the finalize method?  
[http://www.ruby-doc.org/stdlib/libdoc/weakref/rdoc/](http://www.ruby-doc.org/stdlib/libdoc/weakref/rdoc/)

Regards,

Peter

---

<div class="post-metadata">

**Author:** ![Daniel\_Schierbeck](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@Daniel\_Schierbeck](https://rubytalk.org/u/Daniel_Schierbeck)\
**Post date:** [25 November 2005 13:47 UTC](https://rubytalk.org/t/finalize-method/22772/4 "2005-11-25T13:47:27Z")

</div>

Jim Weirich wrote:

> dasch wrote:
> 
> > Yeah, it's me again, your friendly neighbourhood power-suggester!
> > 
> > I'm wondering why there isn't a `finalize' method classes can define,  
> > that will be called immediately before instances of that class are  
> > garbage collected? I'm aware of ObjectSpace.define\_finalizer, but it  
> > seems un-OO, and it doesn't seem to work when being called from within  
> > the instance methods. It also seems as if the Proc sent to  
> > `define\_finalizer' isn't called until \*after\* the object has been destroyed.
> 
> That's correct, it prevents problems like the following code:
> 
> &nbsp;&nbsp;class Klass  
> &nbsp;&nbsp;&nbsp;&nbsp;def finalize  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$global\_reference = self  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end

In that case I'd expect $global\_reference to be nil after the `finalize' method is done executing, since the Klass instance has already been deemed ready for destruction.

Cheers,  
Daniel

---

<div class="post-metadata">

**Author:** ![Christian\_Neukirche1](https://avatars.discourse-cdn.com/v4/letter/c/ee7513/32.png) [@Christian\_Neukirche1](https://rubytalk.org/u/Christian_Neukirche1)\
**Post date:** [25 November 2005 16:28 UTC](https://rubytalk.org/t/finalize-method/22772/5 "2005-11-25T16:28:58Z")

</div>

Jim Weirich \<jim-keyword-rforum.c88827@weirichhouse.org\> writes:

> dasch wrote:
> 
> > Yeah, it's me again, your friendly neighbourhood power-suggester!
> > 
> > I'm wondering why there isn't a `finalize' method classes can define,  
> > that will be called immediately before instances of that class are  
> > garbage collected? I'm aware of ObjectSpace.define\_finalizer, but it  
> > seems un-OO, and it doesn't seem to work when being called from within  
> > the instance methods. It also seems as if the Proc sent to  
> > `define\_finalizer' isn't called until \*after\* the object has been  
> > destroyed.
> 
> That's correct, it prevents problems like the following code:
> 
> &nbsp;&nbsp;class Klass  
> &nbsp;&nbsp;&nbsp;&nbsp;def finalize  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$global\_reference = self  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end

What's the problem if this method ran on the first GC once and then  
the object just stayed around? I.e. have a three-pass GC, mark, run,  
sweep?

> **···**
>
> --  
> Christian Neukirchen \<chneukirchen@gmail.com\> [http://chneukirchen.org](http://chneukirchen.org)

---

<div class="post-metadata">

**Author:** ![Eric\_Mahurin](https://avatars.discourse-cdn.com/v4/letter/e/b4bc9f/32.png) [@Eric\_Mahurin](https://rubytalk.org/u/Eric_Mahurin)\
**Post date:** [30 November 2005 15:23 UTC](https://rubytalk.org/t/finalize-method/22772/6 "2005-11-30T15:23:09Z")

</div>

Or just say in the docs that any references to self will become  
invalid after finalize is called. I don't think doing this is any  
less safe than using #object\_id and ObjectSapce::\_id2ref (same type of  
error if you use this on an object\_id already GCed). Right now if you  
are using ObjectSapce::define\_finalizer, you are likely using  
ObjectSpace::\_id2ref somewhere (you probably have some data-structure  
holding object\_id's).

Maybe this method could be called #\_finalize to say that it isn't safe  
(like ObjectSpace::\_id2ref).

> **···**
>
> On 11/30/05, Peter C. Verhage \<peter@no-nonsense.org\> wrote:
> 
> > Hi,
> > 
> > How about making self a WeakRef in the finalize method?  
> > [http://www.ruby-doc.org/stdlib/libdoc/weakref/rdoc/](http://www.ruby-doc.org/stdlib/libdoc/weakref/rdoc/)

---

<div class="post-metadata">

**Author:** ![Jim\_Weirich](https://avatars.discourse-cdn.com/v4/letter/j/f4b2a3/32.png) [@Jim\_Weirich](https://rubytalk.org/u/Jim_Weirich)\
**Post date:** [25 November 2005 15:02 UTC](https://rubytalk.org/t/finalize-method/22772/7 "2005-11-25T15:02:54Z")

</div>

dasch wrote:

> In that case I'd expect $global\_reference to be nil after the `finalize'  
> method is done executing, since the Klass instance has already been  
> deemed ready for destruction.

"after the 'finalize' method is done" =\> Tricky.

How would this be implemented? Seems to me Ruby would have to scan all  
of the current image to determine if any new references were created  
during the execution of the finalize method. Especially since the  
references may be created deep inside other methods invoked by finalize.

And it might be more subtle than just checking for variable bindings.  
Consider:

&nbsp;&nbsp;class NamedObject  
&nbsp;&nbsp;&nbsp;&nbsp;attr\_reader :name  
&nbsp;&nbsp;&nbsp;&nbsp;def initialize(name)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name = name  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;def finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proc { name }  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;k = NamedObject.new("Billy")  
&nbsp;&nbsp;p = k.finalize # Here p is a proc that has a binding that includes  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# a "finalized" object.

The point is that the current mechanism avoids all these questions by  
only calling the finalizer /after/ the object has been destroyed.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Jim\_Weirich](https://avatars.discourse-cdn.com/v4/letter/j/f4b2a3/32.png) [@Jim\_Weirich](https://rubytalk.org/u/Jim_Weirich)\
**Post date:** [25 November 2005 17:00 UTC](https://rubytalk.org/t/finalize-method/22772/8 "2005-11-25T17:00:29Z")

</div>

chneukirchen wrote:

> What's the problem if this method ran on the first GC once and then  
> the object just stayed around? I.e. have a three-pass GC, mark, run,  
> sweep?

There are two problems:

(1) Detecting that the finalizer has created new reference to a object  
scheduled for collection is problematic. I'm thinking this would  
require a new mark pass to detect.

(2) What is the state of an object that has been finalized, but sticks  
around afterwards? Is it valid to call methods on it? After all,  
supposedly all of its resources have been finalized at this point. And  
when it becomes eligible for collection again, does the finalizer need  
to run again or not?

Most languages that allow finalizers explicitly state that creating new  
references duing finalization is not allowed and depend upon the  
programmer to follow that rule. Ruby handles it by making it impossible  
for the programmer to break that rule (i.e. the finalizer doesn't get a  
reference to the object, making it difficult to create a reference to  
it).

-- Jim Weirich

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Matthias\_Georgi](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@Matthias\_Georgi](https://rubytalk.org/u/Matthias_Georgi)\
**Post date:** [25 November 2005 18:57 UTC](https://rubytalk.org/t/finalize-method/22772/9 "2005-11-25T18:57:27Z")

</div>

> \> That's correct, it prevents problems like the following code:  
> \>  
> \> class Klass  
> \> def finalize  
> \> $global\_reference = self  
> \> end  
> \> end  
> \>
> 
> In that case I'd expect $global\_reference to be nil after the `finalize'  
> method is done executing, since the Klass instance has already been  
> deemed ready for destruction.

This would force the interpreter to keep a back reference for all  
objects to variables which keep references to them, not very efficient  
in regard of cpu and memory. Java solves this problem by reviving those  
objects, which seems at least for me very odd.

So generally you should avoid finalizers, because most of the time you  
are only interested in running some code before the application exits.

This should help in most cases:

BEGIN { $exit\_listeners = }

def add\_exit\_listener(object)  
&nbsp;&nbsp;$exit\_listeners \<\< object  
end

END { $exit\_listeners.each {|listener| listener.on\_exit } }

Alternatively you may declare an END block inside your initialize  
method.

---

<div class="post-metadata">

**Author:** ![Daniel\_Schierbeck](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@Daniel\_Schierbeck](https://rubytalk.org/u/Daniel_Schierbeck)\
**Post date:** [25 November 2005 15:27 UTC](https://rubytalk.org/t/finalize-method/22772/10 "2005-11-25T15:27:27Z")

</div>

Jim Weirich wrote:

> dasch wrote:
> 
> > In that case I'd expect $global\_reference to be nil after the `finalize'  
> > method is done executing, since the Klass instance has already been  
> > deemed ready for destruction.
> 
> "after the 'finalize' method is done" =\> Tricky.
> 
> How would this be implemented? Seems to me Ruby would have to scan all of the current image to determine if any new references were created during the execution of the finalize method. Especially since the references may be created deep inside other methods invoked by finalize.
> 
> And it might be more subtle than just checking for variable bindings. Consider:
> 
> &nbsp;&nbsp;class NamedObject  
> &nbsp;&nbsp;&nbsp;&nbsp;attr\_reader :name  
> &nbsp;&nbsp;&nbsp;&nbsp;def initialize(name)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name = name  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;def finalize  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proc { name }  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;k = NamedObject.new("Billy")  
> &nbsp;&nbsp;p = k.finalize # Here p is a proc that has a binding that includes  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# a "finalized" object.
> 
> The point is that the current mechanism avoids all these questions by only calling the finalizer /after/ the object has been destroyed.

I just think it's weird that PHP has destructors and Ruby doesn't 😉

&nbsp;&nbsp;&nbsp;[PHP: Constructors and Destructors - Manual](http://www.php.net/manual/en/language.oop5.decon.php)

I'm not really into C, neither am I familiar with the Ruby implementation, but doesn't all variables just reference an object? So somewhere, an object is stored, and each variable referencing it really only holds that object's id. I imagine the `finalize' method could be run, and afterwards, the object could be replaced with nil, maybe retaining the old object id. That way any variables that point to the object will be nil.

Now, I don't know if that's how it works, but it sounds logical to me, speaking as a guy who's never taken any programming lessons or programmed/scripted using other languages than PHP, JavaScript and Ruby...

Cheers,  
Daniel

---

<div class="post-metadata">

**Author:** ![Christian\_Neukirche1](https://avatars.discourse-cdn.com/v4/letter/c/ee7513/32.png) [@Christian\_Neukirche1](https://rubytalk.org/u/Christian_Neukirche1)\
**Post date:** [25 November 2005 18:18 UTC](https://rubytalk.org/t/finalize-method/22772/11 "2005-11-25T18:18:29Z")

</div>

Jim Weirich \<jim-keyword-rforum.c88827@weirichhouse.org\> writes:

> chneukirchen wrote:
> 
> > What's the problem if this method ran on the first GC once and then  
> > the object just stayed around? I.e. have a three-pass GC, mark, run,  
> > sweep?
> 
> There are two problems:
> 
> (1) Detecting that the finalizer has created new reference to a object  
> scheduled for collection is problematic. I'm thinking this would  
> require a new mark pass to detect.

No, this is not required by my scheme. Methods which have a finalize  
will require two sweeps to actually get removed (that's not that bad,  
the second one will follow soon if the first one wasn't sucessful).  
You need to keep track of the objects whose finalizer has been run,  
yeah. I'm sure we can use a bit left over somewhere for that...

> (2) What is the state of an object that has been finalized, but sticks  
> around afterwards? Is it valid to call methods on it? After all,  
> supposedly all of its resources have been finalized at this point. And  
> when it becomes eligible for collection again, does the finalizer need  
> to run again or not?

It is unreclaimed. Yes. Yes. No. Yes.  
You can keep track of disposal using an instance variable.

> Most languages that allow finalizers explicitly state that creating new  
> references duing finalization is not allowed and depend upon the  
> programmer to follow that rule. Ruby handles it by making it impossible  
> for the programmer to break that rule (i.e. the finalizer doesn't get a  
> reference to the object, making it difficult to create a reference to  
> it).

That is a valid option, but I think Ruby can do better at little cost.

> **···**
>
> > -- Jim Weirich
> 
> --  
> Christian Neukirchen \<chneukirchen@gmail.com\> [http://chneukirchen.org](http://chneukirchen.org)

---

<div class="post-metadata">

**Author:** ![Hugh\_Sasse](https://avatars.discourse-cdn.com/v4/letter/h/d6d6ee/32.png) [@Hugh\_Sasse](https://rubytalk.org/u/Hugh_Sasse)\
**Post date:** [25 November 2005 15:36 UTC](https://rubytalk.org/t/finalize-method/22772/12 "2005-11-25T15:36:54Z")

</div>

> I just think it's weird that PHP has destructors and Ruby doesn't 😉
> 
> &nbsp;&nbsp;[PHP: Constructors and Destructors - Manual](http://www.php.net/manual/en/language.oop5.decon.php)

I find this tricky too: the only model I can think of is that where  
you need destructors, your constructor desstructs, and you get at  
the object with a block, in the style of open("file"){|f| ...}; if  
you see what I mean.

> I'm not really into C, neither am I familiar with the Ruby implementation, but  
> doesn't all variables just reference an object? So somewhere, an object is  
> stored, and each variable referencing it really only holds that object's id. I  
> imagine the `finalize' method could be run, and afterwards, the object could  
> be replaced with nil, maybe retaining the old object id. That way any  
> variables that point to the object will be nil.

But there is only one nil in the system, so it can't have many ids.

> Now, I don't know if that's how it works, but it sounds logical to me,  
> speaking as a guy who's never taken any programming lessons or  
> programmed/scripted using other languages than PHP, JavaScript and Ruby...
> 
> Cheers,  
> Daniel

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hugh

> **···**
>
> On Sat, 26 Nov 2005, Daniel Schierbeck wrote:
> 
> >

---

<div class="post-metadata">

**Author:** ![Daniel\_Schierbeck](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@Daniel\_Schierbeck](https://rubytalk.org/u/Daniel_Schierbeck)\
**Post date:** [25 November 2005 16:07 UTC](https://rubytalk.org/t/finalize-method/22772/13 "2005-11-25T16:07:26Z")

</div>

Hugh Sasse wrote:

> > I just think it's weird that PHP has destructors and Ruby doesn't 😉
> > 
> > &nbsp;&nbsp;[PHP: Constructors and Destructors - Manual](http://www.php.net/manual/en/language.oop5.decon.php)
> 
> I find this tricky too: the only model I can think of is that where  
> you need destructors, your constructor desstructs, and you get at  
> the object with a block, in the style of open("file"){|f| ...}; if  
> you see what I mean.

No, not really. I really can't stretch enough that I'm a noob... 🙂

> > I'm not really into C, neither am I familiar with the Ruby implementation, but  
> > doesn't all variables just reference an object? So somewhere, an object is  
> > stored, and each variable referencing it really only holds that object's id. I  
> > imagine the `finalize' method could be run, and afterwards, the object could  
> > be replaced with nil, maybe retaining the old object id. That way any  
> > variables that point to the object will be nil.
> 
> But there is only one nil in the system, so it can't have many ids.

Could the object then by replaced by a reference to the nil object? Again, I'm talking theoretically...

Cheers,  
Daniel

> **···**
>
> > On Sat, 26 Nov 2005, Daniel Schierbeck wrote:

---

<div class="post-metadata">

**Author:** ![Logan\_Capaldo](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@Logan\_Capaldo](https://rubytalk.org/u/Logan_Capaldo)\
**Post date:** [25 November 2005 16:14 UTC](https://rubytalk.org/t/finalize-method/22772/14 "2005-11-25T16:14:52Z")

</div>

Matz has also said that define\_finalizer was in ObjectSpace on purpose to  
discourage the use of finalizers. Finalizers are kind of weird, I would  
recommend adding a clean-up method to any object you think "needs" a  
finalizer. At least then the object still exists as in in a known state. Try  
to not to think of them as destructors (in C++ sense) because they aren't.

> **···**
>
> On 11/25/05, Daniel Schierbeck \<daniel.schierbeck@gmail.com\> wrote:
> 
> > Hugh Sasse wrote:  
> > \> On Sat, 26 Nov 2005, Daniel Schierbeck wrote:  
> > \>  
> > \>\> I just think it's weird that PHP has destructors and Ruby doesn't 😉  
> > \>\>  
> > \>\> [http://www.php.net/manual/en/language.oop5.decon.php](http://www.php.net/manual/en/language.oop5.decon.php)  
> > \>  
> > \> I find this tricky too: the only model I can think of is that where  
> > \> you need destructors, your constructor desstructs, and you get at  
> > \> the object with a block, in the style of open("file"){|f| ...}; if  
> > \> you see what I mean.
> > 
> > No, not really. I really can't stretch enough that I'm a noob... 🙂
> > 
> > \>\> I'm not really into C, neither am I familiar with the Ruby  
> > implementation, but  
> > \>\> doesn't all variables just reference an object? So somewhere, an object  
> > is  
> > \>\> stored, and each variable referencing it really only holds that  
> > object's id. I  
> > \>\> imagine the `finalize' method could be run, and afterwards, the object  
> > could  
> > \>\> be replaced with nil, maybe retaining the old object id. That way any  
> > \>\> variables that point to the object will be nil.  
> > \>  
> > \> But there is only one nil in the system, so it can't have many ids.
> > 
> > Could the object then by replaced by a reference to the nil object?  
> > Again, I'm talking theoretically...
> > 
> > Cheers,  
> > Daniel

---

<div class="post-metadata">

**Author:** ![Hugh\_Sasse](https://avatars.discourse-cdn.com/v4/letter/h/d6d6ee/32.png) [@Hugh\_Sasse](https://rubytalk.org/u/Hugh_Sasse)\
**Post date:** [25 November 2005 16:30 UTC](https://rubytalk.org/t/finalize-method/22772/15 "2005-11-25T16:30:37Z")

</div>

> Hugh Sasse wrote:  
> \>  
> \> \> I just think it's weird that PHP has destructors and Ruby doesn't 😉  
> \> \>  
> \> \> [PHP: Constructors and Destructors - Manual](http://www.php.net/manual/en/language.oop5.decon.php)  
> \>  
> \> I find this tricky too: the only model I can think of is that where  
> \> you need destructors, your constructor desstructs, and you get at  
> \> the object with a block, in the style of open("file"){|f| ...}; if  
> \> you see what I mean.
> 
> No, not really. I really can't stretch enough that I'm a noob... 🙂

The braces, curly brackets, are a block. The CS people will tell  
you it is a closure. What it means is: In the current scope (local  
variables defined, etc) execute open("file") to open the file for  
reading, and then [when inside open it effectively calls yield] you  
will have a parameter which we'll call f, and we'll do something  
with it in the local scope until the closing brace of the block. On  
the closing brace, open will close the file for us. The oft' used  
each method behaves in a similar way.

For an intro:  
[http://www.rubycentral.com/book/tut\_containers.html#S2](http://www.rubycentral.com/book/tut_containers.html#S2)

For info about using them with constructors:  
[http://www.rubycentral.com/articles/insteval.html](http://www.rubycentral.com/articles/insteval.html)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[...]

> \> \> imagine the `finalize' method could be run, and afterwards, the object  
> \> \> could  
> \> \> be replaced with nil, maybe retaining the old object id. That way any  
> \> \> variables that point to the object will be nil.  
> \>  
> \> But there is only one nil in the system, so it can't have many ids.
> 
> Could the object then by replaced by a reference to the nil object? Again, I'm  
> talking theoretically...

Ruby doesn't have references, otherwise it could.

> Cheers,  
> Daniel

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hugh

> **···**
>
> On Sat, 26 Nov 2005, Daniel Schierbeck wrote:
> 
> > \> On Sat, 26 Nov 2005, Daniel Schierbeck wrote:

---

<div class="post-metadata">

**Author:** ![Daniel\_Schierbeck](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@Daniel\_Schierbeck](https://rubytalk.org/u/Daniel_Schierbeck)\
**Post date:** [25 November 2005 16:47 UTC](https://rubytalk.org/t/finalize-method/22772/16 "2005-11-25T16:47:27Z")

</div>

Hugh Sasse wrote:

> > Hugh Sasse wrote:
> > 
> > > > I just think it's weird that PHP has destructors and Ruby doesn't 😉
> > > > 
> > > > &nbsp;&nbsp;[PHP: Constructors and Destructors - Manual](http://www.php.net/manual/en/language.oop5.decon.php)
> > > 
> > > I find this tricky too: the only model I can think of is that where  
> > > you need destructors, your constructor desstructs, and you get at  
> > > the object with a block, in the style of open("file"){|f| ...}; if  
> > > you see what I mean.
> > 
> > No, not really. I really can't stretch enough that I'm a noob... 🙂
> 
> The braces, curly brackets, are a block. The CS people will tell  
> you it is a closure. What it means is: In the current scope (local  
> variables defined, etc) execute open("file") to open the file for  
> reading, and then [when inside open it effectively calls yield] you  
> will have a parameter which we'll call f, and we'll do something  
> with it in the local scope until the closing brace of the block. On  
> the closing brace, open will close the file for us. The oft' used  
> each method behaves in a similar way.

Oh, sorry, I misunderstood you: You mean something like this:

&nbsp;&nbsp;&nbsp;class Klass  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield self  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# do something  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

Sorry, I'm kinda groggy 😉

Cheers,  
Daniel

> **···**
>
> > On Sat, 26 Nov 2005, Daniel Schierbeck wrote:
> > 
> > > > On Sat, 26 Nov 2005, Daniel Schierbeck wrote:

---

<div class="post-metadata">

**Author:** ![Hugh\_Sasse](https://avatars.discourse-cdn.com/v4/letter/h/d6d6ee/32.png) [@Hugh\_Sasse](https://rubytalk.org/u/Hugh_Sasse)\
**Post date:** [25 November 2005 16:51 UTC](https://rubytalk.org/t/finalize-method/22772/17 "2005-11-25T16:51:17Z")

</div>

> Oh, sorry, I misunderstood you: You mean something like this:
> 
> &nbsp;&nbsp;class Klass  
> &nbsp;&nbsp;&nbsp;&nbsp;def initialize

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# setup usual stuff, then:

> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield self  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finalize  
> &nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;def finalize  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# do something

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# like releasing resources, yes.

> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> Sorry, I'm kinda groggy 😉

Not that groggy, that's exactly what I meant.

> Cheers,  
> Daniel

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hugh

> **···**
>
> On Sat, 26 Nov 2005, Daniel Schierbeck wrote:
> 
> >

---

<div class="post-metadata">

**Author:** ![Daniel\_Schierbeck](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@Daniel\_Schierbeck](https://rubytalk.org/u/Daniel_Schierbeck)\
**Post date:** [25 November 2005 21:17 UTC](https://rubytalk.org/t/finalize-method/22772/18 "2005-11-25T21:17:27Z")

</div>

Hugh Sasse wrote:

> > Oh, sorry, I misunderstood you: You mean something like this:
> > 
> > &nbsp;&nbsp;class Klass  
> > &nbsp;&nbsp;&nbsp;&nbsp;def initialize
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# setup usual stuff, then:
> 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield self  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finalize  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def finalize  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# do something
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# like releasing resources, yes.
> 
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > Sorry, I'm kinda groggy 😉
> 
> Not that groggy, that's exactly what I meant.
> 
> > Cheers,  
> > Daniel
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hugh

What would you call such an approach? Encapsulating? I use this often enough that I think it would fit lovely in a module:

&nbsp;&nbsp;&nbsp;module Encapsulatable  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def self.included(klass)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;klass.module\_eval do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def self.new(\*args)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield obj = \_\_new\_\_(\*args)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.finalize if obj.respond\_to? :finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

Cheers,  
Daniel

> **···**
>
> > On Sat, 26 Nov 2005, Daniel Schierbeck wrote:

---

<div class="post-metadata">

**Author:** ![ts1](https://avatars.discourse-cdn.com/v4/letter/t/a8b319/32.png) [@ts1](https://rubytalk.org/u/ts1)\
**Post date:** [26 November 2005 12:23 UTC](https://rubytalk.org/t/finalize-method/22772/19 "2005-11-26T12:23:12Z")

</div>

> What would you call such an approach? Encapsulating? I use this often  
> enough that I think it would fit lovely in a module:

A bad approach, at least for me.

> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def self.new(\*args)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield obj = \_\_new\_\_(\*args)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.finalize if obj.respond\_to? :finalize  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

There is a convention in ruby : the method ::new must return an object of  
the class. You must change the name of the method if its return nil, or  
another object.

Guy Decoux

---

<div class="post-metadata">

**Author:** ![Daniel\_Schierbeck](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@Daniel\_Schierbeck](https://rubytalk.org/u/Daniel_Schierbeck)\
**Post date:** [26 November 2005 13:32 UTC](https://rubytalk.org/t/finalize-method/22772/20 "2005-11-26T13:32:28Z")

</div>

ts wrote:

> \> What would you call such an approach? Encapsulating? I use this often \> enough that I think it would fit lovely in a module:
> 
> A bad approach, at least for me.
> 
> \> def self.new(\*args)  
> \> yield obj = \_\_new\_\_(\*args)  
> \> obj.finalize if obj.respond\_to? :finalize  
> \> end
> 
> There is a convention in ruby : the method ::new must return an object of  
> the class. You must change the name of the method if its return nil, or  
> another object.

Roger. That's not that hard to do:

&nbsp;&nbsp;&nbsp;module Encapsulatable  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def self.included(klass)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;klass.metaclass\_eval do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private :new

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def encapsulate(\*args)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield obj = new(\*args)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.finalize if obj.respond\_to? :finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

Note that this doesn't prevent the user from calling methods on the object after its `finalize' method has been called.

&nbsp;&nbsp;&nbsp;class Klass  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include Encapsulatable

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "initializing..."  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def foo  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "called method `foo'"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def finalize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "finalizing..."  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;ref = nil  
&nbsp;&nbsp;&nbsp;Klass.encapsulate { |obj| obj.foo; ref = obj }  
&nbsp;&nbsp;&nbsp;ref.foo

But then again, this ain't Java. If you want to, you could wreak havoc in seconds. But we're all friends, right? 🙂

Cheers,  
Daniel
