Он пытается делегировать, но вы отправляете обратно результат print
.Поскольку 1
не благословен, поэтому вы не можете вызывать метод для него, и в этот момент происходит сбой делегирования.
Я думаю, что вам не хватает указания sub
для точки делегирования.Предполагается вернуть делегата.Damian sez :
Подпрограмма может также возвращать ссылку на объект, и в этом случае подпрограмма делегируется этому объекту (а не атрибуту текущего объекта),Это может быть полезно, когда фактическая цель делегирования более сложна сложна , чем просто прямой атрибут.[выделение мое]
Итак, если вы добавите в свой код, скажем, такой пакет:
package DoesDelegation;
our $Delegate = bless {}, __PACKAGE__;
sub getDelegation {
say 'You just called me!';
}
И вы измените подпрограмму делегирования следующим образом:
...
to => sub {
print "Hello Worlld!! I am foo\n";
$DoesDelegation::Delegate;
},
Вы не увидите неудачного делегирования - потому что теперь вы передали назад что-то, что может обработать сообщение 'getDelegation'
Кроме того, чтобы дать вам понимание того, что происходит в фоновом режиме:Если вы измените свой код следующим образом:
use Class::Delegation
send => 'getDelegation',
to => sub {
use Data::Dumper;
warn "In delegate \@_ :\n", Dumper( \@_ ), "\n";
warn "\$1='$1'\n\$2='$2'\n";
print "Hello Worlld!! I am foo\n";
$DoesDelegation::Delegate;
},
Вы увидите это:
In delegate @_ :
$VAR1 = [
bless( {}, 'DeviceLevelZ' ),
'getDelegation'
];
$1='DeviceLevelZ::'
$2='getDelegation'
Таким образом, есть два источника данных.В @_
вы получаете 1) открытый объект и 2) имя метода.Принимая во внимание, что вы получаете другие данные в $1
и $2
, которые являются полным именем метода, разделенного на пакет (имя тайника?) И имя.
A Предложение для Class::Delegator
Если у вас такое сложное делегирование, вы можете использовать подпрограмму.Но я не вижу этого в вашем описании.Если у вас нет чего-то такого сложного, то я рекомендую урезанную версию Дэвида Уилера Class::Delegator
, где я обнаружил, что это правда, при кредитовании модуля Конвея:
Блестящий модуль Дамиана Конвея делает в десять раз больше, чем этот - и в десять раз медленнее.
Я также рекомендую использовать декларативную структуру use
оператор для отправки ваших делегаций, вместо того, чтобы пытаться делегировать подчиненному, который направляет его соответствующему делегату, как вы, похоже, делаете здесь.
Если у вас имеется делегат для обработки getFoo
, тогда вместо этого сделайте следующее:
...
send => 'getFoo', to => '{foo_getter}'
Moose
Третий ипоследний способ сделать это - Moose
Делегирование :
package Website;
use Moose;
has 'uri' => (
is => 'ro',
isa => 'URI',
handles => [qw( host path )],
);
Таким образом, при указании делегатов для агрегатного объекта, вы указываете делегирование в handles
параметр.