うん知ってるけど、でも別にそういうことしたかったわけじゃないんだ・・・orz。ただSvTRUEの仕様通りにPerlで書きたかっただけなんだ・・・。どうせならこっちをどううまく書くのか教えてください!
#codereposでPerlキチンと正と負を切り分ける、って話が気になった。SvTRUEってマクロあるのは知ってる訳だが、具体的にどういう実装なのかわからん。というか、SvTRUEをPurePerlでかけばいいんじゃね?ってことでsv.hの中のマクロ、SvTRUEをPurePerlにしてみた
テストしたのは以下の値:
で、実行結果
#codereposでPerlキチンと正と負を切り分ける、って話が気になった。SvTRUEってマクロあるのは知ってる訳だが、具体的にどういう実装なのかわからん。というか、SvTRUEをPurePerlでかけばいいんじゃね?ってことでsv.hの中のマクロ、SvTRUEをPurePerlにしてみた
sub SvTRUE
{
my $x = shift;
if (! defined $x) {
return ();
}
if (!ref $x && $x =~ /\D/) {
return length($x) > 1 || substr($x, 0, 1) ne '0';
} else {
return $x;
}
}
CのソースコードからぱくってきたからPerl的でないかもしれんけどね。簡単なテストしかしてませんが。テストしたのは以下の値:
0
1
"0E0"
"0"
''
{}
undef
Hoge->new(0)
Hoge->new(1)
最後のHogeは、与えられた値が正だったら負、負だったら正を返す適当なオブジェクトpackage Hoge;
use overload
bool => \&hoge_bool,
'""' => \&hoge_string,
fallback => 1
;
sub new { bless { val => $_[1] }, $_[0] }
sub hoge_bool { ! shift->{val} } # opposite
sub hoge_string { "Hoge(val=$_[0]->{val})" }
で、実行結果
my @list = ( 0, 1, "0E0", "0", '', {}, undef, Hoge->new(0), Hoge->new(1) );
foreach my $v (@list) {
print defined $v ? $v : 'undef', " is ", SvTRUE($v) ? "true" : "false", "\n";
}
0 is false
1 is true
0E0 is true
0 is false
is false
HASH(0x800168) is true
undef is false
Hoge(val=0) is true
Hoge(val=1) is false
わかってると思うけど、これ圧倒的に遅いっすよ。proof of concept。
コメント