Reputation: 60771
I would like to have a subroutine as a member of a hash which is able to have access to other hash members.
For example
sub setup {
%a = (
txt => "hello world",
print_hello => sub {
print ${txt};
})
return %a
}
my %obj = setup();
$obj{print_hello};
Ideally this would output "hello world"
EDIT
Sorry, I failed to specify one requirement
I should be able to do
$obj{txt} = "goodbye";
and then $obj{print_hello} should output goodbye
Upvotes: 3
Views: 601
Reputation: 6642
Close:
sub setup {
my %a = (
txt => "hello world",
print_hello => sub {
print $a{txt};
});
return %a;
}
my %obj = setup();
$obj{print_hello}->();
Upvotes: 0
Reputation: 42411
If you want the calling code to be able to modify the message in the hash, you need to return the hash by reference. This does what you asked for:
use strict;
use warnings;
sub self_expressing_hash {
my %h;
%h = (
msg => "hello",
express_yourself => sub { print $h{msg}, "\n" },
);
return \%h;
}
my $h = self_expressing_hash();
$h->{express_yourself}->();
$h->{msg} = 'goodbye';
$h->{express_yourself}->();
However, it's a bizarre concoction -- essentially, a data structure that contains some built-in behavior. Sounds a like an object to me. Perhaps you should look into an O-O approach for your project.
Upvotes: 7
Reputation: 66968
This will work:
sub setup {
my %a = ( txt => "hello world" );
$a{print_hello} = sub { print $a{txt} };
return %a;
}
my %obj = setup();
$obj{print_hello}->();
Upvotes: 2