В Ruby один объект может уничтожить другой?
Например:
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)
После того, как крокодил съел существо и поглотило его энергию, существо должно перестать существовать. Но приведенный выше код не уничтожает существо.
Я знаю, что если я скажу fish = nil
, объект, на который ссылается переменная fish
, будет собран мусором. Но сказать, что creature = nil
внутри метода Крокодила eat
, этого не добиться.
Еще один способ выразить это
Изнутри croc.eat, могу ли я сказать "поскольку переменная 'fish' была передана мне, когда я закончу, я собираюсь установить 'fish' в ноль?"
Обновление: проблема решена
Я, по сути, принял подход, предложенный Чаком, с некоторыми изменениями. Вот мои рассуждения:
- Если переменная, указывающая на объект, больше не будет, это будет сборщик мусора
- Если при создании объекта я добавляю его в хеш (например, «x» => объект) и не создаю для него никакой другой переменной, то удаление этого элемента из хеша приводит к сбору мусора объект
- Кажется логичным, что список всех существ должен храниться в классе Существа
Поэтому я сделал это:
- В объекте класса Creature я создал хеш и присвоил его переменной экземпляра. Мы назовем это
@creaturelist
. (Причина, по которой я использовал переменную экземпляра, а не переменную класса, заключается в том, что любой подкласс Creature
также может иметь свой собственный список.)
- В методе Initialize новое существо передает себя в класс Существа
- Класс Существо добавляет ссылку на это существо к
@creaturelist
и возвращает идентификатор существу.
- Существо запоминает этот идентификатор в своей собственной переменной
@id
.
- Если существо умирает, оно вызывает родительский класс с
Creature.remove(@id)
, и единственная ссылка на него удаляется.
Теперь я могу сделать это:
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
Конечно, в этом примере fish
по-прежнему указывает на этот объект существа, поэтому он не является сборщиком мусора. Но в конце концов, существа будут создаваться и есть друг друга по правилам, поэтому я не буду называть их по отдельности.