summaryrefslogtreecommitdiffhomepage
path: root/src/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/class.c')
-rw-r--r--src/class.c65
1 files changed, 34 insertions, 31 deletions
diff --git a/src/class.c b/src/class.c
index dcde9b684..5c5aa52f0 100644
--- a/src/class.c
+++ b/src/class.c
@@ -26,7 +26,7 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
if (!h) return;
for (k = kh_begin(h); k != kh_end(h); k++) {
- if (kh_exist(h, k)){
+ if (kh_exist(h, k)) {
struct RProc *m = kh_value(h, k);
if (m) {
mrb_gc_mark(mrb, (struct RBasic*)m);
@@ -227,6 +227,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
}
switch (mrb_type(outer)) {
case MRB_TT_CLASS:
+ case MRB_TT_SCLASS:
case MRB_TT_MODULE:
break;
default:
@@ -740,14 +741,14 @@ mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
struct RClass *p = c, *ic;
int superclass_seen = 0;
- if (c->mt == m->mt) {
+ if (c->mt && c->mt == m->mt) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
}
while (p) {
if (c != p && p->tt == MRB_TT_CLASS) {
superclass_seen = 1;
}
- else if (p->mt == m->mt){
+ else if (p->mt == m->mt) {
if (p->tt == MRB_TT_ICLASS && !superclass_seen) {
ins_pos = p;
}
@@ -889,6 +890,18 @@ mrb_mod_included_modules(mrb_state *mrb, mrb_value self)
return result;
}
+static mrb_value
+mrb_mod_initialize(mrb_state *mrb, mrb_value mod)
+{
+ mrb_value b;
+
+ mrb_get_args(mrb, "&", &b);
+ if (!mrb_nil_p(b)) {
+ mrb_yield_with_class(mrb, b, 0, 0, mod, mrb_class_ptr(mod));
+ }
+ return mod;
+}
+
mrb_value mrb_class_instance_method_list(mrb_state*, mrb_bool, struct RClass*, int);
/* 15.2.2.4.33 */
@@ -928,29 +941,8 @@ mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod)
return mrb_class_instance_method_list(mrb, recur, c, 0);
}
-/* 15.2.2.4.35 */
-/*
- * call-seq:
- * mod.class_eval {| | block } -> obj
- * mod.module_eval {| | block } -> obj
- *
- * Evaluates block in the context of _mod_. This can
- * be used to add methods to a class. <code>module_eval</code> returns
- * the result of evaluating its argument.
- */
-
-static mrb_value
-mrb_mod_module_eval(mrb_state *mrb, mrb_value mod)
-{
- mrb_value a, b;
- struct RClass *c;
-
- if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
- mrb_raise(mrb, E_NOTIMP_ERROR, "module_eval/class_eval with string not implemented");
- }
- c = mrb_class_ptr(mod);
- return mrb_yield_with_class(mrb, b, 0, 0, mod, c);
-}
+/* implementation of module_eval/class_eval */
+mrb_value mrb_mod_module_eval(mrb_state*, mrb_value);
static mrb_value
mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
@@ -1245,21 +1237,31 @@ mrb_class_path(mrb_state *mrb, struct RClass *c)
{
mrb_value path;
const char *name;
- mrb_int len;
mrb_sym classpath = mrb_intern_lit(mrb, "__classpath__");
path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath);
if (mrb_nil_p(path)) {
struct RClass *outer = mrb_class_outer_module(mrb, c);
mrb_sym sym = mrb_class_sym(mrb, c, outer);
+ mrb_int len;
+
if (sym == 0) {
return mrb_nil_value();
}
else if (outer && outer != mrb->object_class) {
mrb_value base = mrb_class_path(mrb, outer);
- path = mrb_str_plus(mrb, base, mrb_str_new_lit(mrb, "::"));
+ path = mrb_str_buf_new(mrb, 0);
+ if (mrb_nil_p(base)) {
+ mrb_str_cat_lit(mrb, path, "#<Class:");
+ mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, outer));
+ mrb_str_cat_lit(mrb, path, ">");
+ }
+ else {
+ mrb_str_concat(mrb, path, base);
+ }
+ mrb_str_cat_lit(mrb, path, "::");
name = mrb_sym2name_len(mrb, sym, &len);
- mrb_str_concat(mrb, path, mrb_str_new(mrb, name, len));
+ mrb_str_cat(mrb, path, name, len);
}
else {
name = mrb_sym2name_len(mrb, sym, &len);
@@ -1332,7 +1334,7 @@ mrb_class_new(mrb_state *mrb, struct RClass *super)
mrb_check_inheritable(mrb, super);
}
c = boot_defclass(mrb, super);
- if (super){
+ if (super) {
MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super));
}
make_metaclass(mrb, c);
@@ -1698,7 +1700,7 @@ mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod)
val = mrb_iv_remove(mrb, mod, id);
if (!mrb_undef_p(val)) return val;
- if (mrb_cv_defined(mrb, mod, id)){
+ if (mrb_cv_defined(mrb, mod, id)) {
mrb_name_error(mrb, id, "cannot remove %S for %S",
mrb_sym2str(mrb, id), mod);
}
@@ -1978,6 +1980,7 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */
mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */
+ mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */
mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */
mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */