NAME ¶
perlobj - Perl objects
perlobj - Perl のオブジェクト
説明¶
First you need to understand what references are in Perl. See perlref for that. Second, if you still find the following reference work too complicated, a tutorial on object-oriented programming in Perl can be found in perltoot and perltooc.
まず最初に、あなたが Perl におけるリファレンスがなんであるかを理解している 必要があります。 perlref を参照してください。 第二に、これから説明するリファレンスの動作が複雑すぎると思うようなら、 Perl におけるオブジェクト指向プログラミングのチュートリアルが perltoot と perltooc にあります。
If you're still with us, then here are three very simple definitions that you should find reassuring.
ここまででまだ読み進める気があるのなら、あなたを安心させるだろう 三つの非常に単純な定義があります。
-
An object is simply a reference that happens to know which class it belongs to.
オブジェクトとは、単に自分がどのクラスに属しているのかを 知っているようなリファレンスです。
-
A class is simply a package that happens to provide methods to deal with object references.
クラスとは、単にオブジェクトのリファレンスを取り扱うメソッドを 提供するパッケージです。
-
A method is simply a subroutine that expects an object reference (or a package name, for class methods) as the first argument.
メソッドとは、単にその第一引数にオブジェクトのリファレンス (もしくはクラスのメソッドに対するパッケージ名)を取るような サブルーチンです。
We'll cover these points now in more depth.
これらのポイントを、より深く掘り下げて行きます。
オブジェクトは単なるリファレンス¶
Unlike say C++, Perl doesn't provide any special syntax for constructors. A constructor is merely a subroutine that returns a reference to something "blessed" into a class, generally the class that the subroutine is defined in. Here is a typical constructor:
C++ とは違って、Perl はコンストラクタに対して特別な構文を用意していません。 コンストラクタは単に、クラスに "bless" したなにかのリファレンスを 返すようなサブルーチンで、一般的にはサブルーチンが定義されているクラスです。 以下に典型的なコンストラクタを示します。
package Critter;
sub new { bless {} }
That word new
isn't special. You could have written a construct this way, too:
new
という語は特別なものではありません。 コンストラクタを以下のように記述することもできます:
package Critter;
sub spawn { bless {} }
This might even be preferable, because the C++ programmers won't be tricked into thinking that new
works in Perl as it does in C++. It doesn't. We recommend that you name your constructors whatever makes sense in the context of the problem you're solving. For example, constructors in the Tk extension to Perl are named after the widgets they create.
実際のところ、これは C++ プログラマーが C++ と同じように Perl の new
が動くと考えて落とし穴にはまることがないという点で 好ましいものではあります。 あなたには、あなたが解決しようとしている問題に関するコンテキスト でわかりやすいコンストラクタにすることをお奨めします。 例を挙げると、Perl の Tk エクステンションのコンストラクタでは、 作成するウィジェットから名前を取っています。
One thing that's different about Perl constructors compared with those in C++ is that in Perl, they have to allocate their own memory. (The other things is that they don't automatically call overridden base-class constructors.) The {}
allocates an anonymous hash containing no key/value pairs, and returns it The bless() takes that reference and tells the object it references that it's now a Critter, and returns the reference. This is for convenience, because the referenced object itself knows that it has been blessed, and the reference to it could have been returned directly, like this:
Perl のコンストラクタに関して C++ と違うことは、 C++ では自分でメモリを割り当てる必要があるということです。 {}
は空の無名ハッシュを割り当てます。 bless() は引数にリファレンスを取り、そのオブジェクトにオブジェクトが Critter のリファレンスであることを教え、リファレンスを返します。 参照されているオブジェクトはそれ自身自分が bless されていることを知っていて、 リファレンスは以下の例のように直接返すことができます。
sub new {
my $self = {};
bless $self;
return $self;
}
You often see such a thing in more complicated constructors that wish to call methods in the class as part of the construction:
実際のところ、構築の一部としてクラスのメソッドを呼び出すようなもっと 複雑なコンストラクタを良く見かけることでしょう。
sub new {
my $self = {};
bless $self;
$self->initialize();
return $self;
}
If you care about inheritance (and you should; see "Modules: Creation, Use, and Abuse" in perlmodlib), then you want to use the two-arg form of bless so that your constructors may be inherited:
継承について心配していて(そうあるべきなのですが。 "Modules: Creation, Use, and Abuse" in perlmodlibを参照してください)、 継承されているかもしれないコンストラクタで引数二つを取る形式の bless を 使いたいのであれば:
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->initialize();
return $self;
}
Or if you expect people to call not just CLASS->new()
but also $obj->new()
, then use something like the following. (Note that using this to call new() on an instance does not automatically perform any copying. If you want a shallow or deep copy of an object, you'll have to specifically allow for that.) The initialize() method used will be of whatever $class we blessed the object into:
あるいは、ユーザーが CLASS->new()
ではなく $obj->new()
を使うことを期待しているのであれば、以下のような形式を使います。 (インスタンスに対して new() を呼び出すのにこれを使っても、自動的なコピーは 一切行われないことに注意してください。 もしオブジェクトに対して浅い、あるいは深いコピーを望むなら、それが できるように特に処理しなければならないでしょう。) initialize() というメソッドは $class を私たちがオブジェクトに bless しているかどうかに関らず使われます。
sub new {
my $this = shift;
my $class = ref($this) || $this;
my $self = {};
bless $self, $class;
$self->initialize();
return $self;
}
Within the class package, the methods will typically deal with the reference as an ordinary reference. Outside the class package, the reference is generally treated as an opaque value that may be accessed only through the class's methods.
クラスパッケージの中では、メソッドはリファレンスを普通のリファレンスとして 扱うでしょう。 クラスパッケージの外側では、リファレンスは一般的にクラスメソッドを 通してのみアクセスすることのできる不透明な値(opaque value)であるかのように 扱われます。
Although a constructor can in theory re-bless a referenced object currently belonging to another class, this is almost certainly going to get you into trouble. The new class is responsible for all cleanup later. The previous blessing is forgotten, as an object may belong to only one class at a time. (Although of course it's free to inherit methods from many classes.) If you find yourself having to do this, the parent class is probably misbehaving, though.
コンストラクタは現在参照されているオブジェクトを別のクラスに 属させるために、再 bless するかもしれません; これはほとんど確実にトラブルに巻き込まれます。 しかし、その新しいクラスは、後で掃除する原因となります。 オブジェクトは一度に一つのクラスにしか属することができないかのように 以前の bless は忘れ去られます(多くのクラスからメソッドを継承することが 自由にできるとしても、です)。 もし再ブレスしなければならないというのなら、その親クラスは不正な 振る舞いをしています。
A clarification: Perl objects are blessed. References are not. Objects know which package they belong to. References do not. The bless() function uses the reference to find the object. Consider the following example:
解説: Perl のオブジェクトは bless されています。 リファレンスはそうではありません。 オブジェクトは自分が属しているパッケージがなんであるか知っていますが、 リファレンスは知りません。 関数 bless() はリファレンスをオブジェクトとみなすために使われます。 以下の例を見てください。
$a = {};
$b = $a;
bless $a, BLAH;
print "\$b is a ", ref($b), "\n";
This reports $b as being a BLAH, so obviously bless() operated on the object and not on the reference.
これは "$b as being a BLAH" と表示されます; これで明らかなように、bless() はリファレンスに対してではなく オブジェクトに作用します。
クラスは単なるパッケージ¶
Unlike say C++, Perl doesn't provide any special syntax for class definitions. You use a package as a class by putting method definitions into the class.
C++ とは異なり、Perl はクラス定義に対する特別な構文を用意してはいません。 パッケージを、メソッド定義を押し込められたクラスとして使います。
There is a special array within each package called @ISA, which says where else to look for a method if you can't find it in the current package. This is how Perl implements inheritance. Each element of the @ISA array is just the name of another package that happens to be a class package. The classes are searched for missing methods in depth-first, left-to-right order by default (see mro for alternative search order and other in-depth information). The classes accessible through @ISA are known as base classes of the current class.
各パッケージには、カレントのパッケージでメソッドを見つけられなかったときに メソッドを探しに行く別のパッケージを指示する @ISA と呼ばれる 特殊な配列があります。 これが、Perl が継承を実装しているやり方です。 配列 @ISA の各要素は、クラスパッケージである別のパッケージの名前です。 見つからないメソッドは、デフォルトでは深さ優先、左から右の順序でクラスを 探します。 (その他の検索順と、その他のより深い情報については mro を 参照してください)。 @ISA を通じてでアクセスすることのできるクラスは、カレントクラスの 基底クラスとして知られています。
All classes implicitly inherit from class UNIVERSAL
as their last base class. Several commonly used methods are automatically supplied in the UNIVERSAL class; see "Default UNIVERSAL methods" or UNIVERSAL for more details.
全てのクラスは暗黙のうちにその基底クラスとして UNIVERSAL
という クラスを継承しています。 UNIVERSAL クラスで自動的に提供される一般的に使われるメソッドが いくつかあります。 詳しくは "Default UNIVERSAL methods" または UNIVERSAL を 参照してください。
If a missing method is found in a base class, it is cached in the current class for efficiency. Changing @ISA or defining new subroutines invalidates the cache and causes Perl to do the lookup again.
基底クラスで探しているメソッドが見つかれば、効率のために そのメソッドはカレントクラスでキャッシングされます。 @ISA の変更や新たなサブルーチンの定義はキャッシュを無効化し、Perl に再度の 走査を行わせます。
If neither the current class, its named base classes, nor the UNIVERSAL class contains the requested method, these three places are searched all over again, this time looking for a method named AUTOLOAD(). If an AUTOLOAD is found, this method is called on behalf of the missing method, setting the package global $AUTOLOAD to be the fully qualified name of the method that was intended to be called.
カレントクラス、名前つきの基底クラス、UNIVERSAL クラスを検索して、 これらのいずれもが要求されたメソッドを持っていなければ、 AUTOLOAD() という名前のメソッドを検索します。 AUTOLOAD が見つかれば、このメソッドは見失ったメソッドの途中で 呼び出され、パッケージグローバルの $AUTOLOAD をメソッドの完全修飾名に なるように設定します。
If none of that works, Perl finally gives up and complains.
ここまで全部失敗したならば、Perl は音を上げてエラーメッセージを出します。
If you want to stop the AUTOLOAD inheritance say simply
AUTOLOAD の継承を止めたい場合は、単に以下のようにすると:
sub AUTOLOAD;
and the call will die using the name of the sub being called.
呼び出しは予備されたサブルーチンの名前を使って die します。
Perl classes do method inheritance only. Data inheritance is left up to the class itself. By and large, this is not a problem in Perl, because most classes model the attributes of their object using an anonymous hash, which serves as its own little namespace to be carved up by the various classes that might want to do something with the object. The only problem with this is that you can't sure that you aren't using a piece of the hash that isn't already used. A reasonable workaround is to prepend your fieldname in the hash with the package name.
Perl のクラスはメソッドの継承のみを行います。 データの継承はクラス自身にまかされています。 このことは Perl の問題ではありません。 なぜなら、大部分のクラスは無名ハッシュを使って、クラスのオブジェクトの 属性をモデル化しています。 この無名ハッシュはそのオブジェクトに対して何事かを行うような 様々なクラス毎に固有の名前空間を小さくきり分ける役割を果たします。 これに関する問題はあなたが使ったハッシュのひとかけらが 既に使われたものではないということに確信が持てないことです。 これに関する現実的な対応策は、ハッシュのフィールド名に パッケージ名を使うというものです。
sub bump {
my $self = shift;
$self->{ __PACKAGE__ . ".count"}++;
}
メソッドは単なるサブルーチン¶
Unlike say C++, Perl doesn't provide any special syntax for method definition. (It does provide a little syntax for method invocation though. More on that later.) A method expects its first argument to be the object (reference) or package (string) it is being invoked on. There are two ways of calling methods, which we'll call class methods and instance methods.
C++ とは異なり、Perl はメソッド定義に対する特別な構文を持っていません (しかしながら、後述するようにメソッドの起動のためにはちょっとした 構文を提供しています)。 メソッドはその第一引数として、そのメソッドを起動したオブジェクト (リファレンス)、もしくはパッケージ(文字列)を期待しています。 メソッドの呼び出し方にはには二種類あり、 それぞれ私たちがクラスメソッド、インスタンスメソッドと呼ぶものです。
A class method expects a class name as the first argument. It provides functionality for the class as a whole, not for any individual object belonging to the class. Constructors are often class methods, but see perltoot and perltooc for alternatives. Many class methods simply ignore their first argument, because they already know what package they're in and don't care what package they were invoked via. (These aren't necessarily the same, because class methods follow the inheritance tree just like ordinary instance methods.) Another typical use for class methods is to look up an object by name:
クラスメソッドは、その第一引数としてクラスの名前を期待します。 クラスメソッドはクラス全体に対する機能を提供するものであって、クラスに 属する個々のオブジェクトに対するものではありません。 コンストラクタは普通はクラスメソッドですが、 代替案については perltoot と perltooc を参照してください。 多くのクラスメソッドは単純にその第一引数を無視します。 これは、既に自分が置かれているパッケージの名前を知っているし、 パッケージがどのような経路で起動されたのかを 気にする必要がないからです。 (通常のインスタンスメソッドと同じようにクラスメソッドは継承木に 従っているので、これらが同一である必要はありません)クラスメソッドの もう一つの典型的な使用例は名前によってオブジェクトを 検査するためのものです。
sub find {
my ($class, $name) = @_;
$objtable{$name};
}
An instance method expects an object reference as its first argument. Typically it shifts the first argument into a "self" or "this" variable, and then uses that as an ordinary reference.
インスタンスメソッドは、その第一引数としてオブジェクトのリファレンスを 期待します。 典型的には、第一引数は "self" とか "this" といった変数に shift され、 以後は通常のリファレンスのように扱います。
sub display {
my $self = shift;
my @keys = @_ ? @_ : sort keys %$self;
foreach $key (@keys) {
print "\t$key => $self->{$key}\n";
}
}
メソッドの起動¶
For various historical and other reasons, Perl offers two equivalent ways to write a method call. The simpler and more common way is to use the arrow notation:
歴史的、あるいはその他の様々な理由によって、Perl はメソッド呼び出しを 書くための、二つの等価な方法を提供しています。 より単純でより一般的な方法は矢印記法を使うことです:
my $fred = Critter->find("Fred");
$fred->display("Height", "Weight");
You should already be familiar with the use of the ->
operator with references. In fact, since $fred
above is a reference to an object, you could think of the method call as just another form of dereferencing.
リファレンスに対する ->
演算子の使用については既に 親しんでいることでしょう。 実際のところ、上述の $fred
はオブジェクトへのリファレンスなので、 メソッド呼び出しを、単にデリファレンスの別の形と考えることができます。
Whatever is on the left side of the arrow, whether a reference or a class name, is passed to the method subroutine as its first argument. So the above code is mostly equivalent to:
矢印の左側に何があるか、リファレンスかクラス名か、は最初の引数として メソッドサブルーチンに渡されます。 従って、上述のコードは以下のものとほとんど等価です:
my $fred = Critter::find("Critter", "Fred");
Critter::display($fred, "Height", "Weight");
How does Perl know which package the subroutine is in? By looking at the left side of the arrow, which must be either a package name or a reference to an object, i.e. something that has been blessed to a package. Either way, that's the package where Perl starts looking. If that package has no subroutine with that name, Perl starts looking for it in any base classes of that package, and so on.
サブルーチンがどのパッケージにあるかを Perl はどうやって知るのでしょうか? 矢印の左側を見ます; これはパッケージ名かオブジェクトへのリファレンス (つまりパッケージに bless された何か) のどちらかである必要があります。 どちらの場合も、それが Perl が探し始めるパッケージです。 もしそのパッケージに指定された名前のサブルーチンがないなら、Perl は そのパッケージの基底クラスを探し始めます; それを繰り返します。
If you need to, you can force Perl to start looking in some other package:
もし必要なら、Perl に他のパッケージを見るように強制することも 可能です。
my $barney = MyCritter->Critter::find("Barney");
$barney->Critter::display("Height", "Weight");
Here MyCritter
is presumably a subclass of Critter
that defines its own versions of find() and display(). We haven't specified what those methods do, but that doesn't matter above since we've forced Perl to start looking for the subroutines in Critter
.
ここで MyCritter
は、おそらく自分自身の find() と display() を 定義しているCritter
のサブクラスです。 これらのメソッドが何をしているかは指定していませんが、 これらのサブルーチンを Critter
から探すように Perl に強制しているので、 それは問題になりません。
As a special case of the above, you may use the SUPER
pseudo-class to tell Perl to start looking for the method in the packages named in the current class's @ISA
list.
上記の特別な場合として、現在のクラスの @ISA
リストにあるパッケージから メソッドを探し始めるように Perl に指示する、SUPER
擬似クラスもあります。
package MyCritter;
use base 'Critter'; # sets @MyCritter::ISA = ('Critter');
sub display {
my ($self, @args) = @_;
$self->SUPER::display("Name", @args);
}
It is important to note that SUPER
refers to the superclass(es) of the current package and not to the superclass(es) of the object. Also, the SUPER
pseudo-class can only currently be used as a modifier to a method name, but not in any of the other ways that class names are normally used, eg:
SUPER
は、オブジェクトのスーパークラスではなく、カレントパッケージ の スーパークラスを参照するということに注意することは重要です。 また SUPER
擬似クラスは現在のところメソッド名への修飾子としてのみ 使え、普通に使われるクラス名のその他の方法は使えません。 つまり:
something->SUPER::method(...); # OK
SUPER::method(...); # WRONG
SUPER->method(...); # WRONG
Instead of a class name or an object reference, you can also use any expression that returns either of those on the left side of the arrow. So the following statement is valid:
クラス名やオブジェクトリファレンスの代わりに、矢印の左側に 置けるもののどちらかを返す任意の式も使えます。 従って、以下の文は有効です:
Critter->find("Fred")->display("Height", "Weight");
and so is the following:
そして以下のようにします:
my $fred = (reverse "rettirC")->find(reverse "derF");
The right side of the arrow typically is the method name, but a simple scalar variable containing either the method name or a subroutine reference can also be used.
矢印の右側は典型的にはメソッド名ですが、メソッド名やサブルーチン リファレンスが入った単純スカラ変数も使えます。
If the right side of the arrow is a scalar containing a reference to a subroutine, then this is equivalent to calling the referenced subroutine directly with the class name or object on the left side of the arrow as its first argument. No lookup is done and there is no requirement that the subroutine be defined in any package related to the class name or object on the left side of the arrow.
矢印の右側がサブルーチンへのリファレンスを含むスカラのとき、 これは最初の引数として矢印の左側のクラス名やオブジェクトを指定して リファレンスされたサブルーチンを直接呼び出すのと等価です。 検索は行われず、サブルーチンは矢印の左側のクラス名やオブジェクトに関係する パッケージに定義されている必要はありません。
For example, the following calls to $display are equivalent:
例えば、以下の $display の呼び出しは等価です:
my $display = sub { my $self = shift; ... };
$fred->$display("Height", "Weight");
$display->($fred, "Height", "Weight");
間接オブジェクト構文¶
The other way to invoke a method is by using the so-called "indirect object" notation. This syntax was available in Perl 4 long before objects were introduced, and is still used with filehandles like this:
メソッドを起動する他の方法は、「間接オブジェクト」記法と呼ばれる方法を 使うものです。 この文法は、オブジェクトが導入されるよりずっと以前の Perl 4 から 利用可能で、以下のように、ファイルハンドルで今でも使われています:
print STDERR "help!!!\n";
The same syntax can be used to call either object or class methods.
これと同じ構文を、クラスメソッドやインスタンスメソッドを呼び出すときに 使うことができます。
my $fred = find Critter "Fred";
display $fred "Height", "Weight";
Notice that there is no comma between the object or class name and the parameters. This is how Perl can tell you want an indirect method call instead of an ordinary subroutine call.
オブジェクトやクラス名とパラメータの間にカンマがないことに 注目してください。 これによって、通常のサブルーチン呼び出しではなく間接メソッド呼び出しを しようとしていることを Perl に伝えています。
But what if there are no arguments? In that case, Perl must guess what you want. Even worse, it must make that guess at compile time. Usually Perl gets it right, but when it doesn't you get a function call compiled as a method, or vice versa. This can introduce subtle bugs that are hard to detect.
しかし、引数がなかったら? この場合、Perl は求められているものを推測しなければなりません。 さらに悪いことに、この推測は コンパイル時 に行わなければなりません。 Perl は通常正しい答を得るのですが、そうでなかった場合、あなたはメソッドとして 関数呼び出しがコンパイルされたものを受け取ります。 これは検出が非常に困難なバグとなり得るものです。
For example, a call to a method new
in indirect notation (as C++ programmers are wont to make) can be miscompiled into a subroutine call if there's already a new
function in scope. You'd end up calling the current package's new
as a subroutine, rather than the desired class's method. The compiler tries to cheat by remembering bareword require
s, but the grief when it messes up just isn't worth the years of debugging it will take you to track down such subtle bugs.
例を挙げると、(C++ プログラマーがそうしたくなるような)new
という メソッドの間接表記での呼び出しは、カレントのスコープですでに new
関数が あった場合には間違ったサブルーチン呼び出しにコンパイルされてしまいます。 結果として、望んでいたクラスメソッドではなく、カレントパッケージの new
がサブルーチンとして呼び出されることになるのです。 コンパイラはこの問題を裸の単語の require
を覚えておくことによって 避けようと試みますが、それが失敗してしまった場合にはデバッグするのが とても面倒な結果となってしまうことになるでしょう。
There is another problem with this syntax: the indirect object is limited to a name, a scalar variable, or a block, because it would have to do too much lookahead otherwise, just like any other postfix dereference in the language. (These are the same quirky rules as are used for the filehandle slot in functions like print
and printf
.) This can lead to horribly confusing precedence problems, as in these next two lines:
この文法にも問題があります: 間接オブジェクトは名前、スカラ変数、 ブロックに限定されます; なぜなら、他の言語における 接尾辞デリファレンスと同様に、多すぎる先読みをする必要があるからです (これらは print
や printf
のような関数におけるファイルハンドルスロットと 同様な奇妙なルールです)。 これは次に挙げる例のように、混乱した優先順位問題を 導くことになります。
move $obj->{FIELD}; # probably wrong!
move $ary[$i]; # probably wrong!
Those actually parse as the very surprising:
これらはなんと以下のように解釈されるのです:
$obj->move->{FIELD}; # Well, lookee here
$ary->move([$i]); # Didn't expect this one, eh?
Rather than what you might have expected:
あなたが期待したのはこうでしょう:
$obj->{FIELD}->move(); # You should be so lucky.
$ary[$i]->move; # Yeah, sure.
To get the correct behavior with indirect object syntax, you would have to use a block around the indirect object:
間接オブジェクト構文の正しい振る舞いを得るためには、間接オブジェクトの周りに ブロックを使う必要があるかもしれません:
move {$obj->{FIELD}};
move {$ary[$i]};
Even then, you still have the same potential problem if there happens to be a function named move
in the current package. The ->
notation suffers from neither of these disturbing ambiguities, so we recommend you use it exclusively. However, you may still end up having to read code using the indirect object notation, so it's important to be familiar with it.
この場合でも、もし現在のパッケージにたまたま move
という名前の関数が あると、同じ潜在的問題があります。 ->
記法はこれらの物騒なあいまいさのどちらの影響も受けないので、 これだけを使うことを勧めます。 しかし、結局は間接オブジェクト記法を使ったコードを読む必要が あるかもしれないので、この記法に親しんでおくことが重要です。
デフォルトの UNIVERSAL メソッド¶
The UNIVERSAL
package automatically contains the following methods that are inherited by all other classes:
UNIVERSAL
パッケージには、他の全てのクラスが自動的に継承する 以下のようなメソッドがあります。
- isa(CLASS)
-
isa
returns true if its object is blessed into a subclass ofCLASS
isa
は、オブジェクトがCLASS
のサブクラスに bless されていれば true を返します。 - DOES(ROLE)
-
DOES
returns true if its object claims to perform the roleROLE
. By default, this is equivalent toisa
.DOES
は、オブジェクトがROLE
ロールを実行することを主張しているときに 真 を返します。 デフォルトでは、これはisa
と等価です。 - can(METHOD)
-
can
checks to see if its object has a method calledMETHOD
, if it does then a reference to the sub is returned, if it does not thenundef
is returned.can
はオブジェクトがMETHOD
というメソッドを持っているかどうかを検査し、 持っていればそのサブルーチンに対するリファレンスを返し、持っていなければundef
を返します。 - VERSION( [NEED] )
-
VERSION
returns the version number of the class (package). If the NEED argument is given then it will check that the current version (as defined by the $VERSION variable in the given package) not less than NEED; it will die if this is not the case. This method is called automatically by theVERSION
form ofuse
.VERSION
はクラス(パッケージ)のバージョン番号を返します。 引数 NEED が与えられている場合、カレントバージョン(指定されたパッケージ 変数 $VERSION で定義されます)が NEED よりも小さくないことを検査します。 もし小さければ die します。 このメソッドはuse
のVERSION
形式によって自動的に呼び出されます。use Package 1.2 qw(some imported subs); # implies: Package->VERSION(1.2);
デストラクタ¶
When the last reference to an object goes away, the object is automatically destroyed. (This may even be after you exit, if you've stored references in global variables.) If you want to capture control just before the object is freed, you may define a DESTROY method in your class. It will automatically be called at the appropriate moment, and you can do any extra cleanup you need to do. Perl passes a reference to the object under destruction as the first (and only) argument. Beware that the reference is a read-only value, and cannot be modified by manipulating $_[0]
within the destructor. The object itself (i.e. the thingy the reference points to, namely ${$_[0]}
, @{$_[0]}
, %{$_[0]}
etc.) is not similarly constrained.
あるオブジェクトに対する最後のリファレンスが消滅したとき、そのオブジェクトは 自動的に破棄されます(これはあなたがリファレンスを大域変数に格納していて、 プログラムを終了するときでもそうです)。 もしオブジェクトが解放される直前に制御を横取りしたいのであれば、クラスの 中で DESTROY メソッドを定義することができます。 このメソッドは適切な時期に自動的に呼び出され、あなたが必要とする クリーンアップを行うことができます。 デストラクトされるオブジェクトに対する第一引数(かつ唯一の引数)として リファレンスを渡します。 このリファレンスは読み込み専用の値であり、デストラクタの中で $_[0]
を操作することによって変更することはできません。 オブジェクトそれ自身(${$_[0]}
, @{$_[0]}
, %{$_[0]}
のような名前の ついたものに対するリファレンス)は同様に強制されません。
Since DESTROY methods can be called at unpredictable times, it is important that you localise any global variables that the method may update. In particular, localise $@
if you use eval {}
and localise $?
if you use system
or backticks.
DESTROY メソッドは予測不能な回数呼び出されるかもしれないので、 メソッドが更新する全てのグローバル変数をローカル化することが重要です。 特に、eval {}
を使うなら $@
を、system
や逆クォートを使うなら $?
をローカル化してください。
If you arrange to re-bless the reference before the destructor returns, perl will again call the DESTROY method for the re-blessed object after the current one returns. This can be used for clean delegation of object destruction, or for ensuring that destructors in the base classes of your choosing get called. Explicitly calling DESTROY is also possible, but is usually never needed.
デストラクタから抜ける前にリファレンスを再 bless するようにアレンジすると、 perl はカレントのデストラクタから呼び出した後で再 bless されたオブジェクトの ための DESTROY メソッドを再度呼び出します。 これはオブジェクトの委譲を始末するのに使ったり、あなたが呼び出すことを 選択した基底クラスのデストラクタを保証するのに使うことができます。 陽に DESTROY を呼び出すことも可能ですが、通常はそうする必要はありません。
DESTROY is subject to AUTOLOAD lookup, just like any other method. Hence, if your class has an AUTOLOAD method, but does not need any DESTROY actions, you probably want to provide a DESTROY method anyway, to prevent an expensive call to AUTOLOAD each time an object is freed. As this technique makes empty DESTROY methods common, the implementation is optimised so that a DESTROY method that is an empty or constant subroutine, and hence could have no side effects anyway, is not actually called.
DESTROY は、その他のメソッドと同様、AUTOLOAD 検索の影響を受けます。 従って、もしあなたのクラスに AUTOLOAD メソッドがあるけれども、 DESTROY アクションが不要なら、オブジェクトが解放される度に高価な AUTOLOAD を呼び出されるのを避けるために、とにかく DESTROY を 提供したいと思うでしょう。 このテクニックによって空の DESTROY メソッドが一般的になったので、 空や定数サブルーチンの DESTROY メソッドは最適化され、従ってどちらにしても 副作用がないので、実際には呼び出されません。
Do not confuse the previous discussion with how objects CONTAINED in the current one are destroyed. Such objects will be freed and destroyed automatically when the current object is freed, provided no other references to them exist elsewhere.
カレントで破棄されるオブジェクトに属するオブジェクトに関して 混乱しないようにしてください。 そのようなオブジェクトはカレントオブジェクトが解放されるときに自動的に 解放・破棄が行われ、他のなにものに対するリファレンスがないようにします。
まとめ¶
That's about all there is to it. Now you need just to go off and buy a book about object-oriented design methodology, and bang your forehead with it for the next six months or so.
これで、ここでなすべきことは全て終わりました。 今、あなたは部屋を出てオブジェクト指向方法論に関する書籍を購入して、 そして六ヶ月かそこらの間悩む必要があるでしょう。
2 フェーズガベージコレクション¶
For most purposes, Perl uses a fast and simple, reference-based garbage collection system. That means there's an extra dereference going on at some level, so if you haven't built your Perl executable using your C compiler's -O
flag, performance will suffer. If you have built Perl with cc -O
, then this probably won't matter.
ほとんどの目的のために、Perl は単純かつ高速なリファレンスベースの ガベージコレクションシステムを使用します。 このため、幾つかの段階において余計なデリファレンスが起こり、使用している Perl を ビルドするときに -O
フラグをコンパイラに使っていなければ、性能が劣化します。 Perl をビルドするときに cc -O
を使っていれば、このデリファレンスは問題とは ならないでしょう。
A more serious concern is that unreachable memory with a non-zero reference count will not normally get freed. Therefore, this is a bad idea:
より深刻な問題は、ゼロでないリファレンスカウントを持っている アクセスできないメモリー(unreachable memory)が通常は 解放されないということです。 したがって、以下のようにすることは悪いアイデアです。
{
my $a;
$a = \$a;
}
Even thought $a should go away, it can't. When building recursive data structures, you'll have to break the self-reference yourself explicitly if you don't care to leak. For example, here's a self-referential node such as one might use in a sophisticated tree structure:
$a が無くなるように思えるのですが、できないのです。 再帰的データ構造を構築したとき、メモリリークを気にしないためには自分自身で、 明示的に、自己参照を壊さなければなりません。 たとえば、木構造を扱うときに使うような自己参照構造体として以下のようなものを 考えてみます。
sub new_node {
my $class = shift;
my $node = {};
$node->{LEFT} = $node->{RIGHT} = $node;
$node->{DATA} = [ @_ ];
return bless $node => $class;
}
If you create nodes like that, they (currently) won't go away unless you break their self reference yourself. (In other words, this is not to be construed as a feature, and you shouldn't depend on it.)
このようなノードを生成するとき、あなた自身が自分で自己参照を壊さない 限りノードはなくなりません(言い換えれば、これは仕様として 解釈されるものではなく、これに依存すべきではないということです)。
Almost.
もう一息。
When an interpreter thread finally shuts down (usually when your program exits), then a rather costly but complete mark-and-sweep style of garbage collection is performed, and everything allocated by that thread gets destroyed. This is essential to support Perl as an embedded or a multithreadable language. For example, this program demonstrates Perl's two-phased garbage collection:
インタプリタのスレッドが最終的にシャットダウンするとき(通常は プログラムを終了するとき)、コストが掛かりますが、完全な mark-and-sweep 形式のガベージコレクションが実行されます。 そして、(シャットダウンされる)スレッドによって割り当てられたすべての ものは破棄されます。 これはPerlを組み込みに使えるようにしたり、マルチスレッドに対応できる言語と するために重要なことです。 たとえば以下のプログラムは Perl の 2 フェーズガベージコレクションを デモンストレーションします。
#!/usr/bin/perl
package Subtle;
sub new {
my $test;
$test = \$test;
warn "CREATING " . \$test;
return bless \$test;
}
sub DESTROY {
my $self = shift;
warn "DESTROYING $self";
}
package main;
warn "starting program";
{
my $a = Subtle->new;
my $b = Subtle->new;
$$a = 0; # break selfref
warn "leaving block";
}
warn "just exited block";
warn "time to die...";
exit;
When run as /foo/test, the following output is produced:
/foo/test として実行したとき、以下のような出力をします。
starting program at /foo/test line 18.
CREATING SCALAR(0x8e5b8) at /foo/test line 7.
CREATING SCALAR(0x8e57c) at /foo/test line 7.
leaving block at /foo/test line 23.
DESTROYING Subtle=SCALAR(0x8e5b8) at /foo/test line 13.
just exited block at /foo/test line 26.
time to die... at /foo/test line 27.
DESTROYING Subtle=SCALAR(0x8e57c) during global destruction.
Notice that "global destruction" bit there? That's the thread garbage collector reaching the unreachable.
"global destruction" がどこにあるかわかりますか? これは、スレッド ガベージコレクタがアクセスできないオブジェクトに到達したということです。
Objects are always destructed, even when regular refs aren't. Objects are destructed in a separate pass before ordinary refs just to prevent object destructors from using refs that have been themselves destructed. Plain refs are only garbage-collected if the destruct level is greater than 0. You can test the higher levels of global destruction by setting the PERL_DESTRUCT_LEVEL environment variable, presuming -DDEBUGGING
was enabled during perl build time. See "PERL_DESTRUCT_LEVEL" in perlhacktips for more information.
オブジェクトは常に破棄されます。 一般のリファレンス(regulaer refs)が破棄されなかった場合でもそうですし、 一般のリファレンスが分割されたパスで破棄された場合でさえ、 通常のリファレンス(ordinary refs)がオブジェクトデストラクタが自分自身を 破棄してしまったリファレンスを使うのを防ごうとする前に破棄されます。 plain なリファレンスは、そのデストラクトレベルが 0 以上であるときには ガベージコレクションのみ行なわれます。 Perl をビルドするときに -DDEBUGGING
が有効になっていれば、 PERL_DESTRUCT_LEVEL という環境変数に対する設定をすることによって、 グローバルデストラクションのレベルを検査することができます。 さらなる情報については "PERL_DESTRUCT_LEVEL" in perlhacktips を 参照してください。
A more complete garbage collection strategy will be implemented at a future date.
より完璧なガベージコレクションの戦略は将来実装されるでしょう。
In the meantime, the best solution is to create a non-recursive container class that holds a pointer to the self-referential data structure. Define a DESTROY method for the containing object's class that manually breaks the circularities in the self-referential structure.
方法として最善なものは、自己再帰的なデータ構造に対するポインタを 保持するような非再帰的なコンテナクラスを作成することです。 そういったオブジェクトのクラスでの DESTORY メソッドの定義は 自己参照構造中の循環を手作業で断ち切るようなものになります。
SEE ALSO¶
A kinder, gentler tutorial on object-oriented programming in Perl can be found in perltoot, perlboot and perltooc. You should also check out perlbot for other object tricks, traps, and tips, as well as perlmodlib for some style guides on constructing both modules and classes.
Perl におけるオブジェクト指向プログラムに関するより親切で丁寧な チュートリアルは perltoot, perlboot, perltooc にあります。 また、その他のオブジェクトの罠や小技については perlbot を、 モジュールとクラスの作成に関するスタイルガイドについては perlmodlib を 参照してください。