Ваш подход с goto
является правильным, поскольку он гарантирует, что caller
/ wantarray
и тому подобное продолжают работать правильно.
Я бы настроил новый метод так:
sub merhaba {
if (my $method = eval {$_[0]->can('hello')}) {
goto &$method
} else {
# error code here
}
}
Или, если вы не хотите использовать наследование, вы можете добавить новый метод в существующий пакет из вашего вызывающего кода:
*My::Hello::merhaba = \&My::Hello::hello;
# or you can use = My::Hello->can('hello');
тогда вы можете позвонить:
My::Hello->merhaba('StackOverflow');
и получите желаемый результат.
В любом случае будет работать, маршрут наследования будет более понятным, но добавление метода в существующий пакет приведет к более быстрым вызовам метода.
Edit:
Как отмечается в комментариях, в нескольких случаях назначение глоба будет нарушено с наследованием, поэтому в случае сомнений используйте первый метод (создание нового метода в подпакете).
Майкл Карман предложил объединить обе техники в самоопределяющуюся функцию:
sub merhaba {
if (my $method = eval { $_[0]->can('hello') }) {
no warnings 'redefine';
*merhaba = $method;
goto &merhaba;
}
die "Can't make 'merhaba' an alias for 'hello'";
}