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
####
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?