summaryrefslogtreecommitdiffhomepage
path: root/src/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/class.c')
-rw-r--r--src/class.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/src/class.c b/src/class.c
index 2c1145ed3..e0d45a7f3 100644
--- a/src/class.c
+++ b/src/class.c
@@ -731,8 +731,13 @@ boot_defclass(mrb_state *mrb, struct RClass *super)
struct RClass *c;
c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class);
- c->super = super ? super : mrb->object_class;
- mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
+ if (super) {
+ c->super = super;
+ mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
+ }
+ else {
+ c->super = mrb->object_class;
+ }
c->mt = kh_init(mt, mrb);
return c;
}
@@ -1118,7 +1123,7 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
}
new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
if (!mrb_nil_p(blk)) {
- mrb_funcall_with_block(mrb, new_class, mrb_intern_cstr(mrb, "class_eval"), 0, NULL, blk);
+ mrb_funcall_with_block(mrb, new_class, mrb_intern_lit(mrb, "class_eval"), 0, NULL, blk);
}
mrb_funcall(mrb, super, "inherited", 1, new_class);
return new_class;
@@ -1189,22 +1194,28 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod)
mrb_sym name;
mrb_value *a;
int alen;
- mrb_value inspect;
+ mrb_sym inspect;
+ mrb_value repr;
mrb_get_args(mrb, "n*", &name, &a, &alen);
- if (mrb_respond_to(mrb,mod,mrb_intern_lit(mrb, "inspect"))){
- inspect = mrb_funcall(mrb, mod, "inspect", 0);
- if (RSTRING_LEN(inspect) > 64) {
- inspect = mrb_any_to_s(mrb, mod);
+ inspect = mrb_intern_lit(mrb, "inspect");
+ if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) {
+ /* method missing in inspect; avoid recursion */
+ repr = mrb_any_to_s(mrb, mod);
+ }
+ else if (mrb_respond_to(mrb, mod, inspect)) {
+ repr = mrb_funcall_argv(mrb, mod, inspect, 0, 0);
+ if (RSTRING_LEN(repr) > 64) {
+ repr = mrb_any_to_s(mrb, mod);
}
}
else {
- inspect = mrb_any_to_s(mrb, mod);
+ repr = mrb_any_to_s(mrb, mod);
}
mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%S' for %S",
- mrb_sym2str(mrb, name), inspect);
+ mrb_sym2str(mrb, name), repr);
/* not reached */
return mrb_nil_value();
}
@@ -1285,7 +1296,7 @@ mrb_class_name(mrb_state *mrb, struct RClass* c)
if (mrb_nil_p(path)) {
path = mrb_str_new_lit(mrb, "#<Class:");
mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c));
- mrb_str_cat(mrb, path, ">", 1);
+ mrb_str_cat_lit(mrb, path, ">");
}
return mrb_str_ptr(path)->ptr;
}
@@ -1420,7 +1431,7 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
mrb_str_append(mrb, str, mrb_any_to_s(mrb, v));
break;
}
- mrb_str_cat(mrb, str, ">", 1);
+ mrb_str_cat_lit(mrb, str, ">");
}
else {
struct RClass *c;
@@ -1433,20 +1444,20 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
if (mrb_nil_p(path)) {
switch (mrb_type(klass)) {
case MRB_TT_CLASS:
- mrb_str_cat(mrb, str, "#<Class:", 8);
+ mrb_str_cat_lit(mrb, str, "#<Class:");
break;
case MRB_TT_MODULE:
- mrb_str_cat(mrb, str, "#<Module:", 9);
+ mrb_str_cat_lit(mrb, str, "#<Module:");
break;
default:
/* Shouldn't be happened? */
- mrb_str_cat(mrb, str, "#<??????:", 9);
+ mrb_str_cat_lit(mrb, str, "#<??????:");
break;
}
mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c));
- mrb_str_cat(mrb, str, ">", 1);
+ mrb_str_cat_lit(mrb, str, ">");
}
else {
str = path;