Run a Method on deletion of an Object
Asked Answered
G

2

1

I am learning ruby and haven't found a way to override an equivalent object.delete function:

This is how I am doing it:

    class Foo
        @@no_foo=0
        def initialize
            @@no_foo+=1
        end
        def delete
            #class specific cleanup...
            @@no_foo-=1
        end
        def Foo.no_foo
            return "#@@no_foo"
        end
    end

    def delete(obj)
        #object independent cleanup...
        obj.delete
        return nil
    end

    foo1 = Foo.new
    foo2 = Foo.new

    puts Foo.no_foo

    puts foo2
    foo2 = delete(foo2)
    puts foo2

    puts Foo.no_foo

As you can see, this is a bit of a hacky way of going about things... is there an easier way to go about this?
Basically I would like to make my objects unaccessible in the same call as decrementing the total counter for that class. I couldn't find a method that gets called when setting a variable(pointer to object) to nil.

I found no way to delete an object.

Grimalkin answered 28/5, 2013 at 14:3 Comment(3)
I don't understand, what is your exact requirement. But you can take look here - WeakRef.Daguerre
@RubyLovely, WeakRef seems like the easiest way to accomplish what I'm trying to achieve.Grimalkin
Okay! Good then! So if that library helps you to achieve your goal, then please post the final code here also, so that future users can take the advantage,by seeing it.Daguerre
G
1

as per the link provided by @RubyLovely: WeakRef.
I put together the following sample class:

require 'weakref'
  class Foo
    #block to excecute on GC.start...
    FINALIZER = lambda { |object_id| p "finalizing %d" % object_id; @@no_foo -=1 }

    @@no_foo=0
    def initialize
        @@no_foo+=1
        #Initialising the finalizer...
        ObjectSpace.define_finalizer(self, FINALIZER)
    end

    def Foo.no_foo
        @@no_foo
    end
end

foo = Foo.new
foo = WeakRef.new(foo)
puts Foo.no_foo

GC.start

puts Foo.no_foo
Grimalkin answered 31/5, 2013 at 9:16 Comment(0)
F
1

Even though ruby doesn't have explicit destructors, it has support for finalizers. Finalizer is a piece of code that gets called when your object is garbage-collected.

class Foo
  @@no_foo = 0

  def initialize
    @@no_foo += 1
    ObjectSpace.define_finalizer(self, Foo.method(:delete))
  end

  def self.delete id # also this argument seems to be necessary
    @@no_foo -= 1
  end

  def self.no_foo
    @@no_foo
  end
end

Seems that you won't be able to do instance-specific cleanup in the finalizer. It has to be completely detached from the instance in order to work correctly. Here are answer that might also help you: answer, answer.

Famagusta answered 28/5, 2013 at 14:12 Comment(3)
@RubyLovely: is that necessary? The question needed that for clarification. Here it will only confuse, IMHOFamagusta
This is what I had found Earlier, but I hadn't fully understood it. It seems that the finalizer isn't called when the Object is destroyed, but rather when It is garbage collected.Grimalkin
@hamhut1066: that is the only destruction you get. Until object is garbage collected, it lives.Famagusta
G
1

as per the link provided by @RubyLovely: WeakRef.
I put together the following sample class:

require 'weakref'
  class Foo
    #block to excecute on GC.start...
    FINALIZER = lambda { |object_id| p "finalizing %d" % object_id; @@no_foo -=1 }

    @@no_foo=0
    def initialize
        @@no_foo+=1
        #Initialising the finalizer...
        ObjectSpace.define_finalizer(self, FINALIZER)
    end

    def Foo.no_foo
        @@no_foo
    end
end

foo = Foo.new
foo = WeakRef.new(foo)
puts Foo.no_foo

GC.start

puts Foo.no_foo
Grimalkin answered 31/5, 2013 at 9:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.