* error.c (rb_loaderror_with_path): Adding the missing file as an

instance variable to the LoadError exception.

* load.c: call rb_loaderror_with_path so that the missing path is
  added to the exception.

* ruby.c: call rb_loaderror rather than raising our own LoadError
  exception.

* include/ruby/intern.h: add declaration for rb_loaderror_with_path.

* test/ruby/test_require.rb: add supporting test for LoadError#path
  method.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34938 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tenderlove 2012-03-06 23:38:33 +00:00
Родитель c95cfa0a16
Коммит d576a25c26
7 изменённых файлов: 59 добавлений и 7 удалений

Просмотреть файл

@ -1,3 +1,19 @@
Wed Mar 7 08:32:43 2012 Aaron Patterson <aaron@tenderlovemaking.com>
* error.c (rb_loaderror_with_path): Adding the missing file as an
instance variable to the LoadError exception.
* load.c: call rb_loaderror_with_path so that the missing path is
added to the exception.
* ruby.c: call rb_loaderror rather than raising our own LoadError
exception.
* include/ruby/intern.h: add declaration for rb_loaderror_with_path.
* test/ruby/test_require.rb: add supporting test for LoadError#path
method.
Wed Mar 7 08:28:00 2012 Aaron Patterson <aaron@tenderlovemaking.com> Wed Mar 7 08:28:00 2012 Aaron Patterson <aaron@tenderlovemaking.com>
* lib/xmlrpc/parser.rb: support i8 types. Thanks Stas Kelvich! * lib/xmlrpc/parser.rb: support i8 types. Thanks Stas Kelvich!

5
NEWS
Просмотреть файл

@ -28,6 +28,11 @@ with all sufficient information, see the ChangeLog file.
* respond_to? against a protected method now returns false unless * respond_to? against a protected method now returns false unless
the second argument is true. the second argument is true.
* LoadError
* added method:
* added LoadError#path method to return the file name that could not be
loaded.
* Signal * Signal
* incompatible changes: * incompatible changes:
* Signal.trap raises ArgumentError when :SEGV, :BUS, :ILL, :FPE, :VTALRM * Signal.trap raises ArgumentError when :SEGV, :BUS, :ILL, :FPE, :VTALRM

25
error.c
Просмотреть файл

@ -1691,7 +1691,10 @@ Init_Exception(void)
rb_eScriptError = rb_define_class("ScriptError", rb_eException); rb_eScriptError = rb_define_class("ScriptError", rb_eException);
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError); rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
rb_eLoadError = rb_define_class("LoadError", rb_eScriptError); rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
rb_attr(rb_eLoadError, rb_intern("path"), 1, 0, Qfalse);
rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError); rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
rb_eNameError = rb_define_class("NameError", rb_eStandardError); rb_eNameError = rb_define_class("NameError", rb_eStandardError);
@ -1742,11 +1745,29 @@ rb_loaderror(const char *fmt, ...)
{ {
va_list args; va_list args;
VALUE mesg; VALUE mesg;
VALUE err;
va_start(args, fmt); va_start(args, fmt);
mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args); mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
va_end(args); va_end(args);
rb_exc_raise(rb_exc_new3(rb_eLoadError, mesg)); err = rb_exc_new3(rb_eLoadError, mesg);
rb_ivar_set(err, rb_intern("@path"), Qnil);
rb_exc_raise(err);
}
void
rb_loaderror_with_path(VALUE path, const char *fmt, ...)
{
va_list args;
VALUE mesg;
VALUE err;
va_start(args, fmt);
mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
va_end(args);
err = rb_exc_new3(rb_eLoadError, mesg);
rb_ivar_set(err, rb_intern("@path"), path);
rb_exc_raise(err);
} }
void void
@ -1889,7 +1910,7 @@ rb_sys_warning(const char *fmt, ...)
void void
rb_load_fail(const char *path) rb_load_fail(const char *path)
{ {
rb_loaderror("%s -- %s", strerror(errno), path); rb_loaderror_with_path(rb_str_new2(path), "%s -- %s", strerror(errno), path);
} }
void void

Просмотреть файл

@ -209,6 +209,7 @@ VALUE rb_exc_new(VALUE, const char*, long);
VALUE rb_exc_new2(VALUE, const char*); VALUE rb_exc_new2(VALUE, const char*);
VALUE rb_exc_new3(VALUE, VALUE); VALUE rb_exc_new3(VALUE, VALUE);
PRINTF_ARGS(NORETURN(void rb_loaderror(const char*, ...)), 1, 2); PRINTF_ARGS(NORETURN(void rb_loaderror(const char*, ...)), 1, 2);
PRINTF_ARGS(NORETURN(void rb_loaderror_with_path(VALUE path, const char*, ...)), 2, 3);
PRINTF_ARGS(NORETURN(void rb_name_error(ID, const char*, ...)), 2, 3); PRINTF_ARGS(NORETURN(void rb_name_error(ID, const char*, ...)), 2, 3);
PRINTF_ARGS(NORETURN(void rb_name_error_str(VALUE, const char*, ...)), 2, 3); PRINTF_ARGS(NORETURN(void rb_name_error_str(VALUE, const char*, ...)), 2, 3);
NORETURN(void rb_invalid_str(const char*, const char*)); NORETURN(void rb_invalid_str(const char*, const char*));

9
load.c
Просмотреть файл

@ -495,7 +495,7 @@ rb_f_require_relative(VALUE obj, VALUE fname)
{ {
VALUE base = rb_current_realfilepath(); VALUE base = rb_current_realfilepath();
if (NIL_P(base)) { if (NIL_P(base)) {
rb_raise(rb_eLoadError, "cannot infer basepath"); rb_loaderror("cannot infer basepath");
} }
base = rb_file_dirname(base); base = rb_file_dirname(base);
return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level()); return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
@ -588,12 +588,13 @@ search_required(VALUE fname, volatile VALUE *path, int safe_level)
return type ? 's' : 'r'; return type ? 's' : 'r';
} }
void rb_loaderror_with_path(VALUE path, const char *fmt, ...);
static void static void
load_failed(VALUE fname) load_failed(VALUE fname)
{ {
VALUE mesg = rb_str_buf_new_cstr("cannot load such file -- "); rb_loaderror_with_path(fname, "cannot load such file -- %s", RSTRING_PTR(fname));
rb_str_append(mesg, fname); /* should be ASCII compatible */ RB_GC_GUARD(fname);
rb_exc_raise(rb_exc_new3(rb_eLoadError, mesg));
} }
static VALUE static VALUE

2
ruby.c
Просмотреть файл

@ -1560,7 +1560,7 @@ load_file_internal(VALUE arg)
} }
} }
} }
rb_raise(rb_eLoadError, "no Ruby script found in input"); rb_loaderror("no Ruby script found in input");
} }
c = rb_io_getbyte(f); c = rb_io_getbyte(f);

Просмотреть файл

@ -5,6 +5,14 @@ require_relative 'envutil'
require 'tmpdir' require 'tmpdir'
class TestRequire < Test::Unit::TestCase class TestRequire < Test::Unit::TestCase
def test_load_error_path
filename = "should_not_exist"
error = assert_raises(LoadError) do
require filename
end
assert_equal filename, error.path
end
def test_require_invalid_shared_object def test_require_invalid_shared_object
t = Tempfile.new(["test_ruby_test_require", ".so"]) t = Tempfile.new(["test_ruby_test_require", ".so"])
t.puts "dummy" t.puts "dummy"