In Perl, method invocation always involves a package.
$foo is blessed into Foo, so $foo->b calls &Foo::b (or the &b of a package from which Foo inherits).
I have no idea why you think it would call &{ $foo->{ b } }. Objects don't even need to be hashes.
To make b specific to the object, you could add the following to Foo:
sub b { $_[ 0 ]{ b }->( @_ ) }
If you want hide b from stack traces and from caller, you could use
sub b { goto &{ $_[ 0 ]{ b } }; }
Demo:
use v5.14; use warnings; { package Foo; sub new { my $class = shift; return bless( { @_ }, $class ); } sub b { $_[ 0 ]{ b }->( @_ ) } } my $foo1 = Foo->new( b => sub { "foo" } ); my $foo2 = Foo->new( b => sub { $_[1] } ); say $foo1->b( 123 ); # foo say $foo2->b( 123 ); # 123
bis a hash key, not a method. So to call the sub you need to extract from the hash first like this:print $foo->{b}()."\n";