メメメモモ

プログラミング、筋トレ、ゲーム、etc

Acme::Dot

http://search.cpan.org/~ovid/Acme-Dot-1.10/lib/Acme/Dot.pm

メソッド呼び出しをドットでできるようになります。

package Foo;
use Acme::Dot;
sub new { bless {}, shift }
sub hello { print "Hi there! (@_)\n" }

package main;
my $x = Foo->new;
$x.hello(1,2,3);


一見、perlの文法を変えてしまっていることに驚きでした。
ということで、このモジュールがどんなことをやっているのかを調べてみました。


結果的には、ドット演算子のオーバロードを使用している事が分かりました。
Acme::Dotのパッケージを呼び出したモジュールに対して、オーバロードの設定を追加しています。

package Acme::Dot;
use strict;
use warnings;

sub import {
    my $call_pack = ( caller(0) )[0]; 
    my $code = "package $call_pack;\n" . <<'END_OF_CODE';
    use overload "." => sub {
        my ( $obj, $stuff ) = @_;
        @_ = ( $obj, @{ $stuff->{data} } );
        goto &{ $obj->can( $stuff->{name} ) };
    },
    fallback => 1;
END_OF_CODE

     eval $code;
}


FooからAcme::Dotを呼び出すと、下記のコードがevalされて演算子のオーバロードが行なわれます。

package Foo;
use overload "." => sub {
    my ( $obj, @{ $stuff->{data} });
    @_ = ( $obj, @{ $stuff->{data} } );
    goto &{ $obj->can( $stuff->{name} ) };
},
fallback => 1;


Foo.hello()が呼び出されたら、この設定で「goto &hello」の形で呼び出されるようになります。


参考