package Servant::PartlyJustDelegating; has callback_proxy => ( is => 'ro', isa => 'CodeRef', required => 1, ); BEGIN { for (qw( invent_example fail_admittedly )) { no strict 'refs'; my $callback = $_; *$callback = sub { goto &{ shift->callback_proxy->($callback) }; }; } } package Omnipotential::Entity; has servants => ( is => 'ro', isa => 'ArrayRef[Servant::PartlyJustDelegating]', ); has _servant_interface_proxy => ( is => 'ro', isa => 'CodeRef', lazy => 1, builder => '__build_servant_interface_proxy', init_arg => undef, ); sub __build_servant_interface_proxy { my ($self) = @_; weaken($self); my %callback_for = ( invent_example => sub { my $part = shift; ... }, fail_admittedly => sub { my ($part, $arg) = @_; ... }, ); return sub { my $name = shift; return $callback_for{ $name } // croak "callback not found: $name"; }; } sub _build_servant { my ($self, $row) = @_; ... return Servant::PartlyJustDelegating->new( @arguments, callback_proxy => $self->_servant_interface_proxy, ); }