ルモーリン
ホーム 更新 Perl ランドナー サービス 雑談 コースガイド 鉄ゲタ 自転車 Linux リンク 連絡先

サブルーチンは何を返すか?

2019-02-28

きっかけ

このツイートがきっかけです。 え、ホント!?

コード

という訳で書いてみました。
#!/usr/bin/env perl -w

use utf8;
use strict;
use warnings;

use Encode::Locale;
use Encode::Argv;

use feature "say";

binmode STDIN, ":encoding(console_in)";
binmode STDOUT, ":encoding(console_out)";

$| = 1;

say "リストを返す関数の場合";
say  "配列に代入";
my @a = return_list();
say "配列:@a";

say  "変数に代入";
my $s = return_list();
say "変数:$s";

say "戻り値のリファレンスを変数に代入";
my $r = \return_list();
say "リファレンス:$r";
say "リファレンスが指す物は?${$r}";

say "戻り値のリファレンスを配列に代入";
my @ar = \return_list();
say "リファレンス:@ar";
say "リファレンスが指す物は?";
say "「${$_}」" for @ar;

say "配列を返す関数の場合";
say  "配列に代入";
my @a2 = return_array();
say "配列:@a2";

say  "変数に代入";
my $s2 = return_array();
say "変数:$s2";

say "戻り値のリファレンスを変数に代入";
my $r2 = \return_array();
say "リファレンス:$r2";
say "リファレンスが指す物は?${$r2}";

say "戻り値のリファレンスを配列に代入";
my @ar2 = \return_array();
say "リファレンス:@ar2";
say "リファレンスが指す物は?";
say "「${$_}」" for @ar2;

exit;

sub return_list {
	if (wantarray) {
		say "リストコンテキスト";
	} else {
		say "スカラコンテキスト";
	}

	return ("たこルカ", "は", "俺の嫁");
}

sub return_array {
	if (wantarray) {
		say "リストコンテキスト";
	} else {
		say "スカラコンテキスト";
	}

	my @result = ("たこルカ", "は", "俺の嫁");
	return @result;
}

実行結果

うお、ホントだった!
リストを返す関数の場合
配列に代入
リストコンテキスト
配列:たこルカ は 俺の嫁
変数に代入
スカラコンテキスト
変数:俺の嫁
戻り値のリファレンスを変数に代入
リストコンテキスト
リファレンス:SCALAR(0x37d530)
リファレンスが指す物は?俺の嫁
戻り値のリファレンスを配列に代入
リストコンテキスト
リファレンス:SCALAR(0x37d410) SCALAR(0x37d4b8) SCALAR(0x2fc508)
リファレンスが指す物は?
「たこルカ」
「は」
「俺の嫁」
配列を返す関数の場合
配列に代入
リストコンテキスト
配列:たこルカ は 俺の嫁
変数に代入
スカラコンテキスト
変数:3
戻り値のリファレンスを変数に代入
リストコンテキスト
リファレンス:SCALAR(0x386090)
リファレンスが指す物は?俺の嫁
戻り値のリファレンスを配列に代入
リストコンテキスト
リファレンス:SCALAR(0x3860d8) SCALAR(0x386630) SCALAR(0x385f70) 
リファレンスが指す物は?
「たこルカ」
「は」
「俺の嫁」

解説

「戻り値のリファレンスを配列に代入」で配列を返していれば配列のリファレンスになって「ARRAY(0x000000)」みたいに表示されるハズ。 でも個々の要素がリファレンスになっっているのでリストを返している。 ところがreturnに配列を指定して、スカラコンテキストで評価すると要素数が返ります。