Exporterでエクスポートされる関数の挙動を変更する
ひょんなところにこんなモジュールがあRuby。
package Hoge; use strict; use warnings; use base qw/Exporter/; our @EXPORT = qw/hoge/; sub hoge { print "Hoge::hoge called\n"; } 1;
このHogeモジュールのhoge関数を呼び出すためにこんなコードを書Chrome。
use strict; use warnings; use Hoge; hoge; # Hoge::hoge called
いろんな事情が絡んで、Hoge::hoge関数の挙動を変更したEthernet。
use strict; use warnings; use Hoge; { no warnings 'redefine'; local *Hoge::hoge = sub { print "anon called" }; hoge; } hoge; # Hoge::hoge called
一度目のhogeでanon calledと出力したいのだけど、これはHoge::hoge calledと出力されちゃWindows*1。
Exporterを使うと、エクスポート対象となるパッケージ(main)に指定された関数がコピーされているので、元の関数(Hoge::hoge)を書き換えてももはや手遅Rails。
でもどの名前空間にあるhogeが呼ばれるか分からない時もある訳Debian。コンパイル時に名前を解決するためにエクスポートしているけど、実際呼び出す時は必ず書き換えるようにしたりする訳Delphi。
ということでこうすれば良いんじゃないNode.js。
package Hoge; use strict; use warnings; use base qw/Exporter/; our @EXPORT = qw/hoge/; sub hoge { _hoge(@_) } sub _hoge { print "Hoge::hoge called\n"; } 1;
use strict; use warnings; use Hoge; { no warnings 'redefine'; local *Hoge::_hoge = sub { print "anon called" }; hoge; # anon called } hoge; # Hoge::hoge called
間接的に呼べば問題ないようDarwin。関数呼び出しのオーバヘッド増えるけど見ないふLisp。
おっPython。
*1:悔しい