我正在试图修补(duck-punch :-)一个LWP::UserAgent实例,如下所示:
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;
Run Code Online (Sandbox Code Playgroud)
这不是正确的语法 - 它产生:
无法在[module] line [lineno]修改非左值子程序调用.
我记得(来自Programming Perl),调度查找是基于受祝福的包动态执行的(ref($agent)我相信),所以我不确定实例猴子修补如何在不影响受祝福的包的情况下工作.
我知道我可以继承它UserAgent,但我更喜欢更简洁的猴子修补方法.同意成年人和你有什么.;-)
我看到如何重新定义Perl类方法?,所以我想通过一个例子更好地理解它是如何工作的.(相关:我如何引用方法? - PerlMonks)
如果我有一个对象$obj是一些实例Class,其具有Class::method,则$obj还具有$obj->method; 我假设在这种情况下简化的内存布局看起来像这样(在LaTeX表生成器中制作的表 ;对于下面的一个,src在这里):

...也就是说,在(比方说)地址0x1000,我们有$obj->method,这将简单地(某种程度上)指向实际Class::method定义,即(例如)在0x3500.
假设我sub在主文件中有一个定义的地方somefunc(忽略表中的前缀$),其定义最终在地址0x2000.
如果我只为$obj实例"猴子补丁"/替换方法,我希望内存布局看起来像这样(src here):

现在问题就是这个 - 在下面的例子中(stuff的命名比上面的表更加独特),我实际上想Demo::My::Functions::test_me用主文件中定义的方法替换整个类方法repl_test_me.我真的不知道对地址有什么期望,所以我试图在方法修补之前和之后显示我认为的地址,使用的是%p说明符printf.代码输出:
$ perl cltest.pl
Starting Demo::Main...
Orig test_me!
1: DMFo: 8e63dc0 DMFo->test_me 8e916f8 DMF::test_me 8e916e8 repl_test_me 8e91748
Orig test_me!
-- CODE --
Subroutine Demo::My::Functions::test_me redefined at cltest.pl line 59. …Run Code Online (Sandbox Code Playgroud)