mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
class.c (extend_object): remove method; implement Kernel#extend in C
This commit is contained in:
@@ -28,6 +28,7 @@ mrb_method_t mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass
|
||||
mrb_value mrb_mod_const_missing(mrb_state *mrb, mrb_value mod);
|
||||
mrb_value mrb_const_missing(mrb_state *mrb, mrb_value mod, mrb_sym sym);
|
||||
size_t mrb_class_mt_memsize(mrb_state*, struct RClass*);
|
||||
mrb_value mrb_obj_extend(mrb_state*, mrb_value obj);
|
||||
#endif
|
||||
|
||||
mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value);
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
module Kernel
|
||||
##
|
||||
# call-seq:
|
||||
# obj.extend(module, ...) -> obj
|
||||
#
|
||||
# Adds to _obj_ the instance methods from each module given as a
|
||||
# parameter.
|
||||
#
|
||||
# module Mod
|
||||
# def hello
|
||||
# "Hello from Mod.\n"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# class Klass
|
||||
# def hello
|
||||
# "Hello from Klass.\n"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# k = Klass.new
|
||||
# k.hello #=> "Hello from Klass.\n"
|
||||
# k.extend(Mod) #=> #<Klass:0x401b3bc8>
|
||||
# k.hello #=> "Hello from Mod.\n"
|
||||
#
|
||||
# ISO 15.3.1.3.13
|
||||
def extend(*args)
|
||||
args.reverse!
|
||||
obj = self
|
||||
args.each do |m|
|
||||
m.__send__(:extend_object, obj)
|
||||
m.__send__(:extended, obj)
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
+47
-12
@@ -1625,6 +1625,53 @@ mrb_mod_include(mrb_state *mrb, mrb_value mod)
|
||||
return mod;
|
||||
}
|
||||
|
||||
/* 15.3.1.3.13 */
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.extend(module, ...) -> obj
|
||||
*
|
||||
* Adds to _obj_ the instance methods from each module given as a
|
||||
* parameter.
|
||||
*
|
||||
* module Mod
|
||||
* def hello
|
||||
* "Hello from Mod.\n"
|
||||
* end
|
||||
* end
|
||||
*
|
||||
* class Klass
|
||||
* def hello
|
||||
* "Hello from Klass.\n"
|
||||
* end
|
||||
* end
|
||||
*
|
||||
* k = Klass.new
|
||||
* k.hello #=> "Hello from Klass.\n"
|
||||
* k.extend(Mod) #=> #<Klass:0x401b3bc8>
|
||||
* k.hello #=> "Hello from Mod.\n"
|
||||
*
|
||||
*/
|
||||
mrb_value
|
||||
mrb_obj_extend(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_int argc;
|
||||
mrb_value *argv;
|
||||
mrb_sym extended = MRB_SYM(extended);
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
|
||||
mrb_value cc = mrb_singleton_class(mrb, obj);
|
||||
while (argc--) {
|
||||
mrb_value mod = argv[argc];
|
||||
mrb_check_type(mrb, mod, MRB_TT_MODULE);
|
||||
mrb_include_module(mrb, mrb_class_ptr(cc), mrb_class_ptr(mod));
|
||||
if (!mrb_func_basic_p(mrb, cc, extended, mrb_do_nothing)) {
|
||||
mrb_funcall_argv(mrb, cc, extended, 1, &mod);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* 15.2.2.4.28 */
|
||||
/*
|
||||
* call-seq:
|
||||
@@ -1681,16 +1728,6 @@ mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
|
||||
return result;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_mod_extend_object(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
mrb_check_type(mrb, mod, MRB_TT_MODULE);
|
||||
mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod));
|
||||
return mod;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_mod_initialize(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
@@ -3174,7 +3211,6 @@ mrb_init_class(mrb_state *mrb)
|
||||
init_class_new(mrb, cls);
|
||||
|
||||
MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
|
||||
mrb_define_private_method_id(mrb, mod, MRB_SYM(extend_object), mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
|
||||
mrb_define_private_method_id(mrb, mod, MRB_SYM(extended), mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
|
||||
mrb_define_private_method_id(mrb, mod, MRB_SYM(prepended), mrb_do_nothing, MRB_ARGS_REQ(1));
|
||||
mrb_define_method_id(mrb, mod, MRB_SYM_Q(include), mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
|
||||
@@ -3211,7 +3247,6 @@ mrb_init_class(mrb_state *mrb)
|
||||
mrb_define_private_method_id(mrb, mod, MRB_SYM(method_undefined), mrb_do_nothing, MRB_ARGS_REQ(1));
|
||||
mrb_define_private_method_id(mrb, mod, MRB_SYM(const_added), mrb_do_nothing, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_undef_method_id(mrb, cls, MRB_SYM(extend_object));
|
||||
mrb_undef_method_id(mrb, cls, MRB_SYM(module_function));
|
||||
|
||||
mrb->top_self = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb->object_class);
|
||||
|
||||
+2
-1
@@ -591,6 +591,7 @@ mrb_init_kernel(mrb_state *mrb)
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM_Q(eql), mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.10 */
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM(freeze), mrb_obj_freeze, MRB_ARGS_NONE());
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM_Q(frozen), mrb_obj_frozen, MRB_ARGS_NONE());
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM(extend), mrb_obj_extend, MRB_ARGS_ANY()); /* 15.3.1.3.13 */
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM(hash), mrb_obj_hash, MRB_ARGS_NONE()); /* 15.3.1.3.15 */
|
||||
mrb_define_private_method_id(mrb, krn, MRB_SYM(initialize_copy), mrb_obj_init_copy, MRB_ARGS_REQ(1)); /* 15.3.1.3.16 */
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM(inspect), mrb_obj_inspect, MRB_ARGS_NONE()); /* 15.3.1.3.17 */
|
||||
@@ -611,7 +612,7 @@ mrb_init_kernel(mrb_state *mrb)
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM(to_s), mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM(__case_eqq), mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM(__to_int), mrb_ensure_int_type, MRB_ARGS_NONE()); /* internal */
|
||||
mrb_define_private_method_id(mrb, krn, MRB_SYM_Q(respond_to_missing), mrb_false, MRB_ARGS_ARG(1,1));
|
||||
mrb_define_private_method_id(mrb, krn, MRB_SYM_Q(respond_to_missing), mrb_false, MRB_ARGS_ARG(1,1));
|
||||
mrb_define_method_id(mrb, krn, MRB_SYM_Q(__inspect_recursive), mrb_obj_inspect_recursive_p, MRB_ARGS_NONE());
|
||||
|
||||
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
|
||||
|
||||
@@ -295,18 +295,6 @@ assert('Module#const_missing', '15.2.2.4.22') do
|
||||
assert_equal 42, Test4ConstMissing.const_get(:ConstDoesntExist)
|
||||
end
|
||||
|
||||
assert('Module#extend_object', '15.2.2.4.25') do
|
||||
cls = Class.new
|
||||
mod = Module.new { def foo; end }
|
||||
a = cls.new
|
||||
b = cls.new
|
||||
mod.__send__(:extend_object,b)
|
||||
assert_false a.respond_to?(:foo)
|
||||
assert_true b.respond_to?(:foo)
|
||||
assert_raise(FrozenError) { mod.__send__(:extend_object,cls.new.freeze) }
|
||||
assert_raise(FrozenError, TypeError) { mod.__send__(:extend_object,1) }
|
||||
end
|
||||
|
||||
assert('Module#include', '15.2.2.4.27') do
|
||||
module Test4Include
|
||||
Const4Include = 42
|
||||
|
||||
Reference in New Issue
Block a user