Help us understand the problem. What is going on with this article?

Perlのreturnとreturn undefとOdd number of elements in hash assignmentの話

More than 1 year has passed since last update.

概要

たまたまハマったのでPerlとreturn;return undef;の違いと、
それによって発生するエラーOdd number of elements in hash assignmentの話。

はじめに

はじめに、このコードと結果を見てください。

test1.pl
use warnings;
use utf8;
use DDP;

sub test1 { return; }
sub test2 { return undef; }

my %a1 = ( now => test1() );
p %a1;

my %a2 = ( now => test2() );
p %a2;
Odd number of elements in hash assignment at test1.pl line 8.
{
    now   undef
}
{
    now   undef
}

これをみてわかるように、return;をしている時は、
Odd number of elements in hash assignmentのエラーが出ています。

return;return undef;

こちらを参考にそれぞれの違いを確認しました。
参考: http://www.perlplus.jp/perl/sub/index7.html

return;の動作

「return」文が実行されると呼び出し元に処理が戻ります。
「return」文でサブルーチンが終了した場合には、戻り値として空の値が設定されます。
空の値とは呼び出し元が値を求めている場合は未定義値「undef」となり、リストを求めている場合は空のリストとなります。

つまり、呼び出し元によって以下のような動作になります。

test2.pl
use warnings;
use utf8;
use DDP;

sub test1 { return; }

my $a = test1(); # undef
my @b = test1(); # 空のリスト
my %c = test1(); # 空のリスト

p a;
p b;
p c;
undef
[]
{}

return undef;

また「return」文が実行される時に戻り値を指定することも可能です。この場合の書式は次のようになります。
この場合、呼び出し元に処理が戻ると共に戻り値が指定した値に設定されます。

つまり、呼び出し元によって以下のような動作になります。

test3.pl
use warnings;
use utf8;
use DDP;

sub test2 { return undef; }

my $a = test2(); # undef
my @b = test2(); # undef
my %c = test2(); # undef

p a;
p b;
p c;
undef

[
    [0] undef
]

Odd number of elements in hash assignment at test3.pl line 9.
Use of uninitialized value in list assignment at test3.pl line 9.
{
    ''   undef
}

結論

以上のreturn;return undef;の違いから、最初のコードは次のような動作になることがわかりました。

test.pl
use warnings;
use utf8;
use DDP;

sub test1 { return; }
sub test2 { return undef; }

# 空のリストが返るので、 
# %a2 = ('now', ())
# になり、 Odd number of elements in hash assignment のエラーが出る。
my %a1 = ( now => test1() );
p %a1;

# undefが返るので、 
# %a2 = ('now', undef)
# になり、正常に動作する。
my %a2 = ( now => test2() );
p %a2;
narita_cpp
Perlでサーバー書きながら、angular js, vue js, Unityでフロント側も一緒に作るマンです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away