summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorksss <[email protected]>2014-03-28 18:16:28 +0900
committerksss <[email protected]>2014-03-28 18:16:28 +0900
commitf0dd4cb673e5a6746f2726a88a6f45e29e530718 (patch)
tree8ffbadfaf750b9c013b5c3bbc4bdf072b42a26bd
parent03fa45760e2da4c09acb725fdca20f4e8f7adb27 (diff)
downloadmruby-f0dd4cb673e5a6746f2726a88a6f45e29e530718.tar.gz
mruby-f0dd4cb673e5a6746f2726a88a6f45e29e530718.zip
Implement Kernel#define_singleton_method
-rw-r--r--src/kernel.c19
-rw-r--r--test/t/kernel.rb9
2 files changed, 28 insertions, 0 deletions
diff --git a/src/kernel.c b/src/kernel.c
index e637a53b1..afba3e857 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -1098,6 +1098,24 @@ mrb_obj_singleton_methods_m(mrb_state *mrb, mrb_value self)
}
static mrb_value
+mod_define_singleton_method(mrb_state *mrb, mrb_value self)
+{
+ struct RProc *p;
+ mrb_sym mid;
+ mrb_value blk = mrb_nil_value();
+
+ mrb_get_args(mrb, "n&", &mid, &blk);
+ if (mrb_nil_p(blk)) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+ }
+ p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
+ mrb_proc_copy(p, mrb_proc_ptr(blk));
+ p->flags |= MRB_PROC_STRICT;
+ mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p);
+ return mrb_symbol_value(mid);
+}
+
+static mrb_value
mrb_obj_ceqq(mrb_state *mrb, mrb_value self)
{
mrb_value v;
@@ -1165,6 +1183,7 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ANY()); /* 15.3.1.3.43 */
mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.44 */
mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.45 */
+ mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_ANY());
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */
mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */
diff --git a/test/t/kernel.rb b/test/t/kernel.rb
index c8913c718..c6b65ddf7 100644
--- a/test/t/kernel.rb
+++ b/test/t/kernel.rb
@@ -542,6 +542,15 @@ assert('Kernel#__method__') do
assert_equal(:m2, c.new.m2)
end
+assert('Kernel#define_singleton_method') do
+ o = Object.new
+ ret = o.define_singleton_method(:test_method) do
+ :singleton_method_ok
+ end
+ assert_equal :test_method, ret
+ assert_equal :singleton_method_ok, o.test_method
+end
+
assert('stack extend') do
def recurse(count, stop)
return count if count > stop