I am writing a Perl pipeline, a script that calls various other programs and manages passing data from one to the other. The script (call it pipeline.pl
) and the various sub-scripts it manages all share a list of common subroutines defined in subroutines.ph
and included via a require subroutines.ph
directive.
One of these is a function whose job is to exit printing an error message (the actual subroutine also does some other jobs, but they're not relevant here; no, I am not reinventing die()
):
## subroutines.ph
sub errorDie
{
my ($errMsg) = @_;
## various other cleanup tasks here
die($errMsg);
}
1;
And, in pipeline.pl
:
#!/usr/bin/perl
require 'subroutines.ph';
errorDie("foo")
Running the script above results in:
foo at subroutines.ph line 5.
Is it possible to have it instead report something like:
foo at pipelines.pl line 4.
So, instead of reporting the line the die()
was found on, it should report the line of the original script where the errorDie
subroutine was called from. I know I can do this by including the line in the $errMsg
variable, but that is fragile and cumbersome. Can this be done automatically? Can a subroutine defined in an external file detect where it was called from?
That's the point of Carp's croak
.
Pkg.pm
:
package Pkg;
use Carp qw( croak );
sub some_func {
my ($cmd, $param) = @_;
$cmd eq 'encode' || $cmd eq 'decode'
or croak("Invalid command \"$cmd\"");
# ...
}
1;
a.pl
:
use Pkg;
Pkg::some_func('foo', 'bar');
Output:
Invalid command "foo" at a.pl line 3.