遠藤です。

require がパース時に失敗すると以下のように通常の例外になりますが、

$ cat foo.rb
"foo

$ ./ruby -e '
begin
  require "foo.rb"
rescue SyntaxError
  p $!
end
'
#<SyntaxError: /home/mame/work/ruby19/ruby/foo.rb:1: unterminated
string meets end of file>


コンパイル時に失敗すると標準エラー出力になんか出てきます。

$ cat bar.rb
break

$ ./ruby -e '
begin
  require "bar.rb"
rescue SyntaxError
  p $!
end
'
/home/mame/work/ruby19/ruby/bar.rb:1: Invalid break
#<SyntaxError: compile error>


eval ではパース時でもコンパイル時でも通常の例外になります。

$ ./ruby -e '
begin
  eval "\"foo"
rescue SyntaxError
  p $!
end
'
#<SyntaxError: (eval):1: unterminated string meets end of file>

$ ./ruby -e '
begin
  eval "break"
rescue SyntaxError
  p $!
end
'
#<SyntaxError: (eval):1: Can't escape from eval with break>


以上の挙動は意図的でしょうか。


私の感性では、require のコンパイル時の失敗でも通常の例外にするのが
いいと思いました。以下はそうするパッチです。

# この感性が正しければ、parse_in_eval というフラグの名前は
# parse_and_compile_in_eval とかいう方が実体にあっている気がします。
# リファクタリングすべき?

Index: load.c
===================================================================
--- load.c	(revision 17562)
+++ load.c	(working copy)
@@ -276,10 +276,10 @@

 	th->parse_in_eval++;
 	node = (NODE *)rb_load_file(RSTRING_PTR(fname));
-	th->parse_in_eval--;
 	loaded = Qtrue;
 	iseq = rb_iseq_new(node, rb_str_new2("<top (required)>"),
 			   fname, Qfalse, ISEQ_TYPE_TOP);
+	th->parse_in_eval--;
 	rb_iseq_eval(iseq);
     }
     POP_TAG();

-- 
Yusuke ENDOH <mame / tsg.ne.jp>