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」の形で呼び出されるようになります。
参考
- http://blog.livedoor.jp/dankogai/archives/50812040.html
- goto &EXPRの動作を知るために参考にしました。
- http://digit.que.ne.jp/work/wiki.cgi?Perlメモ/caller
- caller関数について