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();
在双方的情况下,您都在调用 subs 而不是简单地引用它们。
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 代码部分的行为(我可能有些错误,有人纠正我)
如果你真的需要在每个实例的基础上做,你可能会做一些类继承,只是构建一个派生类,和/或动态创建新包。