为什么变量仍然绑定

Why is the variable still tied

运行:

$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 包装到块中,并期望在到达块末尾时调用 untie (如 'local' ,其中值在块末尾恢复,但对于 tied我希望行为恢复的变量 (untie $t) )。请注意 $t 尚未超出范围。

Answering: Why is UNTIE not called when tied variable goes out of scope?

因为 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};
    

Why is UNTIE not called when tied variable goes out of scope?

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

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

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

至于全新的问题,

在进行这些更改的范围内时,不会自动撤消对变量的更改

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.

my 的例子给了我一个线索。所以在我的例子中使用 local.

my $t = 3;

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

print "$t\n";  # 3.