Can one Ruby object destroy another?

In Ruby, can one object destroy another?

For example:

class Creature def initialize @energy = 1 end attr_accessor :energy end class Crocodile < Creature def eat(creature) @energy += creature.energy creature = nil #this does not work end end fish = Creature.new croc = Crocodile.new croc.eat(fish) 

After the crocodile ate the creature and absorbed its energy, the creature should cease to exist. But the above code does not destroy the creature.

I know that if I say fish = nil , the object referenced by varible fish will be garbage collected. But saying creature = nil inside the eat crocodile method fails.

Another way to put it

From inside croc.eat, can I say "since the variable" fish "was passed to me, when I finished, am I going to set the" fish "to zero?"

Update: issue resolved

I essentially took the approach that Chuck suggested with some changes. Here are my thoughts:

  • If there is no longer any variable pointing to the object, this will be garbage collection
  • If when creating an object, I add it to the hash (for example, "x" => the object) and do not create any other variable for it, and then remove this element from the hash results when garbage collecting the object
  • It seems logical that a list of all creatures should be stored in a creature class

So I did this:

  • In an object of the Creature class, I created a hash and assigned it to an instance variable. We will call him @creaturelist . (The reason I used the instance variable rather than the class variable, so any subclass of Creature can also have its own list.)
  • In the Initialize method, the new creature passes itself to the creature class
  • The creature class adds a link to this creature at @creaturelist and returns the identifier of the creature.
  • The creature remembers this identifier in its own @id variable.
  • If the creature dies, it calls the parent class with Creature.remove(@id) , and only the reference to itself is deleted.

Now I can do it:

 class Predator < Creature def eat(creature) @energy += creature.energy creature.die end end fish = Creature.new Creature.list #shows the fish croc = Predator.new croc.eat(fish) Creature.list #no more fish 

Of course, in this example, fish still points to this creature object, so it does not collect garbage. But ultimately, the creatures will be created and eat each other on the basis of the rules, so I will not individually name them.

+6
garbage-collection ruby
source share
5 answers

I think that the problem is that you think of the program itself as a world in which these simulated things live, not imitate.

 fish = Creature.new croc = Crocodile.new $world = [fish, croc] class Crocodile def eat(creature) @energy += creature.energy $world.delete creature end end croc.eat fish world # [croc], now all by his lonesome, the last creature in the world :( 

And assuming that the fish variable has gone out of scope, as it would be in a well-structured program, this object is likely to be garbage now.

+7
source share

Nothing can be safely collected by garbage unless there is a link to it in any active area.

+2
source share

croc.eat (fish) will close the croc link to the Creature referenced by the fish, but note that the fish variable still contains a reference to that Creature, so the instance is not garbage.

edit: Think of it this way: Inside the croc, you don't get fish, you get a copy of what's inside the fish. A fish value is a reference to an object you created using Creature.new. A copy of this link is copied to the variable being when croc.eat (fish) is executed. So now both the fish and the creature have references to the same object.

It is like a balloon floating in the air, with two ropes tied to it. the fish holds one line, and the creature holds another line. when you set the creature to zero, it releases its holding in the balloon, but the fish still holds in the balloon with its own string, so the balloon does not float into the large garbage collector in the sky.

edit 2: No, you cannot (without any deep magic, which would be a very bad idea to do) reach out to catch fish and destroy its link to the object in question.

+1
source share

You are not "destroying the object" - GC does this for you. You talk about being in a method, and go out into the call area and change the binding there.

If the binding was part of the object and you passed the object, you can reassign it (to zero) from there.

0
source share

One Ruby object (usually) should not destroy another. Do not worry about whether or not objects exist. The only exception - if you are using a database repository - you might be wondering if objects are deleted or not.

But in general, my answer is this: you should not care. (However, other answers make sense).

0
source share

All Articles