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

ruby-changes:26915

From: nobu <ko1@a...>
Date: Tue, 29 Jan 2013 16:49:33 +0900 (JST)
Subject: [ruby-changes:26915] nobu:r38967 (trunk): proc.c: original arity

nobu	2013-01-29 16:49:22 +0900 (Tue, 29 Jan 2013)

  New Revision: 38967

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38967

  Log:
    proc.c: original arity
    
    * proc.c (rb_mod_method_arity): return original arity of the method if
      aliased because of visibility change, like as Method#arity.

  Added directories:
    trunk/ext/-test-/method/
    trunk/test/-ext-/method/
  Added files:
    trunk/ext/-test-/method/arity.c
    trunk/ext/-test-/method/extconf.rb
    trunk/ext/-test-/method/init.c
    trunk/test/-ext-/method/test_arity.rb
  Modified files:
    trunk/ChangeLog
    trunk/proc.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38966)
+++ ChangeLog	(revision 38967)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Jan 29 16:49:19 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* proc.c (rb_mod_method_arity): return original arity of the method if
+	  aliased because of visibility change, like as Method#arity.
+
 Tue Jan 29 12:05:18 2013  Tanaka Akira  <akr@f...>
 
 	* test/ruby/test_marshal.rb: remove temporally files early.
Index: proc.c
===================================================================
--- proc.c	(revision 38966)
+++ proc.c	(revision 38967)
@@ -1743,10 +1743,26 @@ method_arity(VALUE method) https://github.com/ruby/ruby/blob/trunk/proc.c#L1743
     return rb_method_entry_arity(data->me);
 }
 
+static rb_method_entry_t *
+original_method_entry(VALUE mod, ID id)
+{
+    VALUE rclass;
+    rb_method_entry_t *me;
+    while ((me = rb_method_entry(mod, id, &rclass)) != 0) {
+	rb_method_definition_t *def = me->def;
+	if (!def) break;
+	if (def->type != VM_METHOD_TYPE_ZSUPER) break;
+	mod = RCLASS_SUPER(rclass);
+	id = def->original_id;
+    }
+    return me;
+}
+
 int
 rb_mod_method_arity(VALUE mod, ID id)
 {
-    rb_method_entry_t *me = rb_method_entry(mod, id, 0);
+    rb_method_entry_t *me = original_method_entry(mod, id);
+    if (!me) return 0;		/* should raise? */
     return rb_method_entry_arity(me);
 }
 
Index: ext/-test-/method/init.c
===================================================================
--- ext/-test-/method/init.c	(revision 0)
+++ ext/-test-/method/init.c	(revision 38967)
@@ -0,0 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/method/init.c#L1
+#include "ruby.h"
+
+#define init(n) {void Init_##n(VALUE klass); Init_##n(klass);}
+
+void
+Init_method(void)
+{
+    VALUE mBug = rb_define_module("Bug");
+    VALUE klass = rb_define_module_under(mBug, "Method");
+    TEST_INIT_FUNCS(init);
+}

Property changes on: ext/-test-/method/init.c
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ext/-test-/method/extconf.rb
===================================================================
--- ext/-test-/method/extconf.rb	(revision 0)
+++ ext/-test-/method/extconf.rb	(revision 38967)
@@ -0,0 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/method/extconf.rb#L1
+$srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
+inits = $srcs.map {|s| File.basename(s, ".*")}
+inits.delete("init")
+inits.map! {|s|"X(#{s})"}
+$defs << "-DTEST_INIT_FUNCS(X)=\"#{inits.join(' ')}\""
+create_makefile("-test-/method")

Property changes on: ext/-test-/method/extconf.rb
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ext/-test-/method/arity.c
===================================================================
--- ext/-test-/method/arity.c	(revision 0)
+++ ext/-test-/method/arity.c	(revision 38967)
@@ -0,0 +1,22 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/method/arity.c#L1
+#include "ruby.h"
+
+static VALUE
+obj_method_arity(VALUE self, VALUE obj, VALUE mid)
+{
+    int arity = rb_obj_method_arity(obj, rb_check_id(&mid));
+    return INT2FIX(arity);
+}
+
+static VALUE
+mod_method_arity(VALUE self, VALUE mod, VALUE mid)
+{
+    int arity = rb_mod_method_arity(mod, rb_check_id(&mid));
+    return INT2FIX(arity);
+}
+
+void
+Init_arity(VALUE mod)
+{
+    rb_define_module_function(mod, "obj_method_arity", obj_method_arity, 2);
+    rb_define_module_function(mod, "mod_method_arity", mod_method_arity, 2);
+}

Property changes on: ext/-test-/method/arity.c
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: test/-ext-/method/test_arity.rb
===================================================================
--- test/-ext-/method/test_arity.rb	(revision 0)
+++ test/-ext-/method/test_arity.rb	(revision 38967)
@@ -0,0 +1,37 @@ https://github.com/ruby/ruby/blob/trunk/test/-ext-/method/test_arity.rb#L1
+require '-test-/method'
+require 'test/unit'
+
+class TestMethod < Test::Unit::TestCase
+  class TestArity < Test::Unit::TestCase
+    class A
+      def foo0()
+      end
+      def foom1(*a)
+      end
+      def foom2(a,*b)
+      end
+      def foo1(a)
+      end
+      def foo2(a,b)
+      end
+    end
+
+    class B<A
+      private :foo1, :foo2
+    end
+
+    METHODS = {foo0: 0, foo1: 1, foo2: 2, foom1: -1, foom2: -2}
+
+    def test_base
+      METHODS.each do |name, arity|
+        assert_equal(arity, Bug::Method.mod_method_arity(A, name), "A##{name}")
+      end
+    end
+
+    def test_zsuper
+      METHODS.each do |name, arity|
+        assert_equal(arity, Bug::Method.mod_method_arity(B, name), "B##{name}")
+      end
+    end
+  end
+end

Property changes on: test/-ext-/method/test_arity.rb
___________________________________________________________________
Added: svn:eol-style
   + LF


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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