複数のグローバル変数をevalを使わず動的にlocalすることは可能ですか?
グローバルな変数$foo
, $bar
, $buz
が存在し、それらを特定のスコープ内のみ局所化しようとすると、以下のようになると思います:
use strict;
use warnings;
use v5.10;
our ($foo, $bar, $buz) = qw(foo bar buz);
UPPER_CASE_WORLD: {
# このスコープだけ所定のグローバル変数を大文字に
no strict 'refs';
local ($foo, $bar, $buz) = map { uc ${"::$_"} } qw(foo bar buz);
say $foo, $bar, $buz;
}
say $foo, $bar, $buz;
1;
これを「不特定多数のグローバル変数」に拡張した時、forループをそのまま使うとforの外に局所化した変数を出せません。
# 不特定多数のグローバル変数を大文字に
no strict 'refs';
my @globals = qw(foo bar buz);
local ${"::$_"} = uc ${"::$_"} for @globals;
# がっ...駄目っ...forの外!
say $foo, $bar, $buz;
仕方なくeval
に頼ると、ブロックそのものを食わせる必要がありそうです。ちょっと無理矢理感があります。
use strict;
use warnings;
use v5.10;
our ($foo, $bar, $buz) = qw(foo bar buz);
no strict 'refs';
my @globals = qw(foo bar buz);
my $bunch_of_locals = join q{}, map {
"local \${'::$_'} = uc \${'::$_'};"
} @globals;
eval <<"__UPPER_CASE_WORLD";
{
# 不特定多数のグローバル変数を大文字に
$bunch_of_locals
# ここまでしなきゃいけない?
say \$foo, \$bar, \$buz;
}
__UPPER_CASE_WORLD
say $foo, $bar, $buz;
1;
このような不特定多数のグローバル変数をあるスコープで局所化したい場合、eval
を使わずにすんなり書く事はできないでしょうか?