1

「Programming Perl」という本を読みましたが、かなり複雑なところがあります。それらの場所の 1 つは、第 12 章「オブジェクト」のセクション「インスタンス デストラクタ」です。このセクションは次のように述べています。

  1. Perl のオブジェクトは、それらへの参照がなくなると破棄されます。
  2. DESTROYクラスでメソッドを定義することにより、オブジェクトがリサイクルされる直前に制御を取得する機会があります。
  3. Perl ではデストラクタが必要になることはめったにありませんが、一部のオブジェクトには、メモリ システムの外部にあるファイルハンドルやデータベース接続などがある場合があります。したがって、特別に出席する必要があります。
  4. Perl は階層的な破壊を行いません。

次に、私が理解できなかった段落があります:

これは、継承されたクラスにのみ適用されます。たとえば、より大きなハッシュの 1 つの値など、現在のオブジェクトに含まれているだけのオブジェクトは、自動的に解放され、破棄されます。これが、単なる集約 (「has-a」関係と呼ばれることもある) によるコンテナーシップが継承 (「is-a」関係) よりもクリーンで明確である理由の 1 つです。

私はそれが何を意味するのか理解できません。現在のオブジェクトに単純に含まれていないオブジェクトは、 自動的に解放および破棄されないということですか?

DESTROYガベージ コレクションで呼び出された a が最も近いものであり、唯一のものであることは知っています。DESTROYインスタンスへの参照がない場合、他のオーバーライドされたメソッドは呼び出されません。しかし、私が理解しているように、インスタンスへの参照が別のオブジェクト内に配置されている場合、同じ動作が予想されます。

誰かが解釈してコード例を提供するのはとても楽しいでしょうか?


アップデート:

実際に私が探していたのは、継承されたクラスにのみ適用されるの説明でした。それが判明した言葉:

クラスのインスタンスがあり、そのメソッドが親クラスのDESTROYメソッドをオーバーライドするよりもメソッドがある場合、それは問題のオブジェクトとの関係にあるDESTROYオブジェクトには適用されません。has-aそれDESTROYはオーバーライドされません

明確でない質問で申し訳ありませんが、英語と使用法に適していると思います。みんなありがとう。

4

4 に答える 4

3

ルール1:Perlのオブジェクトは、それらへの参照がなくなると破棄されます。

{
  my $object = Class->new()
}
# there are no more references to $object
# (it is out of scope and can't be accessed by any means)
# Perl is free to garbage-collect it.

ルール2:クラスでDESTROYメソッドを定義することにより、オブジェクトがリサイクルされる直前にコントロールをキャプチャする機会があります。

package Class;
sub new     { return bless({}, shift) }
sub DESTROY { print STDERR "The object is destroyed" }

####

{
  my $object = Class->new();
}
# before the object is garbage-collected, cleanup-operations should be manually performed
# like closing down connections, solving circular references
# any time, the object might print it's message.

ルール4:Perlは階層的破壊を行いません。

package AnotherClass;
use Class;
use parent 'Class';
sub DESTROY { print STDERR "subclass reporting dead" }

AnotherClassこれで、インスタンス化される場合、のメソッドではなく、のDESTROYメソッドのみAnotherClass が呼び出されます。これは、階層的な破壊がないことを意味します。メソッドが前のエントリを上書きするため、これは明らかです。オリジナルは手動で呼び出すことができますDESTROYClassDESTROYDESTROY

親クラスと子クラスの使用はIS-A関係です:AnotherClassClassです。

YetAnotherClassがある場合:

package YetAnotherClass;
use Class;
sub new {return bless({member => Class->new()}, shift) }

{
   my $object = YetAnotherClass->new();
}
# $object goes out of scope (zero reference count) and will be destroyed.
# Therefore, the reference count of the "member" drops to zero
# The member will therefore be destroyed and print it's message.

これは、集約(ClassのデータメンバーYetAnotherClass)の場合であり、HAS-A関係です。

于 2012-09-15T08:36:12.680 に答える
2
  1. has-a 関係では、多くの場合、オブジェクトは他のオブジェクトへの参照を持ちます。したがって、クラスが与えられVanた場合、a のインスタンスにVanwheelがあります。そのインスタンスが破棄されると、perl (プログラム) はWheelオブジェクトのデストラクタを別々に呼び出します。これは、オブジェクトが 2 つの異なるオブジェクトであるためです。

  2. is-a 関係では、Van ISVehicleの参照は、問題のオブジェクトの同じ参照です。したがって、一部の言語のようにDESTROY、継承されたすべてのクラスを呼び出して階層をたどることはなく、単純DESTROYにそれぞれの bless された参照に対して 1 回呼び出します。

注: #1 が常に当てはまるとは限りません。たとえば、インサイドアウト オブジェクトはサブクラスへの参照を含まず、アドレスがパッケージ内のレキシカル ハッシュへのキーとして使用される祝福されたスカラー参照です。永続パッケージの字句スコープは、オブジェクトではなく参照を保持します。しかし、これは、クラスのクリーンアップと is-a/has-a 関係との間の直接的な相関関係をなくすのに役立ちます。

perl がこれらの has-a 関係を自動的に取得しないにもかかわらず、の破棄を行う必要があることは明らかです。

したがって、これを理解するための鍵は、has-a 関係では、破棄する必要がある別の参照があるということだと思います。Perl は、参照カウントがデクリメントされると自動的にこれを行うか、自分で行う必要があります。

于 2012-09-15T10:33:58.127 に答える
1

has-a 関係は、オブジェクトが単に別のタイプのオブジェクトを格納する関係です。オブジェクトが数値や文字列を格納できるように、別のオブジェクトも格納できます。それよりも複雑なことはありません。

package MyClass;
sub new {
  my $class = shift;
  my $obj = bless {}, $class;
  $obj->{some_thing_else} = SomeOtherClass->new;
}

is-a 関係は、継承の別名です。

package SomeSubClass;
use parent 'SomeParentClass'; 
# older ways to do this are 'use base' and pushing on @ISA.

これらの概念は Perl に関するものなので特に何もありませんが、上で Perl の例を示しました。

最初の例は、標準的な Perl クラスです。2 番目の例は has-a 関係です。どちらのコードも継承の例を省略していません (is-a)。

[ちなみに、blessメソッドを呼び出すときnewは、(上で示したように) new の最初のパラメーターからクラス名を取得する必要があります。そうしないと、 をオーバーライドせずにクラスから継承することができなくなりますnew。を呼び出しSomeSubClass->new、SomeSubClass が SomeParentClass から new を継承し、SomeParentClass が先ほど行ったことを実行すると、SomeSubClass の代わりにクラス SomeParentClass のオブジェクトが取得されます。(もちろん、何らかの理由で、クラスを継承可能にしたくない場合や、 new をオーバーライドしたい場合もあります。)]

Perl のオブジェクト システムは非常に基本的なものであり、必要なものは何でも作成できます。しかし、コミュニティは Moose と呼ばれるものに移行しています。これは、上に構築されたより洗練されたオブジェクト システムを提供する CPAN モジュールです。

于 2012-09-15T08:21:59.213 に答える
1

継承は「is-a」の関係であり、クラス/パッケージが持つ属性 (「has」を含むムース) または祝福されたオブジェクトのハッシュキー (たとえば、オブジェクトがハッシュリファレンスに祝福されていると仮定) は、has-a

于 2012-09-15T08:23:04.493 に答える