note
Yaribz
Isn't it a typical use case of tied hash ? This code for example should do exactly what you want, without requiring any get or set function:
<code>use warnings;
use strict;
package ParamsHash;
require Tie::Hash;
our @ISA='Tie::StdHash';
use constant { UNDEF_VAL => 'a' };
# configure your parameter inheritance here:
our @GLOBAL_PARAMS=(qw'margin padding');
our %SUB_PARAMS=(horizontal => [qw'left right'],
vertical => [qw'top bottom']);
my %INHERIT;
foreach my $param (@GLOBAL_PARAMS) {
foreach my $subp (keys %SUB_PARAMS) {
map {$INHERIT{"$param-$_"}="$param-$subp"} @{$SUB_PARAMS{$subp}};
$INHERIT{"$param-$subp"}=$param;
}
}
sub FETCH {
my ($this,$key)=@_;
my $val=$this->{$key};
return $val if(defined $val && $val ne UNDEF_VAL);
my $inherited=$INHERIT{$key};
return UNDEF_VAL unless(defined $inherited);
return $this->FETCH($inherited);
}
</code>
You can test it by adding this code at the end of the file for example:
<code>
package main;
my %par;
tie(%par,'ParamsHash');
print "Initial values:\n";
printSomeParams();
print "Setting 'margin' to 4:\n";
$par{margin}=4;
printSomeParams();
print "Setting 'margin-horizontal' to 8:\n";
$par{'margin-horizontal'}=8;
printSomeParams();
print "Setting 'margin-left' to 3:\n";
$par{'margin-left'}=3;
printSomeParams();
sub printSomeParams {
map {printParam($_)} (qw'
margin
margin-horizontal
margin-left
margin-right
')
}
sub printParam { print " $_[0] = $par{$_[0]}\n" }
</code>
This should give you following result:
<code>
Initial values:
margin = a
margin-horizontal = a
margin-left = a
margin-right = a
Setting 'margin' to 4:
margin = 4
margin-horizontal = 4
margin-left = 4
margin-right = 4
Setting 'margin-horizontal' to 8:
margin = 4
margin-horizontal = 8
margin-left = 8
margin-right = 8
Setting 'margin-left' to 3:
margin = 4
margin-horizontal = 8
margin-left = 3
margin-right = 8
</code>
11145036
11145036