sub _user_agent_get_basic_credentials_patch {
return ($username, $password);
}
my $agent = LWP::UserAgent->new();
$agent->get_basic_credentials = _user_agent_get_basic_credentials_patch;
У вас здесь не 1, а 2 проблемы, потому что это то, что вы делаете:
( $agent->get_basic_credentials() ) = _user_agent_get_basic_credentials_patch();
В обоих случаях вы вызываете подводные лодки, а не просто ссылаетесь на них.
assign the result of
'_user_agent_get_basic_credentials_patch'
to the value that was returned from
'get_basic_credentials';
Эквивалентная логика:
{
package FooBar;
sub foo(){
return 5;
}
1;
}
my $x = bless( {}, "FooBar" );
sub baz(){
return 1;
}
$x->foo() = baz();
# 5 = 1;
Так что неудивительно, что он жалуется.
Ваш "фиксированный" код в вашем ответе также неверен, по той же причине с другой проблемой, которую вы можете не осознавать:
$agent->{get_basic_credentials} = _user_agent_get_basic_credentials_patch;
Это довольно некорректная логика, которая думает, что работает так, как вы думаете.
Что он на самом деле делает, это:
1. Dereference $agent, which is a HashRef
2. Set the hash-key 'get_basic_credentials' to the result from _user_agent_get_basic_credentials_patch
Вы не назначали никакой функции вообще.
{
package FooBar;
sub foo(){
return 5;
}
1;
}
my $x = bless( {}, "FooBar" );
sub baz(){
return 1;
}
$x->{foo} = baz();
# $x is now = ( bless{ foo => 1 }, "FooBar" );
# $x->foo(); # still returns 5
# $x->{foo}; # returns 1;
Исправление обезьяны, конечно, довольно плохо, и я сам не видел, как переопределить метод в единственном экземпляре чего-то подобного.
Однако вы можете сделать следующее:
{
no strict 'refs';
*{'LWP::UserAgent::get_basic_credentials'} = sub {
# code here
};
}
Что в глобальном масштабе заменит поведение разделов кода get_basic_credentials (я могу ошибаться, кто-то меня поправит)
Если вам действительно нужно сделать это для каждого экземпляра, вы, вероятно, могли бы немного наследовать классы и просто вместо этого создать производный класс и / или динамически создавать новые пакеты.