遠藤です。
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>