

グローバルな変数`$foo`, `$bar`, `$buz`が存在し、それらを特定のスコープ内のみ局所化しようとすると、以下のようになると思います:

[code]

    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;
    
[/code]

これを「不特定多数のグローバル変数」に拡張した時、forループをそのまま使うとforの外に局所化した変数を出せません。

[code]

        # 不特定多数のグローバル変数を大文字に
        no strict 'refs';
        my @globals = qw(foo bar buz);
        local ${"::$_"} = uc ${"::$_"} for @globals;
    
        # がっ...駄目っ...forの外！
        say $foo, $bar, $buz;
    
[/code]

仕方なく`eval`に頼ると、ブロックそのものを食わせる必要がありそうです。ちょっと無理矢理感があります。

[code]

    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;
    
[/code]

このような不特定多数のグローバル変数をあるスコープで局所化したい場合、`eval`を使わずにすんなり書く事はできないでしょうか？


CC BY-SA 3.0
2015-04-22T14:53:15.037
9474
2017-07-13T16:17:38.533
2015-04-22T15:21:48.823
62
62
question
perl
複数のグローバル変数をevalを使わず動的にlocalすることは可能ですか？


例えば次のような感じでどうでしょうか。  
コンセプトはスコープの最初に値を保存し終了時に戻す。（つまり手動local)

[code]

    use strict;
    use warnings;
    use v5.10;
    
    our ($foo, $bar, $buz) = qw(foo bar buz);
    
    #糖衣構文用関数
    sub using(&@) {
        my $code = shift;
        my @v = @_;#変数の内容を保存
        $code->(@_);
        my $i = 0;
        $_ = $v[$i++] for @_;#変数の内容を復元
    }
    
    using {
        $_ = uc  $_  for @_;
        say $foo, $bar, $buz;#内容が変更された(大域)変数、大文字で表示される。
    } $foo, $bar, $buz;#不特定の可変個の引数
    
    say $foo, $bar, $buz;
    
[/code]


CC BY-SA 3.0
2015-04-22T22:18:16.673
9481
2015-04-22T22:53:35.327
2015-04-22T22:53:35.327
5044
5044
9474
answer