你如何在Perl中明确地销毁一个对象?

时间:2022-05-10 19:32:23

Let's say I have a Perl class that has a DESTROY method. This method is used to implicitly release an external resource, such as a file handle or database transaction.

假设我有一个具有DESTROY方法的Perl类。此方法用于隐式释放外部资源,例如文件句柄或数据库事务。

Given an instance of this class, I would like to explicitly destroy it. The primary purpose of this is to cause the DESTROY method to be called so the external resource can be released. However, having the "object" itself released from memory would be an added benefit.

给定这个类的一个实例,我想明确地销毁它。这样做的主要目的是使DESTROY方法被调用,以便释放外部资源。然而,让“对象”本身从内存中释放将是一个额外的好处。

How can I do this? I have considered directly calling the DESTROY method and undefining any variables that reference the object.

我怎样才能做到这一点?我考虑直接调用DESTROY方法并取消定义引用该对象的任何变量。

2 个解决方案

#1


17  

Perl5 objects get destructed as soon as the last reference to them disappears, unless you have self-referential structures (see Destructors and the Two phase garbage collection paragraph after that for some interesting information).

Perl5对象一旦最后一次引用就会被删除,除非你有自引用结构(参见Destructors和之后的两阶段垃圾收集段以获得一些有趣的信息)。

If you don't have self-references, you don't need to worry about anything, the DESTROY method will be called when it needs to be; trying to destruct the object yourself would not be safe (how can you be sure the object isn't references somewhere else), unless you're also doing reference counting yourself (if that's actually possible, and that would be duplicating perl's efforts, which isn't such a good idea).

如果你没有自引用,你不需要担心任何事情,DESTROY方法将在需要时被调用;试图破坏对象本身并不安全(你怎么能确定对象不是其他地方的引用),除非你自己也做引用计数(如果这实际上是可能的,那将会重复perl的工作,不是一个好主意)。

So I'd say, as long as you don't have cyclic references:

所以我会说,只要你没有循环引用:

  • If you want to release external resources at a specific point in your code, do so explicitly with a release/close/dispose/whatever method (that your DESTROY code could call too).
  • 如果要在代码中的特定点释放外部资源,请使用release / close / dispose / whatever方法(您的DESTROY代码也可以调用)明确地执行此操作。
  • If you don't really care that that release happens exactly at that point in your code, just that it does get called eventually, don't worry about it.
  • 如果你真的不在乎那个版本恰好在你的代码中发生了那个版本,那么它最终会被调用,不要担心它。
  • Don't worry about the perl object itself.
  • 不要担心perl对象本身。

If you do have cyclic references, you'll need to be much more careful, and use weak references (see Scalar::Util) to break the cycles.

如果你有循环引用,你需要更加小心,并使用弱引用(参见Scalar :: Util)来打破循环。

(In other words, I don't know of a way to explicitly delete a perl object. That doesn't work well with a reference-counted garbage collection system.)

(换句话说,我不知道显式删除perl对象的方法。这对于引用计数的垃圾收集系统不起作用。)

#2


4  

You can use undef to explicitly destroy an object. The below code illustrates it.

您可以使用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>;

#1


17  

Perl5 objects get destructed as soon as the last reference to them disappears, unless you have self-referential structures (see Destructors and the Two phase garbage collection paragraph after that for some interesting information).

Perl5对象一旦最后一次引用就会被删除,除非你有自引用结构(参见Destructors和之后的两阶段垃圾收集段以获得一些有趣的信息)。

If you don't have self-references, you don't need to worry about anything, the DESTROY method will be called when it needs to be; trying to destruct the object yourself would not be safe (how can you be sure the object isn't references somewhere else), unless you're also doing reference counting yourself (if that's actually possible, and that would be duplicating perl's efforts, which isn't such a good idea).

如果你没有自引用,你不需要担心任何事情,DESTROY方法将在需要时被调用;试图破坏对象本身并不安全(你怎么能确定对象不是其他地方的引用),除非你自己也做引用计数(如果这实际上是可能的,那将会重复perl的工作,不是一个好主意)。

So I'd say, as long as you don't have cyclic references:

所以我会说,只要你没有循环引用:

  • If you want to release external resources at a specific point in your code, do so explicitly with a release/close/dispose/whatever method (that your DESTROY code could call too).
  • 如果要在代码中的特定点释放外部资源,请使用release / close / dispose / whatever方法(您的DESTROY代码也可以调用)明确地执行此操作。
  • If you don't really care that that release happens exactly at that point in your code, just that it does get called eventually, don't worry about it.
  • 如果你真的不在乎那个版本恰好在你的代码中发生了那个版本,那么它最终会被调用,不要担心它。
  • Don't worry about the perl object itself.
  • 不要担心perl对象本身。

If you do have cyclic references, you'll need to be much more careful, and use weak references (see Scalar::Util) to break the cycles.

如果你有循环引用,你需要更加小心,并使用弱引用(参见Scalar :: Util)来打破循环。

(In other words, I don't know of a way to explicitly delete a perl object. That doesn't work well with a reference-counted garbage collection system.)

(换句话说,我不知道显式删除perl对象的方法。这对于引用计数的垃圾收集系统不起作用。)

#2


4  

You can use undef to explicitly destroy an object. The below code illustrates it.

您可以使用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>;