perlevalwarningscarp

How can I change some specific carps into croaks in Perl?


I tried to catch a carp-warning:

 carp "$start is > $end" if (warnings::enabled()); ) 

with eval {} but it didn't work, so I looked in the eval documentation and I discovered, that eval catches only syntax-errors, run-time-errors or executed die-statements.

How could I catch a carp warning?

#!/usr/bin/env perl
use warnings;
use strict;
use 5.012;
use List::Util qw(max min);
use Number::Range;

my @array;
my $max = 20;
print "Input (max $max): ";
my $in = <>;

$in =~ s/\s+//g;
$in =~ s/(?<=\d)-/../g;

eval {
    my $range = new Number::Range( $in );
    @array = sort { $a <=> $b } $range->range;
};
if ( $@ =~ /\d+ is > \d+/ ) { die $@ }; # catch the carp-warning doesn't work 

die "Input greater than $max not allowed $!" if defined $max and max( @array ) > $max;
die "Input '0' or less not allowed $!" if min( @array ) < 1;
say "@array";

Solution

  • Based on your comments, my understanding is that you would like to make carp into a fatal warning.

    If it is acceptable to make all carp warnings in your target package into fatal errors you can monkey-patch carp.

    Carping Package:

    package Foo;
    use Carp;
    
    sub annoying_sub {
        carp "Whine whine whine";
    }
    

    Main program:

    use Foo;
    
    *Foo::carp = \&Foo::croak;
    
    Foo::annoying_sub();
    

    If you want to limit the monkey patch to a dynamic scope, you can use local:

    use Foo;
    
    Foo::annoying_sub();  # non-fatal
    
    {   local *Foo::carp = \&Foo::croak;
        Foo::annoying_sub();  # Fatal
    }