use strict; 
use warnings;  

sub eval_func {
  eval { 
  return 1; 
 if ($@) {  
  return 0; 

my $res = eval_func; 
printf "%s\n", $res; # $res is blank!!!

ハマった。perldoc -f evalしてみると...

In both forms, the value returned is the value of the last expression evaluated inside the mini-program; a return statement may be also used, just as with subroutines.

と書かれてますねぃ。 evalブロックでのreturnは evalブロックの戻り値になるので注意。知らずに書くと思わぬバグをつくりこみそう。