diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-07-17 10:35:41 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-07-17 10:35:41 +0900 |
| commit | d605b72c1d6fa4564a0a5e88535504b6850463b5 (patch) | |
| tree | 774fc0de56002abb3bb2b1c3387ff08f91876d17 /mrbgems/mruby-method | |
| parent | 2af92d0ebcbeca6d3d85a27c8193273080a63090 (diff) | |
| parent | 9af3b7c6258de327218dd04e69d76ae68caf17b1 (diff) | |
| download | mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.tar.gz mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.zip | |
Merge branch 'master' into i110/inspect-recursion
Diffstat (limited to 'mrbgems/mruby-method')
| -rw-r--r-- | mrbgems/mruby-method/mrblib/kernel.rb | 5 | ||||
| -rw-r--r-- | mrbgems/mruby-method/mrblib/method.rb | 8 | ||||
| -rw-r--r-- | mrbgems/mruby-method/src/method.c | 31 | ||||
| -rw-r--r-- | mrbgems/mruby-method/test/method.rb | 38 |
4 files changed, 49 insertions, 33 deletions
diff --git a/mrbgems/mruby-method/mrblib/kernel.rb b/mrbgems/mruby-method/mrblib/kernel.rb index b2ebd45ea..eb17df5a6 100644 --- a/mrbgems/mruby-method/mrblib/kernel.rb +++ b/mrbgems/mruby-method/mrblib/kernel.rb @@ -1,8 +1,9 @@ module Kernel def singleton_method(name) m = method(name) - if m.owner != singleton_class - raise NameError, "undefined method `#{name}' for class `#{singleton_class}'" + sc = (class <<self; self; end) + if m.owner != sc + raise NameError, "undefined method '#{name}' for class '#{sc}'" end m end diff --git a/mrbgems/mruby-method/mrblib/method.rb b/mrbgems/mruby-method/mrblib/method.rb index 5de0afdf7..f7cefa2e5 100644 --- a/mrbgems/mruby-method/mrblib/method.rb +++ b/mrbgems/mruby-method/mrblib/method.rb @@ -17,4 +17,12 @@ class Method def name @name end + + def <<(other) + ->(*args, &block) { call(other.call(*args, &block)) } + end + + def >>(other) + ->(*args, &block) { other.call(call(*args, &block)) } + end end diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index e445b34c8..d94db1cb2 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -212,19 +212,8 @@ static mrb_value method_arity(mrb_state *mrb, mrb_value self) { mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "proc")); - struct RProc *rproc; - struct RClass *orig; - mrb_value ret; - - if (mrb_nil_p(proc)) - return mrb_fixnum_value(-1); - - rproc = mrb_proc_ptr(proc); - orig = rproc->c; - rproc->c = mrb->proc_class; - ret = mrb_funcall(mrb, proc, "arity", 0); - rproc->c = orig; - return ret; + mrb_int arity = mrb_nil_p(proc) ? -1 : mrb_proc_arity(mrb_proc_ptr(proc)); + return mrb_fixnum_value(arity); } static mrb_value @@ -281,16 +270,16 @@ method_to_s(mrb_state *mrb, mrb_value self) mrb_str_cat_lit(mrb, str, ": "); rklass = mrb_class_ptr(klass); if (mrb_class_ptr(owner) == rklass) { - mrb_str_cat_str(mrb, str, mrb_funcall(mrb, owner, "to_s", 0)); + mrb_str_cat_str(mrb, str, mrb_str_to_str(mrb, owner)); mrb_str_cat_lit(mrb, str, "#"); - mrb_str_cat_str(mrb, str, mrb_funcall(mrb, name, "to_s", 0)); + mrb_str_cat_str(mrb, str, mrb_str_to_str(mrb, name)); } else { mrb_str_cat_cstr(mrb, str, mrb_class_name(mrb, rklass)); mrb_str_cat_lit(mrb, str, "("); - mrb_str_cat_str(mrb, str, mrb_funcall(mrb, owner, "to_s", 0)); + mrb_str_cat_str(mrb, str, mrb_str_to_str(mrb, owner)); mrb_str_cat_lit(mrb, str, ")#"); - mrb_str_cat_str(mrb, str, mrb_funcall(mrb, name, "to_s", 0)); + mrb_str_cat_str(mrb, str, mrb_str_to_str(mrb, name)); } mrb_str_cat_lit(mrb, str, ">"); return str; @@ -327,7 +316,7 @@ name_error: s = mrb_class_name(mrb, c); mrb_raisef( mrb, E_NAME_ERROR, - "undefined method `%S' for class `%S'", + "undefined method '%S' for class '%S'", mrb_sym2str(mrb, name), mrb_str_new_static(mrb, s, strlen(s)) ); @@ -387,7 +376,7 @@ mrb_mruby_method_gem_init(mrb_state* mrb) mrb_define_method(mrb, unbound_method, "bind", unbound_method_bind, MRB_ARGS_REQ(1)); mrb_define_method(mrb, unbound_method, "super_method", method_super_method, MRB_ARGS_NONE()); mrb_define_method(mrb, unbound_method, "==", method_eql, MRB_ARGS_REQ(1)); - mrb_alias_method(mrb, unbound_method, mrb_intern_lit(mrb, "eql?"), mrb_intern_lit(mrb, "==")); + mrb_define_alias(mrb, unbound_method, "eql?", "=="); mrb_define_method(mrb, unbound_method, "to_s", method_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, unbound_method, "inspect", method_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, unbound_method, "arity", method_arity, MRB_ARGS_NONE()); @@ -396,11 +385,11 @@ mrb_mruby_method_gem_init(mrb_state* mrb) mrb_undef_class_method(mrb, method, "new"); mrb_define_method(mrb, method, "==", method_eql, MRB_ARGS_REQ(1)); - mrb_alias_method(mrb, method, mrb_intern_lit(mrb, "eql?"), mrb_intern_lit(mrb, "==")); + mrb_define_alias(mrb, method, "eql?", "=="); mrb_define_method(mrb, method, "to_s", method_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, method, "inspect", method_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, method, "call", method_call, MRB_ARGS_ANY()); - mrb_alias_method(mrb, method, mrb_intern_lit(mrb, "[]"), mrb_intern_lit(mrb, "call")); + mrb_define_alias(mrb, method, "[]", "call"); mrb_define_method(mrb, method, "unbind", method_unbind, MRB_ARGS_NONE()); mrb_define_method(mrb, method, "super_method", method_super_method, MRB_ARGS_NONE()); mrb_define_method(mrb, method, "arity", method_arity, MRB_ARGS_NONE()); diff --git a/mrbgems/mruby-method/test/method.rb b/mrbgems/mruby-method/test/method.rb index b229a4560..0b67d3e61 100644 --- a/mrbgems/mruby-method/test/method.rb +++ b/mrbgems/mruby-method/test/method.rb @@ -21,7 +21,7 @@ class Interpreter } def interpret(string) @ret = "" - string.each_char {|b| Dispatcher[b].bind(self).call } + string.split("").each {|b| Dispatcher[b].bind(self).call } end end @@ -102,10 +102,7 @@ end assert 'Method#call for regression' do obj = BasicObject.new - def obj.foo - :ok - end - assert_equal :ok, Kernel.instance_method(:send).bind(obj).call(:foo), "https://github.com/ksss/mruby-method/issues/4" + assert_equal String, Kernel.instance_method(:inspect).bind(obj).call().class, "https://github.com/ksss/mruby-method/issues/4" end assert 'Method#call with undefined method' do @@ -149,7 +146,7 @@ assert 'Method#source_location' do assert_equal [filename, lineno], klass.new.method(:find_me_if_you_can).source_location lineno = __LINE__ + 1 - klass.define_singleton_method(:s_find_me_if_you_can) {} + class <<klass; define_method(:s_find_me_if_you_can) {}; end assert_equal [filename, lineno], klass.method(:s_find_me_if_you_can).source_location klass = Class.new { def respond_to_missing?(m, b); m == :nothing; end } @@ -243,7 +240,7 @@ assert 'owner' do assert_equal(c, c.new.method(:foo).owner) assert_equal(c, c2.new.method(:foo).owner) - assert_equal(c.singleton_class, c2.method(:bar).owner) + assert_equal((class <<c; self; end), c2.method(:bar).owner) end assert 'owner missing' do @@ -374,6 +371,25 @@ assert "Method#initialize_copy" do assert_equal(m1, m2) end +assert "Method#<< and Method#>>" do + obj = Object.new + class << obj + def mul2(n); n * 2; end + def add3(n); n + 3; end + end + + f = obj.method(:mul2) + g = obj.method(:add3) + + m1 = f << g + assert_kind_of Proc, m1 + assert_equal 16, m1.call(5) + + m2 = f >> g + assert_kind_of Proc, m2 + assert_equal 13, m2.call(5) +end + assert 'UnboundMethod#arity' do c = Class.new { def foo(a, b) @@ -413,12 +429,14 @@ assert 'UnboundMethod#bind' do assert_equal(:meth, m.bind(1).call) assert_equal(:meth, m.bind(:sym).call) assert_equal(:meth, m.bind(Object.new).call) - sc = Class.new { - class << self + sc = nil + Class.new { + sc = class << self def foo end + self end - }.singleton_class + } assert_raise(TypeError) { sc.instance_method(:foo).bind([]) } assert_raise(TypeError) { Array.instance_method(:each).bind(1) } assert_kind_of Method, Object.instance_method(:object_id).bind(Object.new) |
