[Israel.pm] reference to tied variables
Moshe Kaminsky
kaminsky at math.huji.ac.il
Thu Jul 15 16:02:14 PDT 2004
Ok, sorry. I had a misconception about tied variables. I thought it is
just a purely syntactic declaration, associated with the name of the
variable, rather than the value. In fact, it turns out that you can do
things like
tie $f{'a'}, 'Foo';
and also take references and so on.
But I still don't understand what's going on with the following code.
It's a slight modification of the Remember example in the perltie page.
In this example, values are written to a file when they are stored. The
controlling class also has a method to add extra comments to that file.
Therefore, to use the whole thing you need both the tied variable and
its controlling object (for calling the comment method).
I wanted to have one variable for both things. So I added a new() method
that ties a variable to the class, and then stores a reference to it in
the controlling object. Here is the whole code:
====8<====
#!/usr/bin/perl
package Remember;
use strict;
use warnings;
use IO::File;
use overload '${}' => \&as_scalar;
sub new {
my $Tie;
my $Res = tie $Tie, shift, @_;
$Res->{Tie} = \$Tie;
return $Res;
}
sub as_scalar : lvalue {
$_[0]->{Tie};
}
sub TIESCALAR {
my $class = shift;
my $filename = shift;
my $handle = new IO::File "> $filename"
or die "Cannot open $filename: $!\n";
print $handle "The Start\n";
bless {FH => $handle, Value => 0}, $class;
}
sub FETCH {
my $self = shift;
return $self->{Value};
}
sub STORE {
my $self = shift;
my $value = shift;
my $handle = $self->{FH};
print $handle "$value\n";
$self->{Value} = $value;
}
sub UNTIE {
print "Untying...\n";
my $self = shift;
my $handle = $self->{FH};
print $handle "The End\n";
close $handle;
}
sub DESTROY {
print "Destroying...\n";
my $self = shift;
untie ${$self->{Tie}};
}
sub comment {
my $self = shift;
my $text = shift;
my $handle = $self->{FH};
print $handle $text, "\n";
}
package main;
use warnings;
use strict;
my $X = new Remember 'myfile.txt';
$$X = 1;
$$X = 2;
$$X = 4;
$X->comment('changing...');
$$X = 5;
print "X==$$X\n";
undef $X;
====>8====
Again, the whole difference with the example in perltie is the methods
new() and as_scalar(), and the usage.
The problem is with the DESTROY. The untie is never executed. In fact,
it appears that in all of the prescribed uppercase methods, $self->{Tie}
is not recognized as a reference to a tied variable
(tied(${$self->{Tie}}) is undef). If I call UNTIE directly from DESTROY,
I further discover that the value of FH is undef. The strangest thing is
that this behavior is irregular, and sometimes when I use extra modules,
the problem disappears.
I would really like to know what's going on (of course, there are other
ways to do all this).
Thanks,
Moshe
* Yuval Yaari <yuval at windax.com> [15/07/04 23:47]:
> Sorry - what I wanted to say about references and forgot:
> $$Bar = 4;
> is equivalent to
> $Foo = 4;
> (In case, like in your example, that $Bar is a reference to $Foo)
>
> So it's not a bug, it's a feature :)
>
> --Yuval
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://perl.org.il/pipermail/perl/attachments/20040716/ce09251d/attachment.pgp
More information about the Perl
mailing list