Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Thursday, February 18, 2016

Can one Ruby object destroy another?

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 has eaten a creature and absorbed its energy, the creature should cease to exist. But the code above doesn't destroy the creature.

I know that if I say fish = nil, the object that the varible fish refers to will be garbage collected. But saying creature = nil inside the Crocodile's eat method doesn't accomplish that.

Another way of putting it

From inside croc.eat, can I say "since the variable 'fish' was passed to me, when I'm done, I'm going to set 'fish' to nil?"

Update: problem solved

I've essentially taken the approach that Chuck suggested, with some modifications. Here was my reasoning:

  1. If there is no longer any variable pointing to an object, it will be garbage collected
  2. If, when an object is created, I add it to a hash (like 'x' => object), and don't create any other variable for it, then deleting that item from the hash results in garbage collecting the object
  3. It seems logical that a list of all creatures should be stored in the Creature class

Therefore, I did this:

  1. On the Creature class object, I created a hash and assigned it to an instance variable. We'll call it @creaturelist. (The reason I used an instance variable and not a class variable is so that any subclass of Creature can have its own list, too.)
  2. In the Initialize method, a new creature hands itself to the Creature class
  3. The Creature class adds a reference to that creature to @creaturelist and returns an ID to the creature.
  4. The creature remembers that ID in its own @id variable.
  5. If the creature dies, it calls the parent class with Creature.remove(@id), and the only reference to itself gets deleted.

Now I can do this:

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 that creature object, so it's not garbage collected. But eventually, creatures will be created and eat each other based on rules, so I won't be individually naming them.

Answer by Azeem.Butt for Can one Ruby object destroy another?


Nothing can be safely garbage collected until there are no references to it in any active scope.

Answer by Ken for Can one Ruby object destroy another?


You aren't "destroying an object" -- the GC does that for you. You're talking about being in a method, and reaching out into the caller's scope and changing a binding there.

If the binding was part of an object, and you passed the object in, you could reassign it (to nil) from there.

Answer by mbarnett for Can one Ruby object destroy another?


croc.eat(fish) will nil out croc's reference to the Creature referenced by fish, but note the variable "fish" itself still holds a reference to that Creature, so the instance is not garbage.

edit: Think about it this way: Inside of croc, you're not getting fish, you're getting a copy of what's inside of fish. fish's value is a reference to the object you created with Creature.new. A copy of that reference is copied into the variable creature when you execute croc.eat(fish). So now both fish and creature have references to the same object.

It's like there's a balloon floating in the air, with two strings tied to it. fish is holding one string, and creature is holding another string. when you set creature to nil, it releases its hold on the balloon, but fish is still holding onto the balloon by its own string, so the balloon doesn't float away to the big garbage collector in the sky.

edit 2: No, you can't (without some deep magic that it would be a very bad idea to perform), reach out to fish and wipe out its reference to the object in question.

Answer by Peter for Can one Ruby object destroy another?


One Ruby object (usually) shouldn't destroy another. It's not your job to worry about whether objects still exist or not. The one exception would be if you are using a database store - there you might care about whether the objects are deleted or not.

But in general, my answer is: you shouldn't care about this. (The other answers do make sense, though.)

Answer by Chuck for Can one Ruby object destroy another?


I think the problem is that you're thinking of the program itself as the world in which these simulated things live rather than simulating one.

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 the fish variable had gone out of scope like it would in a properly structured program, that object would most likely now be garbage.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.