When is #finalize run?


I wrote up this example, to see if a finalizer goes away when a class is inherited, but the finalizer doesn’t seem to be called at any point. When is a finalize method called?

class Parent
  property parent_prop = "Parent property"

  def initialize
    puts "initializing parent"
  def initialize(@parent_prop)
  	puts "initializing parent"
	def finalize
    puts "Finalizing parent!"

class Child < Parent
  property child_prop = "Child property"
  def initialize
    puts "initializing child"

p! (p = Parent.new), (p = nil), (c = Child.new), (c = nil)

sleep 15
puts "collecting"
100.times { GC.collect }
puts "done"


(p = Parent.new) # => initializing parent
#<Parent:0x102d20f20 @parent_prop="Parent property">
(p = nil)        # => nil
(c = Child.new)  # => initializing child
#<Child:0x102d20f00 @parent_prop="Parent property", @child_prop="Child property">
(c = nil)        # => nil


Try this:

p = Parent.new
p = nil
c = Child.new
c = nil

puts "collecting"
puts "done"

The p! macro creates temporary variables to hold each of the expressions. That means they will still be in the stack when you call GC.collect.


Actually, what I said is not correct… but I’m sure some things remain in the stack, for some reason. I’ll need to debug it, but I don’t consider this something super important. The GC will collect things when they are unreachable: no references in the heap or stack. And you shouldn’t rely on GC.collect to collect things you don’t need anymore.


My use of GC.collect was just to try to get the #finalize method to be called. I suppose my real question is whether the #finalize method of a superclass goes away along with all of the initialize methods when an initialize method is overridden in a subclass, or if perhaps a #finalize method is never inherited… some strange behavior like that.

To be specific, I’m writing a shard and CLI for converting between different subtitle file-formats. I wanted a superclass Format with a @content property which could be any IO including an open file, and I wanted to make sure that this method would make it into the subclasses and not just be a part of the (abstract) superclass.

def finalize
  @content.close if @content.responds_to? :close

Thanks @asterite


Yes, finalize is (or should) be inherited.


Thank you!