後からメソッドを追加する

Perlのオブジェクトはリファレンスにクラス名をblessしたもので、
クラスはpackage名で区切られた名前空間なわけですが、
それを利用してこんな書き方が出来たり。

use strict;
use warnings;

my $foo = Foo->new('hoge');
$foo->echo();

sub Foo::echo {
    my $self = shift;
    print $self->{arg};
}

package Foo;
sub new {
    my ($class, $arg) = @_;
    my $self = {
        arg => $arg || 'huga',
    };
    bless $self, $class;
}

結果は

hoge

となります。


Fooクラスにはもともとechoなんていうメソッドは無いわけなんですが、
きちんと「hoge」と出力してくれます。


Perlはオブジェクトのメソッド呼び出しの際に
blessされているクラス名、つまりその名前空間内のサブルーチンを探し出します。

sub Foo::echo

という記述はFooという名前空間内にechoというサブルーチンを定義しますよ、
という意味なので、

$foo->echo()

と書いてもメソッドを呼び出せるというわけです。


ちなみに今日のエントリは
HTML::TreeBuilder + CSSセレクタがいい感じな件
のサンプルコードを見てて気づきました。


こんな書き方できるなんて知らなかったなあ。
まだまだ奥が深いです。