* error.c (NameError::Message): new class for lazy evaluation of

message to ensure replaced before marshalling.  [ruby-dev:22604]

* eval.c (rb_method_missing): use NameError::Message.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5481 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2004-01-17 14:58:57 +00:00
Родитель f9c2dcec4e
Коммит 292b3ecbb4
3 изменённых файлов: 113 добавлений и 70 удалений

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

@ -1,3 +1,10 @@
Sat Jan 17 23:58:51 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* error.c (NameError::Message): new class for lazy evaluation of
message to ensure replaced before marshalling. [ruby-dev:22604]
* eval.c (rb_method_missing): use NameError::Message.
Sat Jan 17 21:49:50 2004 NAKAMURA Usaku <usa@ruby-lang.org>
* lib/time.rb (test_rfc2822, test_rfc3339, test_encode_xmlschema):

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

@ -293,6 +293,7 @@ VALUE rb_eNoMethodError;
VALUE rb_eSecurityError;
VALUE rb_eNotImpError;
VALUE rb_eNoMemError;
static VALUE rb_cNameErrorMesg;
VALUE rb_eScriptError;
VALUE rb_eSyntaxError;
@ -627,6 +628,28 @@ name_err_name(self)
return rb_attr_get(self, rb_intern("name"));
}
/*
* call-seq:
* name_error.to_s => string
*
* Produce a nicely-formated string representing the +NameError+.
*/
static VALUE
name_err_to_s(exc)
VALUE exc;
{
VALUE mesg = rb_attr_get(exc, rb_intern("mesg")), str = mesg;
if (NIL_P(mesg)) return rb_class_path(CLASS_OF(exc));
StringValue(str);
if (str != mesg) {
rb_iv_set(exc, "mesg", mesg = str);
}
if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);
return mesg;
}
/*
* call-seq:
* NoMethodError.new(msg, name [, args]) => no_method_error
@ -649,6 +672,78 @@ nometh_err_initialize(argc, argv, self)
return self;
}
static void
name_err_mesg_mark(ptr)
VALUE *ptr;
{
rb_gc_mark_locations(ptr, ptr+3);
}
static VALUE
name_err_mesg_init(obj, mesg, recv, method)
VALUE obj, mesg, recv, method;
{
VALUE *ptr = ALLOC_N(VALUE, 3);
ptr[0] = mesg;
ptr[1] = recv;
ptr[2] = method;
return Data_Wrap_Struct(rb_cNameErrorMesg, name_err_mesg_mark, -1, ptr);
}
static VALUE
name_err_mesg_to_str(obj)
VALUE obj;
{
VALUE *ptr, mesg;
Data_Get_Struct(obj, VALUE, ptr);
mesg = ptr[0];
if (NIL_P(mesg)) return Qnil;
else {
char *desc = 0;
VALUE d = 0, args[3];
obj = ptr[1];
switch (TYPE(obj)) {
case T_NIL:
desc = "nil";
break;
case T_TRUE:
desc = "true";
break;
case T_FALSE:
desc = "false";
break;
default:
d = rb_protect(rb_inspect, obj, 0);
if (!NIL_P(d) || RSTRING(d)->len > 65) {
d = rb_any_to_s(obj);
}
desc = RSTRING(d)->ptr;
break;
}
if (desc && desc[0] != '#') {
d = rb_str_new2(desc);
rb_str_cat2(d, ":");
rb_str_cat2(d, rb_obj_classname(obj));
}
args[0] = mesg;
args[1] = ptr[2];
args[2] = d;
mesg = rb_f_sprintf(3, args);
}
if (OBJ_TAINTED(obj)) OBJ_TAINT(mesg);
return mesg;
}
static VALUE
name_err_mesg_load(klass, str)
VALUE klass, str;
{
return str;
}
/*
* call-seq:
* no_method_error.args => obj
@ -884,6 +979,12 @@ Init_Exception()
rb_eNameError = rb_define_class("NameError", rb_eStandardError);
rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
rb_define_method(rb_eNameError, "name", name_err_name, 0);
rb_define_method(rb_eNameError, "to_s", name_err_to_s, 0);
rb_define_singleton_method(rb_eNameError, "message", name_err_mesg_init, 3);
rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "Message", rb_cData);
rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_to_str, 1);
rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1);
rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError);
rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);

75
eval.c
Просмотреть файл

@ -5159,65 +5159,6 @@ static int last_call_status;
#define CSTAT_VCALL 4
#define CSTAT_SUPER 8
/*
* call-seq:
* name_error.to_s => string
*
* Produce a nicely-formated string representing the +NameError+.
*/
static VALUE
name_err_to_s(exc)
VALUE exc;
{
VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
ID id_recv = rb_intern("recv");
if (NIL_P(mesg)) return rb_class_path(CLASS_OF(exc));
if (rb_ivar_defined(exc, id_recv)) {
char buf[BUFSIZ];
char *desc = "";
volatile VALUE d = 0;
int noclass;
VALUE obj = rb_ivar_get(exc, id_recv);
int state;
switch (TYPE(obj)) {
case T_NIL:
desc = "nil";
break;
case T_TRUE:
desc = "true";
break;
case T_FALSE:
desc = "false";
break;
default:
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
d = rb_inspect(obj);
}
POP_TAG();
if (!d || RSTRING(d)->len > 65) {
d = rb_any_to_s(obj);
}
break;
}
if (d) {
desc = RSTRING(d)->ptr;
}
noclass = (!desc || desc[0]=='#');
snprintf(buf, BUFSIZ, RSTRING(mesg)->ptr, desc,
noclass ? "" : ":",
noclass ? "" : rb_obj_classname(obj));
mesg = rb_str_new2(buf);
rb_iv_set(exc, "mesg", mesg);
st_delete(ROBJECT(exc)->iv_tbl, (st_data_t*)&id_recv, 0);
}
if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);
return mesg;
}
/*
* call-seq:
* obj.method_missing(symbol [, *args] ) => result
@ -5268,36 +5209,33 @@ rb_method_missing(argc, argv, obj)
id = SYM2ID(argv[0]);
if (last_call_status & CSTAT_PRIV) {
format = "private method `%s' called for %%s%%s%%s";
format = "private method `%s' called for %s";
}
else if (last_call_status & CSTAT_PROT) {
format = "protected method `%s' called for %%s%%s%%s";
format = "protected method `%s' called for %s";
}
else if (last_call_status & CSTAT_VCALL) {
format = "undefined local variable or method `%s' for %%s%%s%%s";
format = "undefined local variable or method `%s' for %s";
exc = rb_eNameError;
}
else if (last_call_status & CSTAT_SUPER) {
format = "super: no superclass method `%s'";
}
if (!format) {
format = "undefined method `%s' for %%s%%s%%s";
format = "undefined method `%s' for %s";
}
ruby_current_node = cnode;
{
char buf[BUFSIZ];
int n = 0;
VALUE args[3];
snprintf(buf, BUFSIZ, format, rb_id2name(id));
args[n++] = rb_str_new2(buf);
args[n++] = rb_funcall(exc, rb_intern("message"), 3, rb_str_new2(format), obj, argv[0]);
args[n++] = argv[0];
if (exc == rb_eNoMethodError) {
args[n++] = rb_ary_new4(argc-1, argv+1);
}
exc = rb_class_new_instance(n, args, exc);
rb_iv_set(exc, "recv", obj);
ruby_frame = ruby_frame->prev; /* pop frame for "method_missing" */
rb_exc_raise(exc);
}
@ -7661,9 +7599,6 @@ Init_load()
ruby_dln_librefs = rb_ary_new();
rb_global_variable(&ruby_dln_librefs);
/* not really a right place */
rb_define_method(rb_eNameError, "to_s", name_err_to_s, 0);
}
static void