I just started to learn Perl. When I moved to object orientation I am getting an error like
Can't locate object method "say_hello" via package "1" (perhaps you forgot to load "1"?) at ./main.pl line 8.
I googled a lot for a solution. Got some similar issues like this . My understanding is it's not a general issue.
Here is my class
# MyModule.pm
package MyModule;
use strict;
use warnings;
sub new {
print "calling constructor\n";
}
sub say_hello {
print "Hello from MyModule\n";
}
1;
Here is my test script
# main.pl
#!/usr/bin/perl -w
use strict;
use warnings;
use MyModule;
my $myObj = new MyModule();
$myObj->say_hello();
The code is working perfectly if remove last line from main.pl
Your constructor new
needs to return a blessed reference to the data structure you are using to contain the object's information. You have no relevant data here, but you still need to return something
bless
associates the data with a specific package. In this case, your object should be blessed into MyModule
, so that perl knows to look for MyModule::say_hello
when it sees a method call like $myObj->say_hello()
Your current constructor returns the value returned by the print
statement, which is 1
if it succeeded, as it almost certainly does. That is why you see the "1"
in the error message
Can't locate object method "say_hello" via package "1" (perhaps you forgot to load "1"?) at ./main.pl line 8.
The most common container for an object's data is a hash , so you need to change new
to this
sub new {
print "calling constructor\n";
my $self = { };
bless $self, 'MyModule';
return $self;
}
and then your program will work as it should. It creates an anonymous hash and assigns it to the $self
variable, then blesses and returns it
Note that this can be made much more concise:
Without a return
statement, a subroutine will return the value of the most recently executed statement
By default, bless
will bless the data into the current package
There is no need to store the reference in a variable before blessing it
So the same effect may be achieved by writing
sub new {
print "calling constructor\n";
bless { };
}
Note also that your call
my $myObj = new MyModule()
is less than ideal. It is called indirect object notation and can be ambiguous. It is better to always use a direct method reference, such as
my $myObj = MyModule->new()
so as to disambiguate the call
You're not creating a new object, and thus $myObj
is just the return code of the "print" statement (or 1).
You need to bless
something and return it.
sub new {
my ( $class ) = @_;
print "Calling Constructor\n";
my $self = {};
bless $self, $class;
return $self;
}
That way $myObj
will actually be an object, not just a return code :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.