P
Paul Lalli
I've been staring at this and playing with variations for over an hour
now. Can someone help me out? My goal is to be able to use croak()
from within a subroutine that is called by the &wanted subroutine
which is passed to File::Find::find(). I want the error message
printed as a result of this croak() to list the line number of the
call to the final subroutine. Here is a short-but-complete script to
demonstrate the problem I'm having:
#!/usr/bin/perl
use strict;
use warnings;
use Carp;
use File::Find;
die "Usage: $0 [croak|confess] [level]\n" unless @ARGV == 2;
my ($which, $carplevel) = @ARGV;
sub err {
$Carp::CarpLevel = $carplevel;
if ($which eq 'croak') {
croak "You did something bad!"; #line 12
} else {
confess "You did something bad!"; #line 14
}
}
sub wanted {
err(); #line 19
}
find(\&wanted, '.'); #line 22
__END__
So, find() is calling wanted() which is calling err() which is calling
croak(). What I want is an error message saying:
"You did something bad! at ff_carp.pl line 19". However:
$ ./ff_carp.pl croak 0
You did something bad! at /opt2/Perl5_8_4/lib/perl5/5.8.4/File/Find.pm
line 810
Calling croak with a CarpLevel of 0 shows me where in File::Find the
wanted() subroutine is being called.
$ ./ff_carp.pl croak 1
You did something bad! at ./ff_carp.pl line 22
But if I call croak with a CarpLevel of 1, I instead get where in my
main file find() is being called.
So instead I tried looking at the whole stack trace, to see what's
going wrong. I tried calling confess() with a CarpLevel of 0:
$ ./ff_carp.pl confess 0
You did something bad! at ./ff_carp.pl line 14
main::err() called at ./ff_carp.pl line 19
main::wanted() called at /opt2/Perl5_8_4/lib/perl5/5.8.4/File/
Find.pm line 810
File::Find::_find_dir('HASH(0x13e82c)', ., 2) called at /opt2/
Perl5_8_4/lib/perl5/5.8.4/File/Find.pm line 690
File::Find::_find_opt('HASH(0x13e82c)', .) called at /opt2/
Perl5_8_4/lib/perl5/5.8.4/File/Find.pm line 1193
File::Find::find('CODE(0x1b66d0)', .) called at ./ff_carp.pl
line 22
Now this is exactly what I'd expect. It's telling me the actual
confess was called on line 14, inside the err() function that was
called on line 19, inside the wanted() function that was called within
File::Find.pm. Exactly. And furthermore, if I skip a level by
setting CarpLevel to 1:
$ ./ff_carp.pl confess 1
You did something bad! at ./ff_carp.pl line 19
main::wanted() called at /opt2/Perl5_8_4/lib/perl5/5.8.4/File/
Find.pm line 810
File::Find::_find_dir('HASH(0x13e82c)', ., 2) called at /opt2/
Perl5_8_4/lib/perl5/5.8.4/File/Find.pm line 690
File::Find::_find_opt('HASH(0x13e82c)', .) called at /opt2/
Perl5_8_4/lib/perl5/5.8.4/File/Find.pm line 1193
File::Find::find('CODE(0x1b66d0)', .) called at ./ff_carp.pl
line 22
Again, Exactly what I expect. I skipped a level, so the first level
being printed is the source of the err() call, line 19.
Now - how do I get croak() to behave the same way? I don't want to
print the entire stack trace, I just want it to tell me that the
subroutine was called from line 19, like confess() does when I skip a
level.
Thank you for any insight you can provide,
Paul Lalli
now. Can someone help me out? My goal is to be able to use croak()
from within a subroutine that is called by the &wanted subroutine
which is passed to File::Find::find(). I want the error message
printed as a result of this croak() to list the line number of the
call to the final subroutine. Here is a short-but-complete script to
demonstrate the problem I'm having:
#!/usr/bin/perl
use strict;
use warnings;
use Carp;
use File::Find;
die "Usage: $0 [croak|confess] [level]\n" unless @ARGV == 2;
my ($which, $carplevel) = @ARGV;
sub err {
$Carp::CarpLevel = $carplevel;
if ($which eq 'croak') {
croak "You did something bad!"; #line 12
} else {
confess "You did something bad!"; #line 14
}
}
sub wanted {
err(); #line 19
}
find(\&wanted, '.'); #line 22
__END__
So, find() is calling wanted() which is calling err() which is calling
croak(). What I want is an error message saying:
"You did something bad! at ff_carp.pl line 19". However:
$ ./ff_carp.pl croak 0
You did something bad! at /opt2/Perl5_8_4/lib/perl5/5.8.4/File/Find.pm
line 810
Calling croak with a CarpLevel of 0 shows me where in File::Find the
wanted() subroutine is being called.
$ ./ff_carp.pl croak 1
You did something bad! at ./ff_carp.pl line 22
But if I call croak with a CarpLevel of 1, I instead get where in my
main file find() is being called.
So instead I tried looking at the whole stack trace, to see what's
going wrong. I tried calling confess() with a CarpLevel of 0:
$ ./ff_carp.pl confess 0
You did something bad! at ./ff_carp.pl line 14
main::err() called at ./ff_carp.pl line 19
main::wanted() called at /opt2/Perl5_8_4/lib/perl5/5.8.4/File/
Find.pm line 810
File::Find::_find_dir('HASH(0x13e82c)', ., 2) called at /opt2/
Perl5_8_4/lib/perl5/5.8.4/File/Find.pm line 690
File::Find::_find_opt('HASH(0x13e82c)', .) called at /opt2/
Perl5_8_4/lib/perl5/5.8.4/File/Find.pm line 1193
File::Find::find('CODE(0x1b66d0)', .) called at ./ff_carp.pl
line 22
Now this is exactly what I'd expect. It's telling me the actual
confess was called on line 14, inside the err() function that was
called on line 19, inside the wanted() function that was called within
File::Find.pm. Exactly. And furthermore, if I skip a level by
setting CarpLevel to 1:
$ ./ff_carp.pl confess 1
You did something bad! at ./ff_carp.pl line 19
main::wanted() called at /opt2/Perl5_8_4/lib/perl5/5.8.4/File/
Find.pm line 810
File::Find::_find_dir('HASH(0x13e82c)', ., 2) called at /opt2/
Perl5_8_4/lib/perl5/5.8.4/File/Find.pm line 690
File::Find::_find_opt('HASH(0x13e82c)', .) called at /opt2/
Perl5_8_4/lib/perl5/5.8.4/File/Find.pm line 1193
File::Find::find('CODE(0x1b66d0)', .) called at ./ff_carp.pl
line 22
Again, Exactly what I expect. I skipped a level, so the first level
being printed is the source of the err() call, line 19.
Now - how do I get croak() to behave the same way? I don't want to
print the entire stack trace, I just want it to tell me that the
subroutine was called from line 19, like confess() does when I skip a
level.
Thank you for any insight you can provide,
Paul Lalli