[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]