Transparently handle first argument to Perl Package subroutines

It’s always baffled me that Perl subroutines behave differently when called from inside the Package vs. outside.

The use case may be obvious but I’ll say it: you write a small utility routine that you want to call as $pack->func(1); and from within the Package as func(1);;

The problem of course is that when called as $pack->func(1); the first arg will the object itself and when called as func(1); from within the package the first arg will be “1.”

There’s a very simple solution:
shift if ((ref $_[0]) eq __PACKAGE__);

Here’s a simple example:


#!/usr/bin/perl -w
#
package Pack;

sub new {
    my $c = shift;

    my $self = {};
    bless $self, $c;
    return $self;
}

sub func {
    shift if ((ref $_[0]) eq __PACKAGE__);
    my $a = shift;

    print "passed in: $a\n";
}

sub call_func {
    print "calling func from inside ", __PACKAGE__, ":\n";
    func(2);
}
1;

my $p = new Pack;

print "calling func from main:\n";
$p->func(1);

$p->call_func();

Try commenting the “shift” line in sub func() and see how it behaves differently.

This entry was posted in Perl, Programming on by .

About morgan

Morgan is a freelance IT consultant living in Philadelphia. He lives with his girlfriend in an old house in Fishtown that they may never finish renovating. His focus is enterprise Messaging (think email) and Directory. Many of his customers are education, school districts and Universities. He also gets involved with most aspects of enterprise Linux and UNIX (mostly Solaris) administration, Perl, hopefully Ruby, PHP, some Java and C programming. He holds a romantic attachment to software development though he spends most of his time making software work rather than making software. He rides motorcycles both on and off the track, reads literature with vague thoughts of giving up IT to teach English literature.

Leave a Reply

Your email address will not be published. Required fields are marked *