为什么包例程的@_包含包名,是否传递了params?

时间:2013-07-03 19:28:15

标签: perl

我的基本问题是这个。如果我没有将参数传递给我的软件包 - DbIoFunc的例程OpenIcsDB(),为什么@_中的pacakge名称?

当我没有将参数传递给以下函数时,我期望@_为null,而是参数包含包名。我尝试使用类->::语法进行调用,但没有区别。

我应该测试什么来确定除了以下内容之外是否传递了参数?

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

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

我想知道两件事。为什么包名称是@_的一部分并且是我最好的方法来摆脱包名?

这是电话:

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

这是功能:

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;
}

3 个答案:

答案 0 :(得分:1)

您可能希望将该功能称为DbIoFunc::OpenIcsDb()。使用箭头操作符会做一些对象。

答案 1 :(得分:1)

  

我试过用课程打电话 - &gt;和::语法,没有区别。

有区别。如果您使用::并且未传递任何其他参数,那么@_ 为空。您可以通过在函数顶部插入以下代码来确认这一事实:

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

你真正的问题可能在这里:

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

如果@_为空,则$DBPathLocal将为undeflength(undef)始终为undefundef <= 0始终 true

普罗蒂普:

use warnings;
use strict;

答案 2 :(得分:1)

要做OOP,Perl必须知道包名称或对象的工作引用。如果您使用::调用方法,则可以避免这种情况。

package Foo;

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

package main;

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

请注意,对Foo::bar();的调用不会打印包名称。