=head1 名前 UNIVERSAL - 全てのクラス(ブレスされたリファレンス)の基底クラス =head1 概要 $is_io = $fd->isa("IO::Handle"); $is_io = Class->isa("IO::Handle"); $does_log = $obj->DOES("Logger"); $does_log = Class->DOES("Logger"); $sub = $obj->can("print"); $sub = Class->can("print"); $sub = eval { $ref->can("fandango") }; $ver = $obj->VERSION; # but never do this! $is_io = UNIVERSAL::isa($fd, "IO::Handle"); $sub = UNIVERSAL::can($obj, "print"); =head1 説明 C は全てのブレスされたリファレンスが継承する基底クラスです, L も参照してください. C は以下のメソッドを提供しています: =over 4 =item C<< $obj->isa( TYPE ) >> =item C<< CLASS->isa( TYPE ) >> =item C<< eval { VAL->isa( TYPE ) } >> ここで =over 4 =item C はパッケージ名 =item C<$obj> はブレスされたリファレンスかパッケージ名を含んだ文字列 =item C はパッケージ名 =item C 上のいずれかかブレスされていないリファレンス =back インスタンス若しくはクラスメソッド (C<< $obj->isa( TYPE ) >>)として 使うときは $obj がパッケージ C 若しくはパッケージ C の派生にブレスされているときに I<真> を返します. クラスメソッド (C<< CLASS->isa( TYPE ) >>: スタティックメソッドとして 参照されることもあります)として使う時は C がパッケージ名 C 若しくはパッケージ C の派生から派生している(若しくは そのもの)の時に I<真> を返します. もし調べたい対象が何であるのかはっきりしていないとき(Cのケース)では, C が未定義のときの例外を捕捉するために, メソッド呼び出しを C で包む必要があります. C をクラスではなくメソッド呼び出しであることを保証したいのであれば 最初に L の C で呼び出しを確認します: use Scalar::Util 'blessed'; if ( blessed( $obj ) && $obj->isa("Some::Class") { ... } =item C<< $obj->DOES( ROLE ) >> =item C<< CLASS->DOES( ROLE ) >> C はオブジェクト若しくはクラスが役割 C として機能するかどうかを 調べます. 役割(role)とは特定の振る舞いに名前を付けたグループです( しばしば特定の名前やシグニチャを持ったメソッドです), クラスと似て いますが, それ自体が完全なクラスである必要はありません. 例えば, logging や serialization は役割になるでしょう. C と C はどちらも, 真であればメソッドを呼び出したオブジェクト 若しくはクラスが特定の振る舞いを行えるかどうかを知ることが 出来るという点で似ています. しかしながら, C は 呼び出し先が操作を どのように処理するかには気にしないで, 単にそれを行うということを調べるに すぎないという点で C とは異なります. (C はもちろん 関連の継承を委任しています. 他の関連には集約(aggregation), 委譲(delegation), mock が含まれます.) デフォルトでは, Perl のクラスは C ロールとして機能するだけです. 自分のクラスで他のロールの機能をマークするには, C を適切に オーバーライドします. ロールとクラスの間には, 各クラスは暗にその同じ名前のロールが存在するという 関連があります. 継承トロールには, 基底クラスから派生したサブクラスは 暗黙にその親の機能する任意のロールは機能するという点も関連があります. それ故に C が真を返す全ての場所で C は真を返すので(オーバー ライドされた C I<及び> C メソッドは適切に振る舞うため), 安全に C の代わりに C を使うことが出来ます, =item C<< $obj->can( METHOD ) >> =item C<< CLASS->can( METHOD ) >> =item C<< eval { VAL->can( METHOD ) } >> C はオブジェクト若しくはクラスが C というメソッドを 持っているかを調べます. もし持っていれば関数リファレンスが返されます. もし持っていなければ I が返されます. これには C<$obj>, C, 若しくは C で継承されている若しくはインポートされている メソッドが含まれます. C はオブジェクトが(オブジェクトのクラスが C を適切にオーバー ライドしていないのであれば) AUTOLOAD を通してメソッドを提供可能かどうかは 知ることができません, そのため I が返ってきてもオブジェクトが そのメソッド呼び出しを処理することができないとは限りません. これを 回避するにはモジュールの作者が AUTOLOAD を使って処理するメソッドに対して 前方宣言を使うことです(L参照). そのような'ダミー'の関数は C はコードリファレンスを返しますが, それが呼び出された時には AUTOLOAD へとフォールスルーされます. もし適切な AUTOLOAD が提供されて いなければ, コードリファレンスの呼び出しはエラーになるでしょう. C はクラス(スタティック)メソッド, オブジェクトメソッドとして 呼び出すことができます. 繰り返しますが, 有効な呼び出しのためには同じルールがつかわれます -- C ブロックかよりこだわるのであれば C を使う必要が あります. =item C C はオブジェクトがブレスされているパッケージの変数 C<$VERSION> の値を返します. もし C が与えられていた 場合には比較をおコアってパッケージのバージョンが C 以上でなかった場合には die します. C はクラス(スタティック)メソッド若しくはオブジェクトメソッド として呼び出すことができます. =back =head1 エクスポート デフォルトでは何もエクスポートされません. 3つの関数(C, C, そして C)をインポートしたいかも しれませんが, それを行うことはたいてい有害なことです. 新しいコードでは それは行わないでください. 例えば, このドキュメントの以前のバージョンではリファレンスの 種類を調べるのに C を関数として使うことを提案していました: use UNIVERSAL 'isa'; $yes = isa $h, "HASH"; $yes = isa "Foo", "Bar"; この時, このコードは他のクラスでオーバーライドされた C メソッドを呼び出すI<ことがない>という問題があります. 1つめのケースについては代わりに L の C を 使うようにしてください. use Scalar::Util 'reftype'; $yes = reftype( $h ) eq "HASH"; そして2番目のケースについてはメソッド形式の C を使うように してください. $yes = Foo->isa("Bar"); =head1 和訳 山科 氷魚 (YAMASHINA Hio) 原典: perl VERSION 5.9.4. 翻訳日: 2007-03-19.