What is the most elegant way to catch a signal in Perl?

I have 2 lines next to each other in a Perl script that can trigger __WARN__. If the first one throws, then I just want to return from the function and not try to continue.

I know how to set up a handler before both lines so that I can report an error, etc:

local $SIG{__WARN__} = sub {
  my $e = shift;
  # log the error etc.
  return;
};
# possibly warning-resulting line 1
# possibly warning-resulting line 2

But then this happens for both lines. I would prefer it to just catch the first instance and return from the function. But returning in this handler returns a handler, not an external function.

Is there a way to return from a function when processing a signal?

+3
source share
4 answers

, , . - , .

sub wrap_line_1
{
    local $SIG{__WARN__} = ...;
    ...do line 1...
    return ($warning_fired ? 1 : 0);
}

sub wrap_line_2
{
    local $SIG{__WARN__} = ...;
    ...do line 2...
    return;
}


...calling code...
wrap_line_1() and return;
wrap_line_2();
...
+2

, . (, , , XS, !)

; , , .

+1

.

, if eval.

, - , .

:

# We're in the caller now
eval{
    local $SIG{__WARN__} = sub {
        my $e = shift;
        # log the error etc.
        die MyWarnException->new("This is an exception.");
    };

    # Offending statements go here
    do_things();

};
if( $@ && $@->isa('MyWarnException')){
    return;
}
0

You can die () in your handler and catch this in eval, as shown below:

use 5.12.0;

local $SIG{__WARN__} = sub {
  my $e = shift;
  # log the error etc.
  die "$e";
};

func(undef);
func('honk');

sub func {
    my $foo = shift;

    eval {
       my $bar = "a $foo";
       say "$bar";
    };
    if ($@) {
       die $@ unless $@ =~ /^Use of uninitialized value/;
    }
    return;
}

You may, however, want to directly check if a warning may occur and simply return:

sub func {
  my $foo = shift;
  return unless defined($foo);
  ...; # use $foo fine
}
0
source

All Articles