Perl compiler? error

F

fatted

Lets say a friend of mine :) wrote code which had a bad error in it:

#!/usr/bin/perl
use warnings;
use strict;

my $words = ["a", "b", "c"];
my $num = 612;

if($num == 1)
{
print "moo\n";
}
elsif (map($_->[0] =~ /\d{6}/, @$words))
{
print "Don't give up day job\n";
}

When run this gives the error:
Can't use string ("a") as an ARRAY ref while "strict refs" in use at
../test.pl line 8.
After about 1/2 hour of head banging, the problem (which was
originally in a much larger program) was finally discovered. The code
problem wasn't on line 8 :). I have fixed that and slapped my "friend"
around the face for stupidity.

However this leads to my real question:
Is the error message above, an error in the compiler? For instance if
the close bracket of an elsif is forgotton, you get an error on the
line where the close bracket was left out. *Not* on the line where the
start of the IF THEN ELSE syntax began.

e.g. if I fixed line 8 to (oops left out close bracket for elsif):

elsif (map(/\d{6}/, @$words)

Error message is:

syntax error at ./test.pl line 14, near ")
{"
Execution of ./test.pl aborted due to compilation errors.
 
J

James E Keenan

Lets say a friend of mine :) wrote code which had a bad error in it:

#!/usr/bin/perl
use warnings;
use strict;

my $words = ["a", "b", "c"];
my $num = 612;

if($num == 1)
{
print "moo\n";
}
elsif (map($_->[0] =~ /\d{6}/, @$words))
{
print "Don't give up day job\n";
}

When run this gives the error:
Can't use string ("a") as an ARRAY ref while "strict refs" in use at
./test.pl line 8.
After about 1/2 hour of head banging, the problem (which was
originally in a much larger program) was finally discovered. The code
problem wasn't on line 8 :). I have fixed that and slapped my "friend"
around the face for stupidity.

However this leads to my real question:
Is the error message above, an error in the compiler? For instance if
the close bracket of an elsif is forgotton, you get an error on the
line where the close bracket was left out. *Not* on the line where the
start of the IF THEN ELSE syntax began.
There's no compiler error here, but I think you may have a conceptual
error. The 'elsif' clause establishes a Boolean context, i.e., either
a 'true' or 'false' (in Perl's terms) is the only acceptable answer.
Boolean context should be thought of as a subset of scalar context.
'map', however, generates a list by performing an operation on each
element of a source list. Hence, 'map' normally establishes a list
context. However, since that 'map' is itself within the
Boolean/scalar context established by 'elsif', it will impose a scalar
context, i.e., it will ask how many items are in the resulting list.
If there is a nonzero number of items in the source list, the 'elsif'
will register as true.

Now, are you sure that that's what you were aiming for with this code?
(In short, I'm puzzled by your use of 'map' inside an 'elsif'
condition.)

Jim Keenan
 
J

James E Keenan

Jeff 'japhy' Pinyan said:
You're not answering the question, though. The OP is curious why the
error is said to stem from line 8, when the expression causing the error
is on line 12. This is because of the way Perl compiles the if-else block
internally.
True. I was posting from Google, so I had to guess as to whether other
responses had been written but not yet posted. My hunch was that someone
would have made the point you did (Brian did, albeit in less specific terms
than you), so I felt free to raise another point about the OP's code.
Thanks.
 
F

fatted

Lets say a friend of mine :) wrote code which had a bad error in it:

#!/usr/bin/perl
use warnings;
use strict;

my $words = ["a", "b", "c"];
my $num = 612;

if($num == 1)
{
print "moo\n";
}
elsif (map($_->[0] =~ /\d{6}/, @$words))
{
print "Don't give up day job\n";
}

When run this gives the error:
Can't use string ("a") as an ARRAY ref while "strict refs" in use at
./test.pl line 8.
After about 1/2 hour of head banging, the problem (which was
originally in a much larger program) was finally discovered. The code
problem wasn't on line 8 :). I have fixed that and slapped my "friend"
around the face for stupidity.

However this leads to my real question:
Is the error message above, an error in the compiler? For instance if
the close bracket of an elsif is forgotton, you get an error on the
line where the close bracket was left out. *Not* on the line where the
start of the IF THEN ELSE syntax began.
There's no compiler error here, but I think you may have a conceptual
error. The 'elsif' clause establishes a Boolean context, i.e., either
a 'true' or 'false' (in Perl's terms) is the only acceptable answer.
Boolean context should be thought of as a subset of scalar context.
'map', however, generates a list by performing an operation on each
element of a source list. Hence, 'map' normally establishes a list
context. However, since that 'map' is itself within the
Boolean/scalar context established by 'elsif', it will impose a scalar
context, i.e., it will ask how many items are in the resulting list.
If there is a nonzero number of items in the source list, the 'elsif'
will register as true.

Now, are you sure that that's what you were aiming for with this code?
(In short, I'm puzzled by your use of 'map' inside an 'elsif'
condition.)

Jim Keenan

I'm comparing each value from the list stored in the array (reference)
to see if it matches the regular expression. If it matches , the
return value of map will be greater than 0, which will be evaluated by
elsif as true and run the code in the elsif block. Seems like a
perfectly good idea to me :)
My coding problem occured, because earlier in my script the value I
wanted to compare against a reg exp, was stored in an array reference
of array references; this doesn't work half as well when trying to
compare against just an array reference:) Unfortunately I did a copy
paste, turned my brain off, and was thrown by the runtime error.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top