一時的なメソッドの上書き
[Perl] メソッドの上書き>Testに使えそう たまには呪文をとなえてみるか:仕事版/ウェブリブログ
後で元に戻す(一時的に上書きする)のであればlocalを使うと簡単にできます。
普通に書くと、元のメソッドを保存・復元する処理を書く必要があります。
package Object; sub new { bless {}, shift } sub method { print "This is Object\n" } package main; my $object = Object->new; $object->method(); my $orig = Object->can('method'); # 保存。と言ってもコードそのものがコピーされるわけじゃなくて参照カウントが増えるだけ ← 間違ってたら教えて(><) *Object::method = sub { print "foo bar baz\n" }; # 上書き $object->method(); *Object::method = $orig; # 復元 $object->method();
# 実行結果
% perl overwrite.pl
This is Object
foo bar baz
This is Object
ところで、名前の付いたサブルーチンはシンボルテーブルに入ってるのでlocal化することができます。(逆に言うとシンボルテーブルに入らないmy変数などはlocal化できません)
local化されたシンボルはスコープの終わりで自動的に元の値に戻ります。(スタック)
package Object; sub new { bless {}, shift } sub method { print "This is Object\n" } package main; my $object = Object->new; $object->method(); { local *Object::method = sub { print "foo bar baz\n" }; # 上書き $object->method(); } # メソッドは復元されている $object->method();
実行結果は同じです。
おまけ
localで@ARGVをいじることもできます。wrapperみたいに使える。
Perlの実行ファイルfoo.plがあったとして、以下のようなfoo-verbose.plを作った場合
{ local @ARGV = (@ARGV, '--verbose'); do 'foo.pl'; }
foo-verbose.plを実行すると必ずfoo.plに--verboseオプションが渡ることになります。