简体   繁体   中英

Can't locate object method “say_hello” via package “1”

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM