perlargumentsundefinedselfperl5.8

Variable $self in Perl is undefined


I am writing a Perl script which makes use of a Perl module, Module.pm.

Module.pm is like so:

package Module;
use strict;
use warnings;

sub getInfo {

    my $self = shift;
    #my $var = shift;

    if (!$self)
    {
        my $errmsg = "My ERROR MESSAGE";
        return [1, $errmsg];
    }

    return [1, $self];
}1;

And I am calling it like so:

use Module

my $result = Module::getInfo();

But I keep getting a FATAL ERROR (at Module.pm) undefined object at line #. Why is that?

Furthermore if I remove the first comment in the getInfo() subroutine and add another argument to my calling line then I don't get the same error. Why? I thought I didn't have to send the Module object as an argument to call the subroutine?

This is a Linux server using Perl 5.8.8.


Solution

  • When you call a member function of a package, the package name is passed as an implicit first argument only if you use the -> notation. This is known as a "method call"; it can also search the class hierarchy to determine what to call. If the prefix is a class name, the implicit first argument is the name of the package, as a string. If the prefix is an object reference, the implicit first argument is that object reference.

    With the :: notation, it's an ordinary subroutine call with no implicit first argument.

    For example:

    % cat foo.pl
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use v5.10;
    
    package M {
        sub getInfo {
            my($self) = shift;
            say "\$self = ", ($self // 'undef');
        }
    
        1;
    };
    
    M::getInfo();
    M->getInfo();
    % ./foo.pl
    $self = undef
    $self = M
    % 
    

    Change Module::getInfo() to Module->getInfo().

    This is discussed in more detail in the Perl documentation:

    Older versions of Perl had perltoot and perlboot tutorials; they've been superseded by perlootut as of 5.20 (or possibly earlier).