in reply to Spot the bug!

Red herrings, and a wrong conclusion. It has nothing to do with either @_, or eval. It all has to do with Perl using pass by alias.
#!/usr/bin/perl use strict; use warnings; my $n; sub foo { $n = 0; return $_[0]; } print foo(3), "\n"; $n = 3; print foo($n), "\n"; __END__ 3 0
$_[0] is just a different name for $n, which is being modified in foo, just like your function uses eval, which sets $@.