12 def do_a() @ret += "there, "; end
13 def do_d() @ret += "Hello "; end
14 def do_e() @ret += "!\n"; end
15 def do_v() @ret += "Dave"; end
17 "a" => instance_method(:do_a),
18 "d" => instance_method(:do_d),
19 "e" => instance_method(:do_e),
20 "v" => instance_method(:do_v)
24 string.each_char {|b| Dispatcher[b].bind(self).call }
29 interpreter = Interpreter.new
30 interpreter.interpret('dave')
31 assert_equal "Hello there, Dave!\n", interpreter.ret
34 assert 'Method#arity' do
37 def initialize; @done = false; end
41 def mo1(a = nil, &b) end
42 def mo2(a, b = nil) end
44 def mo4(a, *b, &c) end
46 def mo6(a, *b, c, &d) end
47 def mo7(a, b = nil, *c, d, &e) end
48 def ma1((a), &b) nil && a end
51 assert_equal(0, method(:m0).arity)
52 assert_equal(1, method(:m1).arity)
53 assert_equal(2, method(:m2).arity)
54 assert_equal(-1, method(:mo1).arity)
55 assert_equal(-2, method(:mo2).arity)
56 assert_equal(-1, method(:mo3).arity)
57 assert_equal(-2, method(:mo4).arity)
58 assert_equal(-3, method(:mo5).arity)
59 assert_equal(-3, method(:mo6).arity)
60 assert_equal(-3, method(:mo7).arity)
61 assert_equal(1, method(:ma1).arity)
63 assert_equal(-1, method(:__send__).arity)
64 assert_equal(-1, method(:nothing).arity)
67 def respond_to_missing?(m, b)
73 assert 'Method and UnboundMethod should not be have a `new` method' do
74 assert_raise(NoMethodError){ Method.new }
75 assert_raise(NoMethodError){ UnboundMethod.new }
79 assert_kind_of Method, 1.method(:+)
80 assert_kind_of UnboundMethod, Fixnum.instance_method(:+)
83 assert 'Method#call' do
84 assert_equal 3, 1.method(:+).call(2)
85 assert_equal "ab", "a".method(:+)["b"]
89 klass2 = Class.new(klass) {
92 assert_equal 42, klass2.new.method(:foo).call
99 assert_raise(LocalJumpError) { i.method(:bar).call }
100 assert_equal 3, i.method(:bar).call { |i| i }
103 assert 'Method#call for regression' do
104 obj = BasicObject.new
105 assert_equal String, Kernel.instance_method(:inspect).bind(obj).call().class, "https://github.com/ksss/mruby-method/issues/4"
108 assert 'Method#call with undefined method' do
110 attr_accessor :m, :argv
111 def respond_to_missing?(m, b)
115 def method_missing(m, *argv)
122 assert_raise(NameError) { cc.method(:nothing) }
123 assert_kind_of Method, cc.method(:foo)
124 assert_raise(NoMethodError) { cc.method(:foo).call(:arg1, :arg2) }
125 assert_equal :foo, cc.m
126 assert_equal [:arg1, :arg2], cc.argv
135 assert_raise(NoMethodError) { m.call(:arg1, :arg2) }
138 assert 'Method#source_location' do
139 skip if proc{}.source_location.nil?
144 lineno = __LINE__ + 1
145 klass.define_method(:find_me_if_you_can) {}
146 assert_equal [filename, lineno], klass.new.method(:find_me_if_you_can).source_location
148 lineno = __LINE__ + 1
149 class <<klass; define_method(:s_find_me_if_you_can) {}; end
150 assert_equal [filename, lineno], klass.method(:s_find_me_if_you_can).source_location
152 klass = Class.new { def respond_to_missing?(m, b); m == :nothing; end }
153 assert_nil klass.new.method(:nothing).source_location
156 assert 'UnboundMethod#source_location' do
157 skip if proc{}.source_location.nil?
161 def respond_to_missing?(m, b)
166 lineno = __LINE__ + 1
167 klass.define_method(:find_me_if_you_can) {}
168 assert_equal [filename, lineno], klass.instance_method(:find_me_if_you_can).source_location
169 assert_nil klass.new.method(:nothing).unbind.source_location
172 assert 'Method#parameters' do
174 def foo(a, b=nil, *c) end
175 def respond_to_missing?(m, b)
179 assert_equal [[:req, :a], [:opt, :b], [:rest, :c]], klass.new.method(:foo).parameters
180 assert_equal [[:rest]], klass.new.method(:missing).parameters
183 assert 'UnboundMethod#parameters' do
185 def foo(a, b=nil, *c) end
186 def respond_to_missing?(m, b)
190 assert_equal [[:req, :a], [:opt, :b], [:rest, :c]], klass.instance_method(:foo).parameters
191 assert_equal [[:rest]], klass.new.method(:nothing).unbind.parameters
194 assert 'Method#to_proc' do
196 assert_kind_of Proc, m.to_proc
197 assert_equal 7, m.call(4)
200 def o.foo(a, b=nil, *c)
203 assert_equal [:bar, nil, []], o.method(:foo).to_proc.call(:bar)
204 # We can fix this issue but leave until the problem
205 # assert_equal o.method(:foo).arity, o.method(:foo).to_proc.arity
210 assert_equal 42, o.bar(&3.method(:+))
217 assert_equal("#<UnboundMethod: #{ class << o; self; end.inspect }#foo>", m.unbind.inspect)
220 c.class_eval { def foo; end; }
221 m = c.new.method(:foo)
222 assert_equal("#<Method: #{ c.inspect }#foo>", m.inspect)
223 m = c.instance_method(:foo)
224 assert_equal("#<UnboundMethod: #{ c.inspect }#foo>", m.inspect)
238 assert_equal(c, c.instance_method(:foo).owner)
239 assert_equal(c, c2.instance_method(:foo).owner)
241 assert_equal(c, c.new.method(:foo).owner)
242 assert_equal(c, c2.new.method(:foo).owner)
243 assert_equal((class <<c; self; end), c2.method(:bar).owner)
246 assert 'owner missing' do
248 def respond_to_missing?(name, bool)
253 assert_equal(c, c.new.method(:foo).owner)
254 assert_equal(c2, c2.new.method(:foo).owner)
257 assert 'receiver name owner' do
261 assert_equal(o, m.receiver)
262 assert_equal(:foo, m.name)
263 assert_equal(class << o; self; end, m.owner)
264 assert_equal(:foo, m.unbind.name)
265 assert_equal(class << o; self; end, m.unbind.owner)
268 assert 'Method#unbind' do
269 assert_equal(:derived, Derived.new.foo)
270 um = Derived.new.method(:foo).unbind
271 assert_kind_of(UnboundMethod, um)
272 Derived.class_eval do
273 def foo() :changed end
275 assert_equal(:changed, Derived.new.foo)
276 assert_equal(:changed, Derived.new.foo{})
277 assert_equal(:derived, um.bind(Derived.new).call)
278 assert_raise(TypeError) do
283 # Block passed method not handled correctly with workaround.
284 # See comment near `mrb_funcall_with_block` for detail.
285 # assert_equal(:derived, um.bind(Derived.new).call{})
288 assert 'Kernel#method' do
293 assert_kind_of Method, o.method(:foo)
294 assert_kind_of Method, o.method('foo')
295 assert_raise(TypeError) { o.method(nil) }
296 assert_raise(NameError) { o.method('bar') }
297 assert_raise(NameError) { o.method(:bar) }
300 assert "Module#instance_method" do
301 assert_kind_of UnboundMethod, Object.instance_method(:object_id)
302 assert_raise(NameError) { Object.instance_method(:nothing) }
304 def respond_to_missing?(m, b)
308 assert_raise(NameError) { c.instance_method(:nothing) }
311 assert 'Kernel#singleton_method' do
317 assert_kind_of Method, o.method(:foo)
318 assert_raise(NameError) { o.singleton_method(:foo) }
319 assert_kind_of Method, o.singleton_method(:bar)
320 assert_raise(TypeError) { o.singleton_method(nil) }
321 m = assert_nothing_raised(NameError) { break o.singleton_method(:bar) }
322 assert_equal(:bar, m.call)
325 assert 'Method#super_method' do
327 m = o.method(:foo).super_method
328 assert_equal(Base, m.owner)
329 assert_true(o.equal? m.receiver)
330 assert_equal(:foo, m.name)
331 assert_nil(m.super_method)
337 o.extend Module.new {
340 assert_equal c, o.method(:foo).super_method.owner
341 assert_equal :foo, o.method(:foo).super_method.name
342 assert_equal o, o.method(:foo).super_method.receiver
345 assert 'Method#==' do
350 assert_not_equal(o.method(:foo), nil)
353 # TODO: assert_not_equal(o.method(:foo), m)
354 assert_equal(o.method(:foo), o.method(:foo))
355 # TODO: assert_false(o.method(:foo).eql? m)
356 assert_true(o.method(:foo).eql? o.method(:foo))
358 assert_false(0.method(:+) == 1.method(:+))
359 assert_false(0.method(:+) == 0.method(:-))
361 assert_true(a.method(:==) == a.method(:eql?))
364 assert "Method#initialize_copy" do
374 assert "Method#<< and Method#>>" do
377 def mul2(n); n * 2; end
378 def add3(n); n + 3; end
381 f = obj.method(:mul2)
382 g = obj.method(:add3)
385 assert_kind_of Proc, m1
386 assert_equal 16, m1.call(5)
389 assert_kind_of Proc, m2
390 assert_equal 13, m2.call(5)
393 assert 'UnboundMethod#arity' do
398 def respond_to_missing?(m, b)
402 assert_equal 2, c.instance_method(:foo).arity
403 assert_equal(-1, c.new.method(:nothing).unbind.arity)
406 assert 'UnboundMethod#==' do
407 assert_false(Fixnum.instance_method(:+) == Fixnum.instance_method(:-))
408 assert_true(Fixnum.instance_method(:+) == Fixnum.instance_method(:+))
409 assert_false(Fixnum.instance_method(:+) == Float.instance_method(:+))
410 assert_true(UnboundMethod.instance_method(:==) == UnboundMethod.instance_method(:eql?))
413 assert 'UnboundMethod#super_method' do
414 m = Derived.instance_method(:foo)
416 assert_equal(Base.instance_method(:foo), m)
417 assert_nil(m.super_method)
419 m = Object.instance_method(:object_id)
420 assert_nil(m.super_method)
423 assert 'UnboundMethod#bind' do
424 m = Module.new{ def meth() :meth end }.instance_method(:meth)
425 assert_raise(ArgumentError) { m.bind }
426 assert_kind_of Method, m.bind(1)
427 assert_kind_of Method, m.bind(:sym)
428 assert_kind_of Method, m.bind(Object.new)
429 assert_equal(:meth, m.bind(1).call)
430 assert_equal(:meth, m.bind(:sym).call)
431 assert_equal(:meth, m.bind(Object.new).call)
440 assert_raise(TypeError) { sc.instance_method(:foo).bind([]) }
441 assert_raise(TypeError) { Array.instance_method(:each).bind(1) }
442 assert_kind_of Method, Object.instance_method(:object_id).bind(Object.new)