summaryrefslogtreecommitdiffhomepage
path: root/src/class.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-07-29 07:05:37 +0900
committerGitHub <[email protected]>2017-07-29 07:05:37 +0900
commitb290e98f3b4e8623fd8932c9996d0481f56f766b (patch)
tree4b875e10e0037d14846999130e4f587bb23d4163 /src/class.c
parentcf23a85333c9c0ee83b0dca4c40d0d33beaf7f66 (diff)
parentf937af5745cbc6edead0ad3911bf16e08f66a96f (diff)
downloadmruby-b290e98f3b4e8623fd8932c9996d0481f56f766b.tar.gz
mruby-b290e98f3b4e8623fd8932c9996d0481f56f766b.zip
Merge pull request #3757 from christopheraue/module_const_get_class_path
Extended Module#const_get to support class paths
Diffstat (limited to 'src/class.c')
-rw-r--r--src/class.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/src/class.c b/src/class.c
index 56f64fd4e..57f64dcc5 100644
--- a/src/class.c
+++ b/src/class.c
@@ -2161,13 +2161,43 @@ mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
}
static mrb_value
+mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id)
+{
+ check_const_name_sym(mrb, id);
+ return mrb_const_get(mrb, mod, id);
+}
+
+static mrb_value
mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
{
+ mrb_value path;
mrb_sym id;
+ char *ptr;
+ mrb_int off, end, len;
- mrb_get_args(mrb, "n", &id);
- check_const_name_sym(mrb, id);
- return mrb_const_get(mrb, mod, id);
+ mrb_get_args(mrb, "o", &path);
+
+ if (mrb_symbol_p(path)) {
+ /* const get with symbol */
+ id = mrb_symbol(path);
+ return mrb_const_get_sym(mrb, mod, id);
+ }
+
+ /* const get with class path string */
+ path = mrb_string_type(mrb, path);
+ ptr = RSTRING_PTR(path);
+ len = RSTRING_LEN(path);
+ off = 0;
+
+ while (off < len) {
+ end = mrb_str_index_lit(mrb, path, "::", off);
+ end = (end == -1) ? len : end;
+ id = mrb_intern(mrb, ptr+off, end-off);
+ mod = mrb_const_get_sym(mrb, mod, id);
+ off = (end == len) ? end : end+2;
+ }
+
+ return mod;
}
static mrb_value