コードリファレンスはクラスかオブジェクト越しに呼ぶと勝手にデリファレンスしてくれるの?優しいね。

心温まる優しさに触れた今日と言う日にありがとう。マツモです。

物語の始まり

何気なく
http://search.cpan.org/src/TOKUHIROM/Class-DBI-Plugin-RetrieveFromSQL-0.02/lib/Class/DBI/Plugin/RetrieveFromSQL.pm
を見てて違和感のあるコードに遭遇。

my $super = $pkg->can('retrieve_from_sql');
・・・
return $self->$super($sql, @args);

この書き方恥ずかしながら初見でした。

今までどう書いてたかというと

my $super = $pkg->can('retrieve_from_sql');
・・・
return $super->($self, $sql, @args);

こういう感じに書いてました。第一引数にオブジェクト渡して辻褄合わせるという感じ。

で、どういう事なのかを見てみました。

自分でもやってみよう

まず

package Foo;

use base qw(Class::Accessor);

sub foo {
    my $class = shift;
    print shift;
}

を作りまして、以下のコードを試してみました。

my $ref_code = Foo->can('foo');

my $class = 'Foo';

$ref_code->($class, "foo"); # 其の一
$class->$ref_code("foo");   # 其の二
$class->$ref_code->("foo"); # 其の三

結果

其の一・其の二は無事'foo'と出力されたんですが、其の三で

Can't use string ("1") as a subroutine ref while "strict refs"

と怒られました。(1はprtintの戻り値でしょうね。)

なので、オブジェクト・クラス越しにcode refを呼んだ場合は良い感じにしてくれるのであろうという結論。


オブジェクトで試したのは↓。勿論結果は同じでした。

my $ref_code = Foo->can('foo');

my $obj = Foo->new();

$ref_code->($obj, "foo");
$obj->$ref_code("foo");
$obj->$ref_code->("foo");


知らない事っていっぱいありますねぇ。