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

もしも既存のコードにlocalを見つけたら

2019-03-26

localは昔の仕様

localの説明から。
「あなたはが本当に望んでいるのは my の方でしょう; local はほとんどの人々が『ローカル』と考えるものと 違うからです。」(原文ママ)
Perlの組み込み関数 local の翻訳 - perldoc.jp
「警告: 一般的には、local ではなくmy を使うべきです; なぜなら、そちらの ほうが早く、安全だからです」
perlsub - Perl のサブルーチン - perldoc.jp
という事で、これからコードを書く時はmyがあるのでlocalを使いません。

サンプル

sample_85.plのコード

#!/usr/bin/env perl -w

use strict;
use warnings;
use utf8;

use feature "say";

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

use FindBin;
use lib $FindBin::Bin;

use sample_85;

use open IO => ":utf8";

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

$| = 1;

local $a = "たこルカ";
say "最初:$a";
s1();
say "s1戻り:$a";
s2();
say "最後:$a";

sub s1 {
	say "s1入口:$a";

	local $a = "は";
	say "s3呼び出し前:$a";
	sample_85::s3();
	say "s3呼び出し後:$a";

	say "s1出口:$a";
}

sub s2 {
	say "s2入口:$a";

	$a = "嫁";
	say "s3呼び出し前:$a";
	sample_85::s3();
	say "s3呼び出し後:$a";

	say "s2出口:$a";
}

sample_85.pmのコード

package sample_85;

use utf8;
use feature "say";

sub s3 {
	say "s3入口:$::a";

	$::a = "俺";
	say "s4呼び出し前:$::a";
	s4();
	say "s4呼び出し後:$::a";

	say "s3出口:$::a";
}

sub s4 {
	say "s4入口:$::a";

	$::a = "の";

	say "s4出口:$::a";
}

1;

実行結果

localを呼んだ所のスコープから抜ける(localを書いたブロックが終わる、サブルーチンの呼び出し元に戻る)と呼ぶ前の値に回復する事に注目してご覧ください。 「s1出口」が回復前で「s1戻り」が回復後です。

最初:たこルカ
s1入口:たこルカ
s3呼び出し前:は
s3入口:は
s4呼び出し前:俺
s4入口:俺
s4出口:の
s4呼び出し後:の
s3出口:の
s3呼び出し後:の
s1出口:の
s1戻り:たこルカ
s2入口:たこルカ
s3呼び出し前:嫁
s3入口:嫁
s4呼び出し前:俺
s4入口:俺
s4出口:の
s4呼び出し後:の
s3出口:の
s3呼び出し後:の
s2出口:の
最後:の