Withigo has asked for the wisdom of the Perl Monks concerning the following question:
I want %conf to be a general wrapper that can be treated like a hash, so tie seems like the way to go. I also want to fetch values from %conf, store them in scalars, and then when those scalars are changed I would like transparent changes to occur back in the tied hash. Kind of confusing, I know. But I need it this way, so lets just suspend alternative designs and look at it as a pure exercise in Perl.tie our %conf, 'My::Hash'; # $dir is a tied Tie::Scalar our $dir = $conf{'dir'}; print $dir, $/; # prints /home/foo for example # using tie magic, storing a value in $dir also updates # 'dir' in %conf $dir = '/somewhere/else'; $dir = $conf{'dir'}; print $dir, $/; # now prints /somewhere/else
Now using the above code something unexpected happens:package My::Hash; use base 'Tie::Hash'; our %hash = ('dir' => '/home/foo'); sub TIEHASH { return bless \%hash, __PACKAGE__; } sub STORE { my ($self, $key, $val) = @_; $self->{$key} = $val; } sub FETCH { my ($self, $key) = @_; my $val = $self->{$key}; tie my $tied_scalar, 'My::Scalar', $key, $val; return $tied_scalar; } 1; package My::Scalar; use base 'Tie::Scalar'; sub TIESCALAR { my ($self, $key, $val) = @_; return bless {'value' => $val, 'key' => $key , 'fetched' => 0 }, __PACKAGE__; } sub STORE { my $self = shift; my $newval = shift; my $key = $self->{'key'}; My::Hash::hash{$key} = $self->{'value'} = $newval; } sub FETCH { my $self = shift; # this cleverness is done so that Tie::Hash FETCH does not # call Tie::Scalar FETCH when it tries to return the tied # scalar. if ($self->{'fetched'}) { return $self->{'value'}; }else{ $self->{'fetched'} = 1; return $self; } } 1;
tie our %conf, 'My::Hash'; our $dir = $conf{'dir'}; print ref $dir, $/; # prints 'My::Scalar'; print tied $dir ? 1 : 0; # prints 0 print $dir, $/; # prints 'My::Scalar=HASH(0x820f268)' print $dir->FETCH # prints '/home/foo'; # attempts to call $dir->STORE give lvalue errors # # why is $dir untied now yet I can still call tied methods # on it?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: A Tied hash returning a tied scalar which becomes untied, why?
by bart (Canon) on Jun 07, 2006 at 09:11 UTC | |
|
Re: A Tied hash returning a tied scalar which becomes untied, why?
by ikegami (Patriarch) on Jun 07, 2006 at 23:13 UTC |