为什么这个陈述会返回true

时间:2011-05-26 04:35:29

标签: perl

为什么这句话,

    if (! $ssh_options{user}) {

    delete $ssh_options{user};

}

返回true,但是这句话

    if ($ssh_options{user} eq 'undef') {

    delete $ssh_options{user};

}

给我错误,

Use of uninitialized value $ssh_options{"user"} in string eq at analyze.pl line 230.

我认为你总是需要perl来比较被比较的变量的值。

**更新**

@ Quick Joe Smith

我无法根据哈希值是否存在进行比较,因为此哈希值

sub ssh_connect {

my $host = shift;

my %ssh_options = (

    port => shift,
    user => shift,
    password => shift

    );

来自调用子例程的函数

        if ((exists $config_file{user}) && (exists $config_file{password})) {

        my $vmware_user = $config_file{user};

        my $vmware_password = $config_file{password};

        ssh_connect($vmware_host, $vmware_port, $vmware_user, $vmware_password);

    } else {

        ssh_connect($vmware_host, $vmware_port);

    }

4 个答案:

答案 0 :(得分:2)

使用exists检查哈希键。

if (exists $ssh_options{user}) {
    ...
}

但是,在您的情况下,似乎您正在检查其值可能未定义的现有密钥,在这种情况下:

if (defined $ssh_options{user}) {
    ...
}

以上可能就是你想要的。


作为旁注,检查是否按照您描述的方式定义任何变量的值:

if ($something eq 'undef') {
    ...
}

错了。您正在检查变量是否包含字符串“undef”。在这些情况下你需要的是:

unless (defined $something) {
    ...
}

答案 1 :(得分:2)

Perl哈希槽有许多方法可以是假的。如果密钥从未填充过,则exists函数将返回false。如果密钥存在但包含未定义的值,exists将为true,但defined函数将返回false。在正常的布尔上下文中,由if语句给出,从未填充或未定义的散列键,''0或任何减少到那些的散列键都将为false。 / p>

从您的更新中,您可能会想要使用defined

delete $ssh_options{user} unless defined $ssh_options{user};

答案 2 :(得分:1)

但如果$ssh_options{"user"}未初始化,那么它没有值可供比较。

答案 3 :(得分:0)

使用Perl,undefined在布尔上下文中的计算结果为false。所以你的第一次测试“有效”,正如你所料。但是,如果您想要将$ssh_options{user}保持为合法值,则可能会引入错误,如果您不希望将其视为与undef相同。那是因为你的第一个测试不区分false作为值,false作为undefined。就Perl的布尔评估而言,以下所有内容均为“false”:0''(空字符串),undef或空列表。

您的第二段代码失败,因为undef应该是一个裸字,而不是一个带引号的字符串。 'undef'作为带引号的字符串是一个值,在布尔测试中实际上会评估为'true'。因为您将实际值与哈希元素进行比较,所以Perl会警告您将某些内容与未定义的值进行比较。在这种情况下,未定义的值为$ssh_options{user}。 Perl警告你真的很好;它给你一个关于你做错了什么的线索。

如果您确实想测试是否定义了$ ssh_options {user},请使用defined()函数。如果要测试$ ssh_options {user}是否存在,请使用exists()函数。