Как вы явно уничтожаете объект в Perl?

Скажем, у меня есть класс Perl, который имеет метод DESTROY. Этот метод используется для неявного выпуска внешнего ресурса, такого как дескриптор файла или транзакция базы данных.

Учитывая экземпляр этого класса, я хотел бы явно его уничтожить. Основная цель этого заключается в том, чтобы вызвать метод DESTROY, чтобы можно было освободить внешний ресурс. Однако наличие самого "объекта", выпущенного из памяти, будет дополнительным преимуществом.

Как я могу это сделать? Я рассмотрел прямое обращение к методу DESTROY и определение каких-либо переменных, ссылающихся на объект.

Ответы

Ответ 1

Объекты Perl5 разрушаются, как только последняя ссылка на них исчезает, если у вас нет самореферентных структур (см. Destructors и После двух этапов сборка мусора для некоторой интересной информации).

Если у вас нет собственных ссылок, вам не нужно ни о чем беспокоиться, метод DESTROY будет вызываться, когда это необходимо; пытаясь уничтожить объект самостоятельно, не будет безопасным (как вы можете быть уверены, что объект не является ссылкой где-то еще), если вы также не выполняете подсчет ссылок самостоятельно (если это действительно возможно, и это будет дублировать усилия perl, которые это не такая хорошая идея).

Итак, я бы сказал, до тех пор, пока у вас нет циклических ссылок:

  • Если вы хотите освободить внешние ресурсы в определенной точке вашего кода, сделайте это явно с помощью метода release/close/dispose/whatever (который может вызвать и ваш код DESTROY).
  • Если вам не все равно, что релиз происходит именно в этот момент вашего кода, просто он вызывает вызов в конце концов, не беспокойтесь об этом.
  • Не беспокойтесь о самом объекте perl.

Если у вас есть циклические ссылки, вам нужно быть более осторожными и использовать слабые ссылки (см. Scalar::Util) на разбить циклы.

(Другими словами, я не знаю, как явно указать delete объект perl. Это плохо работает с системой сбора мусора, подсчитанной по ссылке.)

Ответ 2

Вы можете использовать undef для явного уничтожения объекта. Этот код иллюстрирует это.

package MyPackage;

sub new {
    print "In new\n";
    return bless {};
}

sub DESTROY {
    print "In DESTROY\n";
}

package main;

my $Obj = MyPackage->new();
<STDIN>;
undef $Obj;
<STDIN>;