Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is wrong in this Perl expression?

What's the problem with following. I am getting $attribute not defined error.

if (my $attribute = $Data->{'is_new'} and $attribute eq 'Y') {
}
like image 765
TopCoder Avatar asked Dec 08 '11 05:12

TopCoder


People also ask

What does %s mean in Perl?

Substitution Operator or 's' operator in Perl is used to substitute a text of the string with some pattern specified by the user.

What does $_ mean in Perl?

There is a strange scalar variable called $_ in Perl, which is the default variable, or in other words the topic. In Perl, several functions and operators use this variable as a default, in case no parameter is explicitly used.

What is the meaning of $1 in Perl regex?

$1 equals the text " brown ".

What is =~ in Perl script?

=~ is the Perl binding operator. It's generally used to apply a regular expression to a string; for instance, to test if a string matches a pattern: if ($string =~ m/pattern/) {


2 Answers

You're being too clever. Just do this:

my $attribute = $Data->{'is_new'};

if (defined $attribute && $attribute eq 'Y') { ... }

The problems are twofold:

  • You have an extra ) in your if
  • my in expression context binds very tightly; $attribute is not in lexical scope until the body of the conditional statement that contains it, so the other branch of the and cannot access it. You need to lift it to the containing context, as in my example.
like image 54
bdonlan Avatar answered Oct 08 '22 13:10

bdonlan


use strict; would have found the problem.

$ perl -e'use strict; my $attribute = "..." and $attribute eq "Y";'
Global symbol "$attribute" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.

A my declaration only has an effect on subsequent statements, not the the statement in which the declaration is is located. (Same goes for the our and local declarations.) That means the $attribute that you create with my and to which you assign is a different variable than the $attribute you compare to Y. You want

my $attribute = $Data->{'is_new'};
if ($attribute eq 'Y') { ... }

Now, if $Data->{is_new} doesn't exist or is undefined, $attribute will be undefined, and comparing it to Y will issue a warning. You can avoid this warning as follows:

my $attribute = $Data->{'is_new'};
if (defined($attribute) && $attribute eq 'Y') { ... }

Alternatively: (5.10+)

my $attribute = $Data->{'is_new'};
if (($attribute // '') eq 'Y') { ... }
like image 27
ikegami Avatar answered Oct 08 '22 15:10

ikegami