bless

オブジェクトを生成する

構文

解説

bless はオブジェクト指向プログラミングにおけるクラスを生成する際に使われます。 もう少し正確に言うと、Perl における単なるパッケージをクラスかのように見せ、その中で定義した ハッシュ参照をそのクラスのインスタンスのようにしてくれます。 具体的なクラスの作り方と使い方は後述しますが、まずは bless の仕様を見てみましょう。

bless は、REF の参照先をパッケージ内のオブジェクトとしてマークするよう Perl に指示します。 特別な理由ない限り、2 つの引数を取る bless のほうが推奨されます。

参照先を特定のパッケージに bless する(推奨)
bless $ref, $package;

2 つの引数を取る場合、オブジェクトを第二引数に指定したパッケージに加えます。

参照先を main パッケージに bless する
bless $ref, "";

第二引数が空文字列なら、bless は オブジェクトを main パッケージに追加します。

参照先を現在のパッケージに bless する(継承不可)
bless $ref;

bless が第二引数なしに使われた場合、そのオブジェクトは現在のパッケージの中で生成されます。 派生クラスが bless を実行してメソッドを継承する可能性があるなら、必ず第二引数を指定するべきです。 1 つの引数しか取らない bless は、潜在的なバグの原因になる可能性があるため、非推奨となっています。

CLASSNAME は常に大文字と小文字を組み合わせた名前にするべきです。 それは、すべて大文字、または、すべて小文字の名前は、Perl においては、それぞれ組み込みの型やプラグマとして使われることを意味するからです。 混乱を避けるためにも、すべて大文字、または、すべて小文字のパッケージ名の生成は避けてください。

また、0 をクラス名にしないでください。 これは、参照が bless に失敗したのかを見るために ref の結果をチェックした際に問題となります。なぜなら "0" が返ってしまうからです。

以上、bless の仕様を説明しましたが、これではオブジェクト指向プログラミングのイメージがわきません。 bless を使って簡単なクラスを作ってみましょう。 Perl におけるクラスは単なるパッケージのことです。 ここでは MyClass という名前のパッケージを MyClass.pm というファイル名で保存します。

package MyClass;

sub new {
    my ( $class, %args ) = @_;
    my $self = { name => $args{name} };
    return bless $self, $class;
}

sub greet {
    my($self) = @_;
    print "Hi, my name is " . $self->{name} . "\n";
}

1;

ここではパッケージ名を MyClass としていますが、これがクラス名になります。 サブルーチン new がいわゆるコンストラクタのような存在になります。 Perl の仕組み上、コンストラクタとなるサブルーチンの名前は new でなくても構いませんが、 分かりやすさを考えると new としておくのが良いでしょう。

サブルーチン new には 2 つの引数が引き渡されます。 一つ目はクラス名です。この場合は MyClass がセットされます。 二つ目は new が呼び出された際に引き渡されたパラメータです。

サブルーチン new の中ではハッシュ参照 $self にパラメータの値をセットしています。 このハッシュ参照を bless することで、クラス名 MyClass のインスタンスが生成されます。 bless によって生成されたインスタンスは $self そのものですが、このインスタンスを通して、 $self にセットされたフィールドやメソッドにアクセスできるようになります。

では、この MyClass を使うコードを見てみましょう。

require './MyClass.pm';
my $myclass = MyClass->new( name => 'Taro' );
$myclass->greet(); # "Hi, my name is Taro"

このように、bless は、もともとオブジェクト指向プログラミング言語でない Perl に、 単なるパッケージをクラスとして扱えるようにすることで、Perl でもオブジェクト指向プログラミングができるようにします。

なお、Perl v5.38 から実験的に class 構文が導入されました。 将来的にはパッケージを bless するのではなく、 Perl コアに組み込まれた class 構文を使うことが主流になるのかもしれません。 Perl の class 構文の詳細については記事「Perl に class 構文がやってきた」 をご覧ください。