你怎么定位了一些遗留的全局变量不EVAL?(How do you localize a number

2019-08-17 14:09发布

我问这个问题,因为我终于解决了,我一直试图找到一种技术,在许多情况下的问题。 我认为这是相当整洁,所以我在做这个一个Q-和-A。

见,如果我可以使用eval ,我只是这样做:

eval join( "\n"
         , map { 
             my $v = $valcashe{$_}; 
             sprintf( '$Text::Wrap::%s = %s', $_
                    , ( looks_like_number( $v ) ? $v : "'$v'" )
                    )
          }
        );
Text::Wrap::wrap( '', '', $text );

我甚至尝试是非常棘手,但似乎local本地化符号至虚拟块,而不是物理块。 所以这不工作:

ATTR_NAME: while ( @attr_names ) {
    no strict 'refs';
    my $attr_name       = shift;
    my $attr_name       = shift @attr_names;
    my $attr_value      = $wrapped_attributes{$attr_name};
    my $symb_path       = "Text\::Wrap\::$attr_name";
    local ${$symb_path} = $attr_value;
    next ATTR_NAME if @attr_names;

    Text::Wrap::wrap( '', '', $text );

}

同一物理块 ,和我之前和之后设置测试包变量,他们甚至通过循环显示自己的时间适当的值。 但测试表明,只有通过的最后一个变量保留了呼叫价值wrap 。 所以,价值只停留本地化,直到循环结束。

我认为解决的办法是整齐的 - 即使神秘的Perl magick。 但最终的结果是好的,因为这意味着我可以换一个依赖包范围的变量和放心,设定的值会随着短命越好遗留代码。

Answer 1:

斧头兵,你这个白痴! 该包藏匿是哈希呢! 这工作:

local @Text::Wrap::{ keys %wrapped_attributes } 
    = \( values %wrapped_attributes )
    ;

这将执行以下操作:

  1. 它访问数组切片Text::Wrap的符号表,并返回指定的符号。
  2. 因为它是一个符号 ,而不是一个标量,为了让Perl来知道正确的插槽,你必须分配引用 。 这是数组和哈希也是如此,但我们都知道,他们的参考是比较常见的。
  3. \( ... )语法传递回列表中的每个项目的引用。

所以我们定位在每个键的每个变量%wrapped_attributes ,我们将其指定为每个值有一个参考。

这是丑陋和神秘的,而且很难将其移出的每一次我需要的方式-但有了它,我可以预先指定并延迟定位选择的地方,我可以把达米安康威的建议铁丝网和危险迹象。

如果我要使用它,它在那里我用它只是那个丑陋。



文章来源: How do you localize a number of legacy globals without eval?