(lack of) Helpfulness of Perl error messages.

J

Justin C

As some of you are probably aware I often have difficulty with Perl and
I ask for help here usually about once a month. I try to help myself
where I can, and sometimes, when I'm preparing a minimal example for
posting here, I find the solution to my problem. That's just happened
again, but only due to an error message I received from my text editor
and not Perl directly.

I'm a Mac user, and code using TextMate <URL:http://macromates.com/>, it
has the ability to run code, I don't know how it does it, though, and
it's error message gave me the clue to the solution of my problem. The
error message on my Debian box was non-helpful.

What is likely to be the cause of the non-helpful error message? Is the
version of Perl on my Mac likely more recent - I've just checked and on
my Debian box it's 5.10.0, while on the Mac it's 5.8.8. Does TextMate
have a built in Perl interpreter that gives better error messages?

The error I saw on Debian:
Not a HASH reference at ... line...

The error I saw from TextMate:
Can't coerce array into hash at ... line...

I prepared a minimal code example, so here's the broken code, I'm sure
most of you will know what the problem is at a glance, unfortunately it
wasn't obvious to me, and as there are 3 references to hashes on that line
I didn't know where to start. I erroneously spent quite a while looking
at the part of the line that was fine, just because there was only one
error, and not two - obviously the program halted before checking
further, as it would with an error as opposed to a warning.
e strict;
use warnings;
use Data::Dumper;

my $data = read_in_data();
# print Dumper $data;
foreach my $style ( sort keys %{$data}) {
foreach my $item ( sort { $data->{$style}{$a}{1} cmp $data->{$style}{$b}{1} } keys %{$data->{$style}} ) {
printf("%-20s %-40s %5d\n", $item, @{$data->{$style}{$item}}[0], @{$data->{$style}{$item}}[1]);
}
}

sub read_in_data {
my %data;
while (<DATA>) {
my ($style, $item, $desc, $qty) = split /:/, $_;
$data{$style}{$item} = [$desc, $qty];
}
return \%data;
}


__DATA__
TS:TS/ZEP/HERMIT/D:LED ZEPPELIN hermit TSXL:6
TS:TS/MET/MASTERO/D:METALLICA master of puppets TSXL:5
TS:TS/AC/CLASSIC/B:AC/DC classic red logo TS M:12
TS:TS/MET/MASTERO/C:METALLICA master of puppets TS L:7
BB:BB/MET/MASTERO:METALLICA master of puppets BB Cap:17
BB:BB/AC/LOGO:AC/DC logo BB Cap:10


Justin.
 
R

Randal L. Schwartz

