How can I get the line number and coderef file name?

Let's say I have some bit of library code, not quite unlike this:

sub try_hard {
  my $sub = shift;
  my $tries = 3;
  my @failures;
  while($tries--) {
    eval {
      my $success = $sub->(@_) or die "sub returned false value";
      1;
    } or do {
      push @failures, $@;
    }
  }
  die "try_hard: failed 3 times: $failures[-1]"
}

This may fail:

try_hard: failed 3 times: sub returned false value at BadUtils.pm line 7 

... which is not useful if you are calling try_hardin several places, and you do not know which call was called with an error.

If I could get the source $sub, I could change this stamp to:

  my $success = $sub->(@_) or die "sub returned false value at $file line $lineno
";

and the library will be a bit DWIMmer. Can this be achieved?

+4
source share
2 answers

Use croakinstead die. You can force backtrace by running a script using

perl -MCarp::Always script

or

PERL5OPT=-MCarp::Always script
+3
source

caller :

my ($package, $filename, $line, $subroutine) = caller(1);
my $success = $sub->(@_) or die "sub returned false value at ".
    "$filename line $line in sub $subroutine in package $package";

Also see: How to get the call stack list in Perl?

+2
source

Source: https://habr.com/ru/post/1695347/


All Articles