Reputation: 2675
Why does this statement,
if (! $ssh_options{user}) {
delete $ssh_options{user};
}
return true, but this statement
if ($ssh_options{user} eq 'undef') {
delete $ssh_options{user};
}
give me the error,
Use of uninitialized value $ssh_options{"user"} in string eq at analyze.pl line 230.
I thought you always had to have something for perl to compare the value of the variable being compared.
** Update **
@ Quick Joe Smith
I cannot base my comparison on whether the hash keys exist or not because the values for this hash
sub ssh_connect {
my $host = shift;
my %ssh_options = (
port => shift,
user => shift,
password => shift
);
Come from this function which calls the sub routine
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);
}
Upvotes: 0
Views: 163
Reputation: 13942
With Perl, undefined evaluates to false in Boolean context. So your first test 'works' as you expect. However, it might introduce a bug if zero or an empty string is a legitimate value for $ssh_options{user}
to hold, if you don't wish to treat that the same as undef. That's because your first test doesn't differentiate between false as a value, and false as undefined. As far as Perl's Boolean evaluation goes, all of the following are "false": 0
, ''
(empty string), undef
, or an empty list.
Your second snippet of code fails because undef
should be a bareword, not a quoted string. 'undef' as a quoted string IS a value, which would actually evaluate to 'true' in Boolean tests. Because you're comparing an actual value to your hash element, Perl warns you that you're comparing something to an undefined value. In this case, the undefined value is $ssh_options{user}
. It's actually good that Perl is warning you; it's given you a clue as to what you're doing wrong.
If you really want to test whether $ssh_options{user} is defined, use the defined() function. If you want to test whether $ssh_options{user} exists, use the exists() function.
Upvotes: 0
Reputation: 8222
Use exists
for checking hash keys.
if (exists $ssh_options{user}) {
...
}
However, in your case, it seems as though you're checking for existing keys whose values may be undefined, in which case:
if (defined $ssh_options{user}) {
...
}
The above may be what you want.
As a sidenote, checking to see if the value of any variable is defined in the way you described:
if ($something eq 'undef') {
...
}
Is wrong. You're checking to see if the variable contains the string "undef". What you need in those situations is:
unless (defined $something) {
...
}
Upvotes: 2
Reputation: 40142
Perl hash slots have a number of ways they can be false. If the key has never been filled, the exists
function will return false. If the key exists but contains an undefined value, exists
will be true but the defined
function will return false. In normal boolean context, as given by an if
statement, a hash key that was never filled, or is undefined, ''
, 0
or anything that reduces to those will be false.
From your update, it sounds like what you want is to use defined
delete $ssh_options{user} unless defined $ssh_options{user};
Upvotes: 2
Reputation: 32576
But if $ssh_options{"user"}
is uninitialized then it it doesn't have a value to compare to.
Upvotes: 1