関数処理をラップする
Hook::LexWrapモジュールを使うと、関数を書き換えずに関数の前後に処理を挿入したり、関数の返値を変更することができます。
# 前後に処理を挿入する use strict; use warnings; use Hook::LexWrap; wrap 'foo', pre => sub { print "前処理\n"; }, post => sub { print "後処理\n"; }; foo(); bar(); sub foo { print "foo()\n"; } sub bar { print "bar()\n"; } __END__ [実行結果] 前処理 foo() 後処理 bar()
# 処理の横取り use strict; use warnings; use Hook::LexWrap; wrap 'foo', pre => sub { my ($value) = @_; # $_[-1]に値を設定すると処理を横取りできます $_[-1] = "$valueは奇数" if $value % 2 != 0; }; foreach my $i (1..5) { print foo($i), "\n"; } sub foo { my $value = shift; return "$valueです"; } __END__ [実行結果] 1は奇数 2です 3は奇数 4です 5は奇数
# 返値の書き換え use strict; use warnings; use Hook::LexWrap; wrap 'foo', post => sub { # $_[-1]に値を設定すると戻り値を書き換えます # 呼び出しがリストコンテキストの場合 # $_[0]に戻り値のリストのリファレンスが入ります if (ref $_[0] eq 'ARRAY') { $_[-1] = $_[0]->[0] . "です"; } else { $_[-1] = $_[0] . "です"; } }; foreach my $i (1..5) { print foo($i), "\n"; } sub foo { my $value = shift; return $value; } __END__ [実行結果] 1です 2です 3です 4です 5です