Perlのreturn

ちょっと前に作ったプログラムを見ていて、悪い習慣だなぁ、と思ったので、改めるためにメモ。 Perlを覚えていく中で、関数の返り値を偽として判定させたいときは「undefを返す」という事をやっていた。

1
return undef;

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 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;
}

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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が良いでしょう。

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy