4

跑步:

$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

预期的输出是:

DESTROY
3

我只想tie在其所在的范围内变量 $t tie。在范围之外,它的行为必须与 tie 之前相同。因此,我包装tie到块中并期望untie在到达块末尾时调用它(例如在块末尾恢复值的“本地”,但对于绑定变量,我希望行为恢复(untie $t))。请注意$t尚未超出范围。

4

4 回答 4

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};
    
于 2015-10-05T14:00:10.137 回答
4

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

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

如果您希望在untie调用和销毁对象时调用公共代码,那么没有什么能阻止您。

sub UNTIE   { shift->_destructor(@_) }
sub DESTROY { shift->_destructor(@_) }
于 2015-10-05T14:32:26.607 回答
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.
于 2015-10-05T17:16:00.540 回答
0

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

my $t = 3;

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

print "$t\n";  # 3.
于 2015-10-12T10:25:44.650 回答