为什么变量仍然存在

时间:2015-10-05 13:26:47

标签: perl scope tie

运行:

$t =  3;
{
    tie $t, 'Yep';
} # Expect $t to become untied here.
print $t;

package Yep;

sub TIESCALAR {
   bless {}, 'Yep';
}

sub UNTIE {
   print "UNTIE\n";
}

sub DESTROY {
   print "DESTROY\n";
}

输出结果为:

Can't locate object method "FETCH" via package "Yep" at a.pl line 5.
DESTROY

EXPECTED输出为:

DESTROY
3

我想tie变量$ t仅在tie所在范围的持续时间内。超出范围,它必须与tie之前的行为相同。所以我将tie包装到块中并期望在到达块结束时调用untie(比如'local',其中值在块结束时被恢复,但是对于绑定变量I期望行为恢复(untie $t))。请注意$t尚未超出范围。

4 个答案:

答案 0 :(得分:4)

  

回答:当绑定变量超出范围时,为什么不调用UNTIE?

因为UNTIE在用户调用内置untie命令时处理。如果在超出范围时调用DESTROY,请处理DESTROY

如果你需要逻辑,那么你可以

  1. 从两个中调用一个常见的清理子

    sub UNTIE   { &_destructor; } # Perl 4 style, which passes the current
    sub DESTROY { &_destructor; } # @_ to the called procedure.
    
  2. goto来自两者的常见清理子

    sub UNTIE   { goto &_destructor; } # does not return to this sub
    sub DESTROY { goto &_destructor; } # does not return to this sub
    
  3. 别名一个到另一个:

    *UNTIE = *DESTROY{CODE};
    

答案 1 :(得分:4)

  

当绑定变量超出范围时,为什么不调用UNTIE?

当变量超出范围时,询问为什么UNTIE未被调用,这与询问为什么UNTIE在调用DESTROY时不被调用是一回事。好吧,那将毫无用处。有用的是在调用untie时调用的函数,这就是UNTIE的内容。

如果你想在调用untie时调用公共代码,并且当对象被销毁时,没有什么能阻止你。

sub UNTIE   { shift->_destructor(@_) }
sub DESTROY { shift->_destructor(@_) }

答案 2 :(得分:1)

至于全新的问题,

当进行这些更改的范围

时,变量的更改不会自动撤消
my $t = 3;

{
   $t = 4;
}

print "$t\n";  # 4, not 3.

当改变是添加领带魔法时也是如此。您可以使用untie删除魔法,但如果您只使用新变量,则效果最佳。

my $t = 3;

{
   tie my $t, 'Yep';
} # Tied variable destroyed here.

print "$t\n";  # 3.

答案 3 :(得分:0)

my 的例子给了我一个线索。所以在我的情况下使用local。

my $t = 3;

{
   tie local $t, 'Yep';
} # Tied variable destroyed here.

print "$t\n";  # 3.