Proposal: Using the debugger or 'diagnostics' should preload Carp::Heavy

W

Wolfram Humann

When perl runs using the debugger or if you "use diagnostics", (some?)
compile time errors will be hidden by an error from Carp::Heavy.

Example:
perl -E'use strict; $num = 17'
Global symbol "$num" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.
perl -E'use diagnostics "-t"; use strict; $num = 17'
BEGIN not safe after errors--compilation aborted at /home/wolframh/
perl/perl5.10.1/lib/5.10.1/Carp/Heavy.pm line 11.
Compilation failed in require at /home/wolframh/perl/perl5.10.1/lib/
5.10.1/Carp.pm line 33.
perl -E'use Carp::Heavy; use diagnostics "-t"; use strict; $num = 17'
Uncaught exception from user code:
Global symbol "$num" requires explicit package name at -e line
1.
Execution of -e aborted due to compilation errors.
at -e line 1

In the first example, the problem with $num is reported correctly.
The second example reports an error in Carp::Heavy -- even though the
problem is still $num. This can be verified by adding 'my' before
$num: the error message goes away. The same misguiding error message
happens with
perl -d -E'use strict; $num = 12'
This effect has been reported by many people at various places. Use a
websearch for '"failed in require" "carp heavy"' to see some. The
replies often tell pepole how to correct their code and make the error
message go away but it would be better if they got a decent error
message in the first place so they can fix their bugs without external
help :)
The most helpful reply I found was from Ilya Zakharevich at
http://groups.google.com/group/comp.lang.perl.misc/msg/efa2d9659eb48e90.
This told me that the error message from Carp::Heavy goes away and the
*real* error message reappears, when Carp is fully loaded (i.e.
ncluding Carp::Heavy) before the error occurs. The third example shows
that this is indeed the case.

While in "normal" code it makes sense to defer loading Carp::Heavy
until it's really required (e.g. in production code, the probabilty of
an error occurring that needs to reported should be low), this is not
the case with the debugger or "use diagnostics":
a) the probability is high that Carp::Heavy will be loaded anyway is
high
b) in such a "bug hunting" scenario, the annoyance of a misleading
error message by far outweighs a few extra milliseconds of startup
time.

I would therefore propose, that the debugger and "use diagostics" do a
"use Carp::Heavy" internally. What do you think?
Wolfram
 
I

Ilya Zakharevich

I would therefore propose, that the debugger and "use diagostics" do a
"use Carp::Heavy" internally. What do you think?

Essentially, this would debug different code than the original one. A
no-no-no.

A better thing would be to catch in Carp the errors in loading
Carp::Heavy, and emit the advice to preload Carp::Heavy.

Hope this helps,
Ilya
 
W

Wolfram Humann

Essentially, this would debug different code than the original one.  A
no-no-no.

A better thing would be to catch in Carp the errors in loading
Carp::Heavy, and emit the advice to preload Carp::Heavy.

If I understand you correctly, the reasoning is "if we fix this in the
debugger and dignostics.pm, then the next one trying to use Carp
during compilation phase will run into the same problem again". So
yes, something in Carp.pm should be fixed. Would that be simply to
replace
eval { require Carp::Heavy };
return $@ if $@;
with
eval { require Carp::Heavy };
return $@ . $extra_message if $@;
(but I don't have a really good idea how to word $extra_message)?

Once that is done I would still be in favour of a "use Carp::Heavy" in
diagonstics.pm. Otherwise I would need to "use Carp::Heavy" before
every "use diagnostics" as a standard idiom, which obviously conflicts
with lazyness :)

Wolfram
 
I

Ilya Zakharevich

If I understand you correctly, the reasoning is "if we fix this in the
debugger and dignostics.pm, then the next one trying to use Carp
during compilation phase will run into the same problem again". So
yes, something in Carp.pm should be fixed. Would that be simply to
replace
eval { require Carp::Heavy };
return $@ if $@;
with
eval { require Carp::Heavy };
return $@ . $extra_message if $@;

More or less; as far as I noticed, the $@ is always the same in teh
case of failure; and $^S has a special value. I would probably check
for these conditions...
(but I don't have a really good idea how to word $extra_message)?

Postponed load of Carp::Heavy failed
(load was requested during unappropriate compilation phase):
$@;
One may want to preload Carp::Heavy by -MCarp::Heavy or `use Carp::Heavy'.

Ilya
 

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
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top