Perlのreturn

2010年5月22日
| コメント(0) | トラックバック(0) Perlのreturn

ちょっと前に作ったプログラムを見ていて、悪い習慣だなぁ、と思ったので、改めるためにメモ。


Perlを覚えていく中で、関数の返り値を偽として判定させたいときは「undefを返す」という事をやっていた。

return undef;

しかし、これは返り値を配列で受け取るときに微妙になり、わかりにくいバグを発生させてしまう原因にもなる。
どういう場合に問題になるかを、実際にコードを書いて試してみる。

# utf8
use 5.8.1;
use strict;
use warnings;
use utf8;
use Perl6::Say;
use Data::Dumper qw/Dumper/;
 
my $charset = 'cp932';
binmode STDOUT => ":encoding($charset)";
 
sub return_less {
    my $a = 1;
}
 
sub return_undef {
    my $a = 1;
    return undef;
}
 
sub return_only {
    my $a = 1;
    return;
}
 
# return_less
if (my @result = &return_less) {
    say 'return_less  : true';
    print Dumper \@result;
}
else {
    say 'return_less  : false';
    print Dumper \@result;
}
 
# return_undef
if (my @result = &return_undef) {
    say 'return_undef : true';
    print Dumper \@result;
}
else {
    say 'return_undef : false';
    print Dumper \@result;
}
 
# return_only
if (my @result = &return_only) {
    say 'return_only  : true';
    print Dumper \@result;
}
else {
    say 'return_only  : false';
    print Dumper \@result;
}

このスクリプトを実行すると結果はそれぞれどうなるでしょうか?
しばらく考えてみて下さい。

答えは以下のようになります。

return_less  : true
$VAR1 = [
          1
        ];
return_undef : true
$VAR1 = [
          undef
        ];
return_only  : false
$VAR1 = [];

いかがでしょうか?
undefを返したのに、分岐で「真」になっていますね。

これは、if文が@resultを要素数で判定したためです。
undefを返すと、見ての通り@resultに「undef」が代入されます。
そのため、@resultの判定が1となり、真となります。

期待したのは「return_only」のような動作ではないでしょうか?

return undef;は悪癖です。
理解してやる場合は別ですが、殆どの場合は単独のreturnが良いでしょう。

トラックバック(0)

このブログ記事に対するトラックバックURL:

コメントする

Google検索

Last.fm

このブログ記事について

このページは、のぶりんが2010年5月22日 07:52に書いたブログ記事です。

ひとつ前のブログ記事は「cpan-outdatedも使ってみた(完結編)」です。

次のブログ記事は「cpanminusでminicpanと仲良くする方法(Windows編)」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Creative Commons License
このブログのライセンスは クリエイティブ・コモンズライセンス.
Powered by Movable Type