The best way I can think of (as in, requiring the least amount of existing codebase changes) is to create a "proxy object". In other words, tie the original hash to your own class which looks for the key you want to have tied separately and handles it specially.
#!/usr/bin/perl -l
use warnings;
package Tie::MyHash;
use Tie::Hash;
@ISA = ('Tie::StdHash');
use Tie::IxHash;
use Tie::Scalar::Timeout;
sub TIEHASH {
my $class = shift;
my $hash = {};
tie %$hash, 'Tie::IxHash';
tie ${$hash->{'special'}}, 'Tie::Scalar::Timeout', EXPIRES => '+
+2s';
return bless $hash, $class;
}
sub FETCH {
my ($this, $key) = @_;
if($key eq 'special') {
print tied(${$this->{'special'}}) if $key eq 'special';
return ${$this->{'special'}};
} else {
print tied(%$this);
return $this->{$key};
}
}
sub STORE {
my ($this, $key, $value) = @_;
return ${$this->{'special'}} = $value if($key eq 'special');
return $this->{$key} = $value;
}
sub AUTOLOAD {
my $this = shift;
my $sub = $AUTOLOAD;
$sub =~ s/.*:://;
tied(%$this)->$sub(@_);
}
# Tie::IxHash doesn't have a DESTROY method, so we need one
sub DESTROY {}
package main;
tie my %hash, 'Tie::MyHash';
$hash{'mundane'} = 'foo';
$hash{'special'} = 'bar';
print $hash{'mundane'};
print $hash{'special'};
print "Keys: ", join(", ", tied(%hash)->Keys(0, 1));
sleep 3;
print $hash{'special'} || 'undef';
Update: Hrm. I just realized that the "special" key will not be considered part of the Tie::IxHash at all, for ordering purposes and such, so this isn't really a good solution either. I'll have to think about that...
Update2: It was straight-forward to change it so that the "special" key was stored in the Tie::IxHash. Updated the code accordingly.
bbfu
Black flowers blossum
Fearless on my breath |