in reply to Carp: $! vs "$!" in croaking

I guess that's a consequence of $! being localized rather early: You pass $!... which is available as an alias in Carp::croak. By localizing $!, it also masks the value you passed to the subroutine.

Demo:

use 5.032; sub foo { local $!; my $err = shift; say "foo found: '$err'"; } sub bar { my $err = shift; local $!; say "bar found: '$err'"; } open (my $foo, '<', 'doesnotexist.dat') or foo($!); open (my $bar, '<', 'doesnotexist.dat') or bar($!);

Output:

foo found: '' bar found: 'No such file or directory'

In foo, your $! gets clobbered by localizing. If you quote it, you've already copied the string value of $!, so it doesn't matter that it gets localized afterwards.