diff options
| author | Yukihiro Matsumoto <[email protected]> | 2012-08-02 01:53:01 +0900 |
|---|---|---|
| committer | Yukihiro Matsumoto <[email protected]> | 2012-08-02 01:53:01 +0900 |
| commit | b00529e672a6b64ec41b36c25395d66364f8cc20 (patch) | |
| tree | 187dd3065ad51c24d402aea5f2ce5f8c8196a2f8 /src | |
| parent | 9ccf9767e1661739bb046cc8956a4437e2e75b55 (diff) | |
| download | mruby-b00529e672a6b64ec41b36c25395d66364f8cc20.tar.gz mruby-b00529e672a6b64ec41b36c25395d66364f8cc20.zip | |
reduce invoking const_missing
Diffstat (limited to 'src')
| -rw-r--r-- | src/variable.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/variable.c b/src/variable.c index a62e7e126..0b4288734 100644 --- a/src/variable.c +++ b/src/variable.c @@ -309,7 +309,8 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) struct RClass *c = base; khash_t(iv) *h; khiter_t k; - mrb_sym cm = mrb_intern(mrb, "const_missing"); + int retry = 0; + mrb_sym cm; L_RETRY: while (c) { @@ -319,18 +320,23 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) if (k != kh_end(h)) { return kh_value(h, k); } - if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) { - mrb_value name = mrb_symbol_value(sym); - return mrb_funcall(mrb, mrb_obj_value(c), "const_missing", 1, name); - } } c = c->super; } - - if (base->tt == MRB_TT_MODULE) { - c = base = mrb->object_class; + if (!retry && base->tt == MRB_TT_MODULE) { + c = mrb->object_class; + retry = 1; goto L_RETRY; } + c = base; + cm = mrb_intern(mrb, "const_missing"); + while (c) { + if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) { + mrb_value name = mrb_symbol_value(sym); + return mrb_funcall(mrb, mrb_obj_value(c), "const_missing", 1, name); + } + c = c->super; + } mrb_raise(mrb, E_NAME_ERROR, "uninitialized constant %s", mrb_sym2name(mrb, sym)); /* not reached */ |
