octopusgrabbus
octopusgrabbus

Reputation: 10695

Why does package routine's @_ contain Package name, whether params passed or not?

My basic question is this. If I pass no parameters to my package -- DbIoFunc's routine OpenIcsDB() why is the pacakge name in @_?

I am expecting @_ to be null when I pass no parameters to the following function, but instead the parameter contains the package name. I have tried calling with class -> and :: syntax, and there is no difference.

What should I test to determine if no parameter was passed other than the following?

my ($Temp, $DBPathLocal) = @_; 

if(!defined $DBPathLocal)
{
    $DBPathLocal = DBDEV;
}

I'm wondering two things. Why is the package name part of @_ and is what I've done the best way to get rid of the package name?

Here is the call:

my ($DBHand);
$DBHand = DbIoFunc->OpenIcsDb();

Here is the function:

sub OpenIcsDb
#
# DB Path Constant DBPROD or DBDEV.
#
{
    # Path passed in, either DBPROD or DBDEV
    my ($DBPathLocal); 

    my ($DBSuffix);
    my ($DBHand);      # ICS database handle

    $DBPathLocal = shift;

    #
    # Make sure the database path exists.
    #

    if (length($DBPathLocal) <= 0)
    {
        if (!$Debugging)
        {
            $DBPathLocal= DBPROD;
        }
        else
        {
            $DBPathLocal = DBDEV;
        }
    }
    else
    {
        $DBPathLocal = DBDEV;
    }

    my $DBSuffix = DBSUFFIX;

    $! = 2;
    die("Can't find database directory ".$DBPathLocal.".".$DBSuffix)
    unless ((-e $DBPathLocal.".".$DBSuffix) && (-d $DBPathLocal.".".$DBSuffix));
    #
    # See if we can connect to the ICS database.  We can't proceed without it.
    #
    $DBHand = DBI->connect("dbi:Informix:".$DBPathLocal, "", "")
        or die("Can't connect to the ICS database ".$DBPathLocal);

    return $DBHand;
}

Upvotes: 0

Views: 102

Answers (3)

shawnhcorey
shawnhcorey

Reputation: 3601

To do OOP, Perl has to know the package name or the object's reference to work. If you use the :: call method, you avoid this.

package Foo;

sub bar {
  print "@_\n";
}

package main;

Foo->bar();
Foo::bar();
bar Foo();

Note that the call to Foo::bar(); does not print the package name.

Upvotes: 1

Oktalist
Oktalist

Reputation: 14714

I have tried calling with class -> and :: syntax, and there is no difference.

There is a difference. If you use :: and pass no other parameters then @_ will be empty. You can confirm this fact by inserting the following code at the top of the function:

print '@_ contains ' . scalar(@_) . " elements\n";

Your real problem might be here:

$DBPathLocal = shift;
if (length($DBPathLocal) <= 0)

If @_ is empty then $DBPathLocal will be undef. And length(undef) is always undef. And undef <= 0 is always true.

Protip:

use warnings;
use strict;

Upvotes: 1

AKHolland
AKHolland

Reputation: 4445

You probably want to call the function as DbIoFunc::OpenIcsDb(). Using the arrow operator does some object stuff.

Upvotes: 1

Related Questions