Reputation: 19967
I am trying to run a script on a .csv file that converts sizes in feet and inches to separate columns of width in inches and height in inches.
It works fine when not using strict mode, but returns a warning message when use warnings;
is set.
My problem occurs here:
if ($data[$index_num] =~ /(\d+)'( (\d+)'')? x (\d+)'( (\d+)'')?/) {
my $width = $1*12+$3;
my $height = $4*12+$6;
...
}
Since sometimes the size could be 5' x 8' the special variables $3 and $6 do not exist.
All possible size formats are as follows:
The warning I receive is:
Use of uninitialized value $6 in addition (+) at script.pl line 47, line 567.
This is happening in either case 3 or 4 where the inches are missing on either the width or height.
How can I check to see if either $3 or $6 exists before trying to use them?
Upvotes: 1
Views: 398
Reputation: 385657
First, let's get rid of useless captures:
/(\d+)'(?: (\d+)'')? x (\d+)'(?: (\d+)'')?/
Captures that didn't match are set to undef
, so you can used defined
or //
.
my $width = $1 * 12 + ($2 // 0);
my $height = $3 * 12 + ($4 // 0);
//
was introduced in Perl 5.10. For backwards compatibility, you can use the following:
my $width = $1 * 12 + ($2 || 0);
my $height = $3 * 12 + ($4 || 0);
The second version uses zero when $2
(or $4
) is false (undef, zero, or empty string) rather than undef, but that's perfectly fine here.
Upvotes: 10
Reputation: 10864
If you just want to test for a number AND you're happy to calculate a result when there is no match then you could say:
if ($data[$index_num] =~ /(\d+)\'( (\d+)\'\')? x (\d+)\'( (\d+)\'\')?/) {
my $width = ( $1 || 0 ) * 12 + ( $3 || 0 );
my $height = ( $4 || 0 ) * 12 + ( $6 || 0 );
...
}
Why does this work? Because if, say, $1
is undefined, then ($1 || 0)
returns the right-hand side, or 0
. Likewise if $1
is zero then the left-hand-side of the OR condition will also fail but return 0
nonetheless. And if $1
is non-zero and defined then the left-hand-side will be returned ($1
).
If you're going to use the ||
technique then ensure you put the left-hand and right-hand sides inside parenthesis to avoid operator-precedence side effects.
Upvotes: 3
Reputation: 23729
You can use defined
function:
my $height;
if(defined($6))
{
$height = $4*12+$6;
}
else
{
$height = $4*12;
}
Upvotes: 12