This...
Justin> foreach my $item ( sort { $data->{$style}{$a}{1} cmp $data->{$style}{$b}{1} } keys %{$data->{$style}} ) {

Does not match this...

Justin> $data{$style}{$item} = [$desc, $qty];

which is why you're getting an error. I got suspicious when I saw {1}...
that's a hash element selection, not an array element.

I think you want that to be $data->{$style}{$a}[1] -- note the square
brackets, since you have an array there, not a hash.

"perldoc perlreftut" might help. And we cover this stuff pretty
thoroughly in "Intermediate Perl" (the Alpaca book).

print "Just another Perl hacker,"; # the original
 
J

John Bokma

Justin C said:
foreach my $item ( sort { $data->{$style}{$a}{1} cmp
$data->{$style}{$b}{1

^ you want a [ ] there, since sou assign
to "item" a ref to an array with 2 elements. And that's what the error
you got complained about: you try to treat a ref to an array like it's a
ref to a hash.
sub read_in_data {
my %data;
while (<DATA>) {
my ($style, $item, $desc, $qty) = split /:/, $_;
$data{$style}{$item} = [$desc, $qty];
}
return \%data;
}
 
S

sreservoir

As some of you are probably aware I often have difficulty with Perl and
I ask for help here usually about once a month. I try to help myself
where I can, and sometimes, when I'm preparing a minimal example for
posting here, I find the solution to my problem. That's just happened
again, but only due to an error message I received from my text editor
and not Perl directly.

I'm a Mac user, and code using TextMate<URL:http://macromates.com/>, it
has the ability to run code, I don't know how it does it, though, and
it's error message gave me the clue to the solution of my problem. The
error message on my Debian box was non-helpful.

What is likely to be the cause of the non-helpful error message? Is the
version of Perl on my Mac likely more recent - I've just checked and on
my Debian box it's 5.10.0, while on the Mac it's 5.8.8. Does TextMate
have a built in Perl interpreter that gives better error messages?

The error I saw on Debian:
Not a HASH reference at ... line...

The error I saw from TextMate:
Can't coerce array into hash at ... line...

the two messages are equally helpful if you think about it. The second
doesn't even explicitly tell you it's a reference problem. If you need
to, you can use diagnostics; alternatively, grep perldiag.

As for the line references, you can twiddle with your code so that all
of the references aren't on a single line.
 
J

Justin C

the two messages are equally helpful if you think about it. The second
doesn't even explicitly tell you it's a reference problem. If you need
to, you can use diagnostics; alternatively, grep perldiag.

Maybe it's the way my brain (doesn't)work that made be deduce the
problem from that - I suppose the fact that I got two different errors
made me look more closely.

I've not used diagnostics before, and had forgotten of it's existence,
but I'll try and remember to use it in future.
As for the line references, you can twiddle with your code so that all
of the references aren't on a single line.

That's an idea. Thank you for your reply.

Justin.
 
J

Justin C

Quoth Justin C said:
As some of you are probably aware I often have difficulty with Perl and
I ask for help here usually about once a month. I try to help myself
where I can, and sometimes, when I'm preparing a minimal example for
posting here, I find the solution to my problem. That's just happened
again, but only due to an error message I received from my text editor
and not Perl directly.

I'm a Mac user, and code using TextMate <URL:http://macromates.com/>, it
has the ability to run code, I don't know how it does it, though, and
it's error message gave me the clue to the solution of my problem. The
error message on my Debian box was non-helpful.

What is likely to be the cause of the non-helpful error message? Is the
version of Perl on my Mac likely more recent - I've just checked and on
my Debian box it's 5.10.0, while on the Mac it's 5.8.8. Does TextMate
have a built in Perl interpreter that gives better error messages?

You could have answered this easily by running the code from the
command-line on your Mac. (You would have got the same error message as
from TextMate.)
The error I saw on Debian:
Not a HASH reference at ... line...

The error I saw from TextMate:
Can't coerce array into hash at ... line...

The change in error message is due to the different perl versions. The
'Can't coerce...' message comes from the pseudohash code, which was
removed in 5.10, whereas the 'Not a %s reference' is a generic message
for situations where a value holds the wrong kind of ref.

Before you start thinking this change was a bad idea, try running

perl -le'my $x = [{a => 1}, "b"]; print $x->{a}'

on both machines and consider how hard *that* would have been to debug
with the 5.8 behaviour :).

That looks a bit circular, I suppose that that is your point. Under
5.8.8 I get 'b' and under 5.10.0 I get 'Not a HASH reference...', how
$x->{a} gets to be 'b' is the circular part. If you were expecting '1'
then, yes I can see how debugging that would be tough - especially as
"it worked", quite a shortage of warnings!

I have added "use diagnostics" to my "tesp.pl" file, where I put problem
code reduced to it's minimum parts so that I can work through the
problem. I'm in that file often enough that I'll see it and add it to
anything I'm working on that's giving me grief.

Thanks for the reply.

Justin.
 
S

sreservoir

Quoth Justin C said:
As some of you are probably aware I often have difficulty with Perl and
I ask for help here usually about once a month. I try to help myself
where I can, and sometimes, when I'm preparing a minimal example for
posting here, I find the solution to my problem. That's just happened
again, but only due to an error message I received from my text editor
and not Perl directly.

I'm a Mac user, and code using TextMate<URL:http://macromates.com/>, it
has the ability to run code, I don't know how it does it, though, and
it's error message gave me the clue to the solution of my problem. The
error message on my Debian box was non-helpful.

What is likely to be the cause of the non-helpful error message? Is the
version of Perl on my Mac likely more recent - I've just checked and on
my Debian box it's 5.10.0, while on the Mac it's 5.8.8. Does TextMate
have a built in Perl interpreter that gives better error messages?

You could have answered this easily by running the code from the
command-line on your Mac. (You would have got the same error message as
from TextMate.)
The error I saw on Debian:
Not a HASH reference at ... line...

The error I saw from TextMate:
Can't coerce array into hash at ... line...

The change in error message is due to the different perl versions. The
'Can't coerce...' message comes from the pseudohash code, which was
removed in 5.10, whereas the 'Not a %s reference' is a generic message
for situations where a value holds the wrong kind of ref.

Before you start thinking this change was a bad idea, try running

perl -le'my $x = [{a => 1}, "b"]; print $x->{a}'

on both machines and consider how hard *that* would have been to debug
with the 5.8 behaviour :).

That looks a bit circular, I suppose that that is your point. Under
5.8.8 I get 'b' and under 5.10.0 I get 'Not a HASH reference...', how
$x->{a} gets to be 'b' is the circular part. If you were expecting '1'
then, yes I can see how debugging that would be tough - especially as
"it worked", quite a shortage of warnings!

pseudohashes are a sort of magic where
$t = [ { key => index, ... }, ... ];
causes
$t->{key}
to be the same as
$t->[index]

now forget I ever told you that, because it's obsolete and nobody ever
actually used it.
I have added "use diagnostics" to my "tesp.pl" file, where I put problem
code reduced to it's minimum parts so that I can work through the
problem. I'm in that file often enough that I'll see it and add it to
anything I'm working on that's giving me grief.

as long as you remember that diagnostics is meant for testing and such,
not production code.
 

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

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,810
Latest member
Kassie0918

Latest Threads

Top