Reputation: 25207
Running:
$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";
}
The output is:
Can't locate object method "FETCH" via package "Yep" at a.pl line 5.
DESTROY
The EXPECTED output is:
DESTROY
3
I want to tie
variable $t only for the duration of the scope in which tie
is located. Out of the scope it must behave same as before tie. So I wrap tie
into the block and expect that untie
will be called when the end of block is reached (like 'local' where the value is restored at the end of block, but for tied variable I expect behaviour is restored (untie $t
) ). Notice the $t
is not out of scope yet.
Upvotes: 4
Views: 253
Reputation: 25207
The example with my give me a clue. So in my case use local.
my $t = 3;
{
tie local $t, 'Yep';
} # Tied variable destroyed here.
print "$t\n"; # 3.
Upvotes: 0
Reputation: 29854
Answering: Why is UNTIE not called when tied variable goes out of scope?
Because UNTIE
handles when the user calls the builtin untie
command. If it calls DESTROY
when going out of scope, handle DESTROY
.
If you need logic in both then you can
Call a common cleanup sub from both
sub UNTIE { &_destructor; } # Perl 4 style, which passes the current
sub DESTROY { &_destructor; } # @_ to the called procedure.
goto
common cleanup sub from both
sub UNTIE { goto &_destructor; } # does not return to this sub
sub DESTROY { goto &_destructor; } # does not return to this sub
Alias one to the other:
*UNTIE = *DESTROY{CODE};
Upvotes: 4
Reputation: 386331
Why is UNTIE not called when tied variable goes out of scope?
Asking why UNTIE
isn't called when the variable goes out of scope is the same thing as asking why UNTIE
isn't called whenever DESTROY
is called. Well, that would be useless. What is useful is a function that's called when untie
is called, and that's what UNTIE
is.
If you want common code to be called when untie
is called and when the object is destroyed, nothing's stopping you.
sub UNTIE { shift->_destructor(@_) }
sub DESTROY { shift->_destructor(@_) }
Upvotes: 4
Reputation: 386331
As for the completely new question,
Changes to variables aren't automatically undone when the scope in which those changes are made
my $t = 3;
{
$t = 4;
}
print "$t\n"; # 4, not 3.
Same goes when the change is to add tie magic. You can use untie
to remove the magic, but it's best if you simply use a new variable.
my $t = 3;
{
tie my $t, 'Yep';
} # Tied variable destroyed here.
print "$t\n"; # 3.
Upvotes: 1