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 requested:
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, this is a bizarre mix - essentially a data structure that contains some built-in behavior. Sounds like an object to me. Perhaps you should explore the OO approach for your project.