4

これは私の同僚が抱えている厄介な問題です。そして、私も原因を解明することができませんでした。

短いバージョンは、彼が書いたクラスで、DESTROYデストラクタ/メソッドが定義されてDESTROYおり、オブジェクトが破棄されたときに呼び出されません。オブジェクトがスコープ外になると思った時点では呼び出されません。そして、どこかにぶら下がっている参照があるかもしれないと考えましたが、スクリプトの終了時にも呼び出されていません。クラスとスクリプトにデバッグprintステートメントを散らかし、ブロック内で明示的に呼び出してEND、間違った名前空間に配置されていないことを確認しました。(私たちはしませんでした。明示的な呼び出しはprint、期待どおりにすべてのステートメントをトリガーしました。)

だから私はこれに戸惑い、彼と同じように答えに興味を持っています。どのような状況がこの動作につながる可能性がありますか?問題のスクリプトは正常に終了しています-呼び出しPOSIX::_exitなどはありません。この中の唯一の「変数」は、クラスがClass::MethodMakerいくつかのアクセサーとコンストラクターを定義するために使用していることです。ただし、Class::MethodMakerドキュメントには、クラスDESTROYメソッドとの相互作用(またはオーバーライド)についての参照はありません。

4

3 に答える 3

6

DESTROYが呼び出されない別の方法がありますが、これは特に明確に文書化されていません。ただし、デーモンなどを作成している場合にのみ影響します。基本的に、シグナル(実際にはSIGINTであるCTRL-Cでさえ)が原因でプロセスが停止した場合、DESTROYメソッドは呼び出されません。ただし、exit()を呼び出すだけのシグナルハンドラーを使用することで、これを実現できます。以下の例では、プログラムが通常どおり終了した場合、またはSIGTERMを受信した場合に、DESTROY()メソッドが呼び出されます。

sub _signal_handler {
  exit(0);
}

sub new {
  my ($class) = @_;
  my $self = {};
  bless $self, $class;
  SIG{'TERM'} = \&_signal_handler;
  return $self;
}

sub DESTROY {
  my ($self) = @_;
  print "Destroy method called\n";
}
于 2012-10-17T17:20:39.487 に答える
6

コードを見なければ、何が問題なのかわかりません。しかし、DESTROY() メソッドが呼び出されていないように見えるシナリオを想像できます。

#!/usr/bin/perl

use strict;
use warnings;

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

{
    print "creating object...\n";
    my $obj = bless {};
    print "it goes out of scope...\n";
}

print "object is out of scope\n";

このスクリプトは以下を出力します。

creating object...
it goes out of scope...
object is out of scope

おそらく、エラーはこの例ほど明らかではありません。die() 呼び出しは、DESTROY コードの奥深くにある可能性があります。

die() 呼び出しは、考えもしなかった何らかの条件によって引き起こされた可能性があります。グローバルな破棄中、オブジェクトは任意の順序で定義解除されます。

#!/usr/bin/perl

use strict;
use warnings;

sub DESTROY {
    die {} if ! defined $_[0]->[0];
    print "$_[0]->DESTROY()\n";
}

print "creating objects...\n";
my $x = bless [];
my $y = bless [$x];
$x->[0] = $y;
print "before global destruction...\n";

これが発生するために循環参照は必要ありません。オブジェクトの 1 つは、別のオブジェクトにアクセスできるかどうかを確認します。アクセスに失敗すると、例外がスローされます。

h2h、マティアス

于 2012-06-05T15:08:23.940 に答える