You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl中使用匿名对象调用方法报错,求原因及解决方法

问题

编写了如下Perl脚本:

use strict;
use warnings;
use Data::Dumper;

package Foo;
sub new {
    bless { 'a' => 1, 
            'b' => sub { return "foo" }
    }, $_[0]
};
    
my $foo = Foo->new;
print $foo->b()."\n";

运行该脚本时出现错误:Can't locate object method "b" via package "Foo"。原以为这段代码创建了对象后可以调用函数b,请问问题出在哪里?

解答

Perl里用$obj->method()语法调用方法时,是去对应包的符号表中查找同名子例程,而不是直接读取对象哈希属性里的值。你现在把b作为哈希键存了一个匿名子程序,这只是对象的一个数据属性,并非Foo包的方法,所以调用$foo->b()时Perl找不到对应的方法,就会报错。

有两种方式解决这个问题:

方式一:将b定义为包方法

把b写成Foo包的子例程,这样就能通过方法调用语法访问:

use strict;
use warnings;
use Data::Dumper;

package Foo;
sub new {
    bless { 'a' => 1 }, $_[0]
};

sub b {
    return "foo";
}
    
my $foo = Foo->new;
print $foo->b()."\n";

方式二:直接调用属性中的匿名子程序(不推荐)

如果一定要保留哈希中的匿名子程序,需要先取出这个属性值再执行它,但这种方式破坏了对象封装性,不建议使用:

use strict;
use warnings;
use Data::Dumper;

package Foo;
sub new {
    bless { 'a' => 1, 
            'b' => sub { return "foo" }
    }, $_[0]
};
    
my $foo = Foo->new;
print $foo->{b}->()."\n";

本质上你混淆了对象的属性数据和包的方法这两个概念,Perl的方法调用机制不会自动去对象哈希里找对应键的子程序。

内容的提问来源于stack exchange,提问作者Jim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 13:21:00