ruby-changes:3972
From: ko1@a...
Date: Thu, 14 Feb 2008 00:04:22 +0900 (JST)
Subject: [ruby-changes:3972] mame - Ruby:r15462 (trunk): * eval.c (eval): allow to eval in a binding that has a singleton method.
mame 2008-02-14 00:03:59 +0900 (Thu, 14 Feb 2008) New Revision: 15462 Modified files: trunk/ChangeLog trunk/eval.c trunk/test/ruby/test_method.rb trunk/test/ruby/test_proc.rb Log: * eval.c (eval): allow to eval in a binding that has a singleton method. [ruby-dev:33763] * test/ruby/test_proc.rb: add tests to achieve over 70% test coverage of time.c. * test/ruby/test_method.rb: ditto. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_proc.rb?r1=15462&r2=15461&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15462&r2=15461&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval.c?r1=15462&r2=15461&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_method.rb?r1=15462&r2=15461&diff_format=u Index: ChangeLog =================================================================== --- ChangeLog (revision 15461) +++ ChangeLog (revision 15462) @@ -1,3 +1,13 @@ +Thu Feb 14 00:02:19 2008 Yusuke Endoh <mame@t...> + + * eval.c (eval): allow to eval in a binding that has a singleton method. + [ruby-dev:33763] + + * test/ruby/test_proc.rb: add tests to achieve over 70% test coverage + of time.c. + + * test/ruby/test_method.rb: ditto. + Wed Feb 13 22:46:36 2008 Tanaka Akira <akr@f...> * lib/pathname.rb (Pathname#sub_ext): new method. [ruby-list:44608] Index: eval.c =================================================================== --- eval.c (revision 15461) +++ eval.c (revision 15462) @@ -1700,7 +1700,7 @@ volatile VALUE iseqval; if (scope != Qnil) { - if (CLASS_OF(scope) == rb_cBinding) { + if (rb_obj_is_kind_of(scope, rb_cBinding)) { GetBindingPtr(scope, bind); envval = bind->env; stored_cref_stack = bind->cref_stack; Index: test/ruby/test_proc.rb =================================================================== --- test/ruby/test_proc.rb (revision 15461) +++ test/ruby/test_proc.rb (revision 15462) @@ -1,6 +1,15 @@ require 'test/unit' class TestProc < Test::Unit::TestCase + def setup + @verbose = $VERBOSE + $VERBOSE = nil + end + + def teardown + $VERBOSE = @verbose + end + def test_proc p1 = proc{|i| i} assert_equal(2, p1.call(2)) @@ -200,4 +209,92 @@ assert_equal(fib, [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]) end + + def test_dup_clone + b = proc {|x| x + "bar" } + class << b; attr_accessor :foo; end + + bd = b.dup + assert_equal("foobar", bd.call("foo")) + assert_raise(NoMethodError) { bd.foo = :foo } + assert_raise(NoMethodError) { bd.foo } + + bc = b.clone + assert_equal("foobar", bc.call("foo")) + bc.foo = :foo + assert_equal(:foo, bc.foo) + end + + def test_binding + b = proc {|x, y, z| proc {}.binding }.call(1, 2, 3) + class << b; attr_accessor :foo; end + + bd = b.dup + assert_equal([1, 2, 3], bd.eval("[x, y, z]")) + assert_raise(NoMethodError) { bd.foo = :foo } + assert_raise(NoMethodError) { bd.foo } + + bc = b.clone + assert_equal([1, 2, 3], bc.eval("[x, y, z]")) + bc.foo = :foo + assert_equal(:foo, bc.foo) + + b = nil + 1.times { x, y, z = 1, 2, 3; b = binding } + assert_equal([1, 2, 3], b.eval("[x, y, z]")) + end + + def test_proc_lambda + assert_raise(ArgumentError) { proc } + assert_raise(ArgumentError) { lambda } + + o = Object.new + def o.foo + b = nil + 1.times { b = lambda } + b + end + assert_equal(:foo, o.foo { :foo }.call) + + def o.foo(&b) + b = nil + 1.times { b = lambda } + b + end + assert_equal(:foo, o.foo { :foo }.call) + end + + def test_arity2 + assert_equal(0, method(:proc).to_proc.arity) + assert_equal(-1, proc {}.curry.arity) + end + + def test_proc_location + t = Thread.new { sleep } + assert_raise(ThreadError) { t.instance_eval { initialize { } } } + t.kill + end + + def test_eq2 + b1 = proc { } + b2 = b1.dup + assert(b1 == b2) + end + + def test_to_proc + b = proc { :foo } + assert_equal(:foo, b.to_proc.call) + end + + def test_localjump_error + o = Object.new + def foo; yield; end + exc = foo rescue $! + assert_nil(exc.exit_value) + assert_equal(:noreason, exc.reason) + end + + def test_binding2 + assert_raise(ArgumentError) { proc {}.curry.binding } + end end Index: test/ruby/test_method.rb =================================================================== --- test/ruby/test_method.rb (revision 15461) +++ test/ruby/test_method.rb (revision 15462) @@ -1,6 +1,15 @@ require 'test/unit' class TestMethod < Test::Unit::TestCase + def setup + @verbose = $VERBOSE + $VERBOSE = nil + end + + def teardown + $VERBOSE = @verbose + end + def m0() end def m1(a) end def m2(a, b) end @@ -52,4 +61,143 @@ assert_equal(:m, Class.new {define_method(:m) {tap{return __method__}}}.new.m) assert_nil(eval("class TestCallee; __method__; end")) end + + def test_body + o = Object.new + def o.foo; end + assert_nothing_raised { VM::InstructionSequence.disasm(o.method(:foo)) } + end + + def test_new + c1 = Class.new + c1.class_eval { def foo; :foo; end } + c2 = Class.new(c1) + c2.class_eval { private :foo } + o = c2.new + o.extend(Module.new) + assert_raise(NameError) { o.method(:bar) } + assert_raise(NameError) { o.public_method(:foo) } + assert_equal(:foo, o.method(:foo).call) + end + + def test_eq + o = Object.new + class << o + def foo; end + alias bar foo + def baz; end + end + assert_not_equal(o.method(:foo), nil) + m = o.method(:foo) + def m.foo; end + assert_not_equal(o.method(:foo), m) + assert_equal(o.method(:foo), o.method(:foo)) + assert_equal(o.method(:foo), o.method(:bar)) + assert_not_equal(o.method(:foo), o.method(:baz)) + end + + def test_hash + o = Object.new + def o.foo; end + assert_kind_of(Integer, o.method(:foo).hash) + end + + def test_receiver_name_owner + o = Object.new + def o.foo; end + m = o.method(:foo) + assert_equal(o, m.receiver) + assert_equal("foo", m.name) + assert_equal(class << o; self; end, m.owner) + end + + def test_instance_method + c = Class.new + c.class_eval do + def foo; :foo; end + private :foo + end + o = c.new + o.method(:foo).unbind + assert_raise(NoMethodError) { o.foo } + c.instance_method(:foo).bind(o) + assert_equal(:foo, o.instance_eval { foo }) + assert_raise(NameError) { c.public_instance_method(:foo) } + def o.bar; end + m = o.method(:bar).unbind + assert_raise(TypeError) { m.bind(Object.new) } + end + + def test_define_method + c = Class.new + c.class_eval { def foo; :foo; end } + o = c.new + def o.bar; :bar; end + assert_raise(TypeError) do + c.class_eval { define_method(:foo, :foo) } + end + assert_raise(ArgumentError) do + c.class_eval { define_method } + end + c2 = Class.new(c) + c2.class_eval { define_method(:baz, o.method(:foo)) } + assert_equal(:foo, c2.new.baz) + assert_raise(TypeError) do + Class.new.class_eval { define_method(:foo, o.method(:foo)) } + end + assert_raise(TypeError) do + Class.new.class_eval { define_method(:bar, o.method(:bar)) } + end + + o = Object.new + def o.foo(c) + c.class_eval { define_method(:foo) } + end + c = Class.new + o.foo(c) { :foo } + assert_equal(:foo, c.new.foo) + + o = Object.new + o.instance_eval { define_singleton_method(:foo) { :foo } } + assert_equal(:foo, o.foo) + end + + def test_clone + o = Object.new + def o.foo; :foo; end + m = o.method(:foo) + def m.bar; :bar; end + assert_equal(:foo, m.clone.call) + assert_equal(:bar, m.clone.bar) + end + + def test_call + o = Object.new + def o.foo; p 1; end + def o.bar(x); x; end + m = o.method(:foo) + m.taint + assert_raise(SecurityError) { m.call } + end + + def test_inspect + o = Object.new + def o.foo; end + m = o.method(:foo) + assert_equal("#<Method: #{ o.inspect }.foo>", m.inspect) + m = o.method(:foo) + assert_equal("#<UnboundMethod: #{ class << o; self; end.inspect }#foo>", m.unbind.inspect) + + c = Class.new + c.class_eval { def foo; end; } + m = c.new.method(:foo) + assert_equal("#<Method: #{ c.inspect }#foo>", m.inspect) + m = c.instance_method(:foo) + assert_equal("#<UnboundMethod: #{ c.inspect }#foo>", m.inspect) + + c2 = Class.new(c) + c2.class_eval { private :foo } + m2 = c2.new.method(:foo) + assert_equal("#<Method: #{ c2.inspect }(#{ c.inspect })#foo>", m2.inspect) + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/