Perl の関数をオーバーライドする
Perl で関数を上書くいくつかの方法
一時的なオーバーライド
(Foo.pm)
package Foo;
use strict;
use warnings;
sub bar {
my $baz = shift;
$baz * 2;
}
1;
(hoge.pl)
#!/usr/bin/perl
use strict;
use warnings;
use Perl6::Say;
use Foo;
say Foo::bar(3); # 6
{
no warnings 'redefine';
local *Foo::bar = sub {
my $baz = shift;
$baz ** 2;
};
say Foo::bar(3); # 9
}
say Foo::bar(3); # 6
関数を、local で一時的に上書きする。
no warnings 'redefine';
は関数の再定義を許してね、という宣言。
no warnings 'redefine';
local *Foo::bar = sub {
my $baz = shift;
$baz ** 2;
};
グローバルにオーバーライドする
(hoge.pl)
#!/usr/bin/perl
use strict;
use warnings;
use Perl6::Say;
use Foo;
say Foo::bar(3); # 6
{
no warnings 'redefine';
*Foo::bar = sub {
my $baz = shift;
$baz ** 2;
};
say Foo::bar(3); # 9
}
say Foo::bar(3); # 9
local をつけなければ、グローバルに上書きされる。
プロトタイプ
オーバーライドする関数に、プロトタイプが宣言されている場合は、上書く関数にもプロトタイプをつけないと、「Prototype mismatch: sub Foo::bar ($) vs none」などと警告が出る。
(Foo.pm)
package Foo;
use strict;
use warnings;
sub bar ($) {
my $baz = shift;
$baz * 2;
}
1;
(hoge.pl)
#!/usr/bin/perl
use strict;
use warnings;
use Perl6::Say;
use Foo;
say Foo::bar(3); # 6
{
no warnings 'redefine';
*Foo::bar = sub ($) {
my $baz = shift;
$baz ** 2;
};
say Foo::bar(3); # 9
}
say Foo::bar(3); # 9
一時的な書き換えなら、警告はでない。
組み込み関数のオーバーライド
組み込み関数を上書く場合は、BEGIN ブロックで、以下のようにする。
#!/usr/bin/perl
use strict;
use warnings;
use Perl6::Say;
BEGIN{
*CORE::GLOBAL::length = sub{
'constant';
};
}
say length('foo');
say CORE::length('foo'); # 書き換えられる前の関数
結果はこのようになります。
constant
3