我刚开始学习Perl。当我移动到面向对象时,我收到类似
的错误Can't locate object method "say_hello" via package "1" (perhaps you forgot to load "1"?) at ./main.pl line 8.
我搜索了很多解决方案。遇到类似this的类似问题。我的理解是,这不是一般问题。
这是我的班级
# MyModule.pm
package MyModule;
use strict;
use warnings;
sub new {
print "calling constructor\n";
}
sub say_hello {
print "Hello from MyModule\n";
}
1;
这是我的测试脚本
# main.pl
#!/usr/bin/perl -w
use strict;
use warnings;
use MyModule;
my $myObj = new MyModule();
$myObj->say_hello();
如果从main.pl
答案 0 :(得分:8)
您的构造函数new
需要将祝福引用返回到您用来包含对象信息的数据结构。您在此处没有相关数据,但仍需要返回
bless
将数据与特定包相关联。在这种情况下,您的对象应该被祝福MyModule
,以便perl在看到MyModule::say_hello
等方法调用时知道查找$myObj->say_hello()
您当前的构造函数返回print
语句返回的值,如果成功则返回1
,因为它几乎可以肯定。这就是您在错误消息
"1"
的原因
找不到对象方法" say_hello"通过包" 1" (也许你忘了在./main.pl第8行加载" 1"?)。
对象数据的最常见容器是哈希,因此您需要将new
更改为此
sub new {
print "calling constructor\n";
my $self = { };
bless $self, 'MyModule';
return $self;
}
然后你的程序将按预期工作。它创建一个匿名哈希并将其分配给$self
变量,然后祝福并返回它
请注意,这可以更加简洁:
如果没有return
语句,子程序将返回最近执行的语句的值
默认情况下,bless
会将数据保存到当前包中
在祝福之前无需将参考存储在变量中
因此,写作
可以达到同样的效果sub new {
print "calling constructor\n";
bless { };
}
还请注意您的电话
my $myObj = new MyModule()
不太理想。它被称为间接对象表示法,可能不明确。最好始终使用直接方法引用,例如
my $myObj = MyModule->new()
以消除呼叫的歧义
答案 1 :(得分:5)
您没有创建新对象,因此$myObj
只是“print”语句(或1)的返回代码。
您需要bless
某些内容并将其返回。
sub new {
my ( $class ) = @_;
print "Calling Constructor\n";
my $self = {};
bless $self, $class;
return $self;
}
那样$myObj
实际上是一个对象,而不仅仅是一个返回码:)