$@でエラーを返す件、自己レス。evalで呼ぶときには
evalが正常時に$@を初期化してしまうので、呼び側で配慮が必要ですね。

sub hoge {$@ = 'hoge'; return}
eval '&hoge(); $gERROR = $@';
$@ and die;
print $gERROR if $gERROR;