読者です 読者をやめる 読者になる 読者になる

tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

perlのundefの挙動1(関数でなにも返さないとhashが壊れたりとか

perlをやっていると0や''やundefなんかをbooleanのfalse的に使ってしまうわけですが
その中でもundefについてちょっと検証

っていうのも、関数でreturnするときに

  • return;
  • return undef;

と書くのが同じだと思っていました、っていう話しです。

検証:まずundef的なものを返す関数をいくつか定義

# return;のパターン(ifはあまり意味ない)
sub hoge
{
  return if(!&piyo);
}

# return undef;のパターン
sub piyo
{
  return undef;
}

# return;の関数をそのまま返却
sub func
{
  &hoge;
}

# return;の関数を一度スカラーで受け取ってから返却
sub func2
{
  my $hoge = &hoge;
  $hoge;
}

いくつかのパターンでwarnで出力して検証

こんな感じにwarn並べてみる
my $val1 = undef;
my $val2;
my $val3 = '';
my $val4 = &func;
my $val5 = &func2;

warn "#### warn ####\n";
warn "[val1]\n";
warn $val1;

warn "\n[val2]\n";
warn $val2;

warn "\n[val3]\n";
warn $val3;

warn "\n[val4]\n";
warn $val4;

warn "\n[func]\n";
warn &func;

warn "\n[val5]\n";
warn $val5;

warn "\n[func2]\n";
warn &func2;

warn "\n[piyo]\n";
warn &piyo;
出力結果
#### warn ####
[val1]
Use of uninitialized value in warn at undef_test.pl line 130,  line 1.
Warning: something's wrong at undef_test.pl line 130,  line 1.

[val2]
Use of uninitialized value in warn at undef_test.pl line 133,  line 1.
Warning: something's wrong at undef_test.pl line 133,  line 1.

[val3]
Warning: something's wrong at undef_test.pl line 136,  line 1.

[val4]
Use of uninitialized value in warn at undef_test.pl line 139,  line 1.
Warning: something's wrong at undef_test.pl line 139,  line 1.

[func]
Warning: something's wrong at undef_test.pl line 142,  line 1.

[val5]
Use of uninitialized value in warn at undef_test.pl line 145,  line 1.
Warning: something's wrong at undef_test.pl line 145,  line 1.

[func2]
Use of uninitialized value in warn at undef_test.pl line 148,  line 1.
Warning: something's wrong at undef_test.pl line 148,  line 1.

[piyo]
Use of uninitialized value in warn at undef_test.pl line 151,  line 1.
Warning: something's wrong at undef_test.pl line 151,  line 1.

今回、Use of uninitialized valueなことは想定どおりなわけで
どちらかというと[func]がUse of uninitializedではないことが想定外です。
return undef;とは違うということがわかりました
[piyo]や、一度スカラーで受け取ってから返却している[func2]とは挙動が違うんですね。

次に、いくつかのパターンでwarn Dumperで出力して検証

こんな感じにwarn Dumperして並べてみる
my $val1 = undef;
my $val2;
my $val3 = '';
my $val4 = &func;
my $val5 = &func2;

warn "\n";
warn "#### warn ####\n";
warn "\n[val1]\n";
warn Dumper $val1;

warn "\n[val2]\n";
warn Dumper $val2;

warn "\n[val3]\n";
warn Dumper $val3;

warn "\n[val4]\n";
warn Dumper $val4;

warn "\n[func]\n";
warn Dumper &func;

warn "\n[val5]\n";
warn Dumper $val5;

warn "\n[func]\n";
warn Dumper &func2;

warn "\n[func]\n";
warn Dumper &piyo;
出力結果
#### warn Dumper ####

[val1]
undef

[val2]
undef

[val3]
''

[val4]
undef

[func]
Warning: something's wrong at undef_test.pl line 179,  line 1.

[val5]
undef

[func]
undef

[func]
undef

Dumperしただけなので、やっぱりfuncだけ挙動が違います。
undefとも出ないので、そもそもundefですらないってことのようです。

長くなったので、次はこれを使ってhashが壊れるっていう検証を試そうと思います。
perlのundefの挙動2(return;でhashが壊れる