Eugen Konkov Eugen Konkov - 1 year ago 52
Perl Question

How inheritance works when method is CODEREF?

In Mojo::EventEmitter we have next line of code:

for my $cb (@$s) { $self->$cb(@_) }

of callback.

Will there any difference and which are if I write:

for my $cb (@$s) { $cb->($self, @_) }

I suppose that inheritance will not work because of
as it works in case when
contains string with a method name.
So in this case rewritten code will work similar.

Do I understand all right or miss something?

Answer Source

When $cb is a code reference, inheritance is not checked. In fact, $self is not examined at all.

When $cb is a code reference,


is functionally identical to

$cb->($self, @_)

That's why $cb should be obtained using can, which follows inheritance.

package Parent {
   sub new { bless({ @_ }, shift) }
   sub method { CORE::say("!"); }

package Child {
   our @ISA = 'Parent';

my $self = Child->new();
my $method_name = 'method';

my $cb = $self->can($method_name)
   or die("The object's class doesn't have method $method_name\n");


Note that some people use

my $f = "function_name";

as an alternative to

my $f = "sub_name";
no strict qw( refs );

Yet, it's quite inappropriate to use a method call to call a non-method, and this trick only works if the sub has no parameters. If you really have a problem with this (appropriate) use of no strict, you can you the following trick:

my $f = "sub_name";
\&$f->();                # \&$f isn't subject to "use strict qw( refs );" checks