sub mk_data_accessors3 { my $path = shift; for my $name (@_) { my $accessor = sub { carp "Warning: '$name' takes at most 2 arguments...\n" if @_ > 2; my $self = shift; $self->{$path}{$name} = shift if @_; return $self->{$path}{$name}; }; # keep the scope of "no strict" as small as possible no strict 'refs'; # needed for *$name *$name = $accessor; # install the sub } } mk_data_accessors3('data','bar'); print bar({data=>{bar=>456}}), "\n"; # 456