うん知ってるけど、でも別にそういうことしたかったわけじゃないんだ・・・orz。ただSvTRUEの仕様通りにPerlで書きたかっただけなんだ・・・。どうせならこっちをどううまく書くのか教えてください!


#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。