I agree, Kent.  Shouldn't it be simple to wrap ok() and is() accordingly,
to simply save-and-restore $! and $@, without going deep into anything?
There's already a working example of how to do that right here.

sub ok {
  my($err, $exception) = ($!, $@);
  # ...
  ($!, $@) = ($err, $exception);
  return $ret;
}

And if ok() accepts a code reference to execute, fine ... same principle,
for whenever you execute the code.  It doesn't seem like it's a lot of
work, though I imagine I am probably missing something.  That said, I
generally do something like you have, except I don't put it in a do(), I
just execute it external to the test function:

  local($@, $!);
  my $ret  = do_something_scary();
  ($error, $exception) = ($!, $@);
  ok($ret);
  is($err, 0);
  is($exception, undef);

It's not as nice, but it's safe.  And if I call it multiple times, I
usually put it in my own wrapper:

  sub my_test {
    local($@, $!);
    my($ref) = @_;
    my $ret  = $ref->();
    ($error, $exception) = ($!, $@);
    ok($ret);
    is($err, 0);
    is($exception, undef);
  }

or whatever.  Again ... it's not ideal, but if I am calling it multiple
times, and I want to check for no errors, even if $@ and $! are protected,
I'd still want to have a separate function ... and then the overhead isn't
a big deal.  So, I guess my point is "whatever."  :-)


On Mon, Jan 11, 2016 at 5:34 PM, Kent Fredric <kentfred...@gmail.com> wrote:

> On 12 January 2016 at 13:53, Chad Granum <exodi...@gmail.com> wrote:
> > $! and $@ are altered by many many things, adding { local ... } around
> all
> > of them is a pain
>
> As much as I agree, and as much as this is a "thing in all perl, so we
> should expect this problem from every module"
>
> If I was to offer a counter example, consider the effort of a `*.t`
> file needing to preserve these things instead.
>
> >     ok(do_something_scary());
> >     is($!, 0, "expected $! val");
> >     is($@, undef, '$@ not changed');
>
> vs
>
> >     my ( $error, $exception );
> >     ok(do {
> >               local $@;
> >               local $!;
> >               my $ret  = do_something_scary());
> >               ( $error, $exception ) = ($!, $@);
> >               $ret
> >     });
> >     is($error, 0, "expected $! val");
> >     is($exception, undef, '$@ not changed);
>
> I'm not sure I'd consider the second of these an "improvement".
>
>
> --
> Kent
>
> KENTNL - https://metacpan.org/author/KENTNL
>

Reply via email to