[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