[Bug #3445] 1.9.2-preview3 $B$G(B Object#extend $B$9$k$H(B public_methods(false) $B$+$i%a%=%C

e$B%A%1%C%He(B #3445 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$BC4Ev<Te(B Yusuke E.e$B$K%;%C%He(B

e$B1sF#$G$9!#e(B

e$B85!9$OFC0[%/%i%9$N%a%=%C%I$O0z?t$,e(B false
e$B$G$bNs5s$5$l$F$$$?$N$G$9$,!"e(B
#2993
e$B$N$?$a$KFC0[%/%i%9$N%a%=%C%I$,Ns5s$5$l$J$/$J$C$?$3$H$,860x$G$9!#e(B

Module#public_instance_methods(false):
e$BFC0[%/%i%9$N%a%=%C%I$rNs5s$7$J$$e(B
Object#public_methods(false): e$BFC0[%/%i%9$N%a%=%C%I$rNs5s$r$9$ke(B

e$B$H$9$k%Q%C%A$r=q$$$F$_$^$7$?!#$d$d$3$7$$$G$9$M!#e(B

e$B%F%9%H$N%(%i!<$OA}$($:!"$3$N%A%1%C%H$GJs9p$5$l$F$$$k%3!<%I$O=>MhDL$j$Ne(B
e$B5sF0$K$J$j$^$9!#H?BP$,$J$1$l$P%3%_%C%H$7$^$9!#e(B

diff --git a/class.c b/class.c
index 9a3984a…b6f0999 100644
— a/class.c
+++ b/class.c
@@ -833,7 +833,7 @@ method_entry(ID key, const rb_method_entry_t *me,
st_table *list)
}

static VALUE
-class_instance_method_list(int argc, VALUE *argv, VALUE mod, int
(*func) (ID, long, VALUE))
+class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj,
int (*func) (ID, long, VALUE))
{
VALUE ary;
int recur;
@@ -852,6 +852,7 @@ class_instance_method_list(int argc, VALUE *argv,
VALUE mod, int (*func) (ID, lo
for (; mod; mod = RCLASS_SUPER(mod)) {
st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
if (BUILTIN_TYPE(mod) == T_ICLASS) continue;

  • if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
    if (!recur) break;
    }
    ary = rb_ary_new();
    @@ -891,7 +892,7 @@ class_instance_method_list(int argc, VALUE *argv,
    VALUE mod, int (*func) (ID, lo
    VALUE
    rb_class_instance_methods(int argc, VALUE *argv, VALUE mod)
    {
  • return class_instance_method_list(argc, argv, mod, ins_methods_i);
  • return class_instance_method_list(argc, argv, mod, 0,
    ins_methods_i);
    }

/*
@@ -906,7 +907,7 @@ rb_class_instance_methods(int argc, VALUE *argv,
VALUE mod)
VALUE
rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod)
{

  • return class_instance_method_list(argc, argv, mod,
    ins_methods_prot_i);
  • return class_instance_method_list(argc, argv, mod, 0,
    ins_methods_prot_i);
    }

/*
@@ -929,7 +930,7 @@ rb_class_protected_instance_methods(int argc, VALUE
*argv, VALUE mod)
VALUE
rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod)
{

  • return class_instance_method_list(argc, argv, mod,
    ins_methods_priv_i);
  • return class_instance_method_list(argc, argv, mod, 0,
    ins_methods_priv_i);
    }

/*
@@ -944,7 +945,93 @@ rb_class_private_instance_methods(int argc, VALUE
*argv, VALUE mod)
VALUE
rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
{

  • return class_instance_method_list(argc, argv, mod,
    ins_methods_pub_i);
  • return class_instance_method_list(argc, argv, mod, 0,
    ins_methods_pub_i);
    +}

+/*

    • call-seq:
    • obj.methods    -> array
      
    • Returns a list of the names of methods publicly accessible in
    • obj. This will include all the methods accessible in
    • obj's ancestors.
    • class Klass
      
    •   def kMethod()
      
    •   end
      
    • end
      
    • k = Klass.new
      
    • k.methods[0..9]    #=> [:kMethod, :freeze, :nil?, :is_a?,
      
    •                    #    :class, :instance_variable_set,
      
    •                    #    :methods, :extend, :__send__, 
      

:instance_eval]

    • k.methods.length   #=> 42
      
  • */

+VALUE
+rb_obj_methods(int argc, VALUE *argv, VALUE obj)
+{

  • retry:
  • if (argc == 0) {
  • VALUE args[1];
  • args[0] = Qtrue;
  • return class_instance_method_list(argc, argv, CLASS_OF(obj), 1,
    ins_methods_i);
  • }
  • else {
  • VALUE recur;
  • rb_scan_args(argc, argv, “1”, &recur);
  • if (RTEST(recur)) {
  •  argc = 0;
    
  •  goto retry;
    
  • }
  • return rb_obj_singleton_methods(argc, argv, obj);
  • }
    +}

+/*

    • call-seq:
    • obj.protected_methods(all=true)   -> array
      
    • Returns the list of protected methods accessible to obj. If
    • the all parameter is set to false, only those
      methods
    • in the receiver will be listed.
  • */

+VALUE
+rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj)
+{

  • return class_instance_method_list(argc, argv, CLASS_OF(obj), 1,
    ins_methods_prot_i);
    +}

+/*

    • call-seq:
    • obj.private_methods(all=true)   -> array
      
    • Returns the list of private methods accessible to obj. If
    • the all parameter is set to false, only those
      methods
    • in the receiver will be listed.
  • */

+VALUE
+rb_obj_private_methods(int argc, VALUE *argv, VALUE obj)
+{

  • return class_instance_method_list(argc, argv, CLASS_OF(obj), 1,
    ins_methods_priv_i);
    +}

+/*

    • call-seq:
    • obj.public_methods(all=true)   -> array
      
    • Returns the list of public methods accessible to obj. If
    • the all parameter is set to false, only those
      methods
    • in the receiver will be listed.
  • */

+VALUE
+rb_obj_public_methods(int argc, VALUE *argv, VALUE obj)
+{

  • return class_instance_method_list(argc, argv, CLASS_OF(obj), 1,
    ins_methods_pub_i);
    }

/*
diff --git a/object.c b/object.c
index 414c3a9…f52522d 100644
— a/object.c
+++ b/object.c
@@ -1751,109 +1751,10 @@ rb_mod_const_defined(int argc, VALUE *argv,
VALUE mod)
return RTEST(recur) ? rb_const_defined(mod, id) :
rb_const_defined_at(mod, id);
}

-/*

    • call-seq:
    • obj.methods    -> array
      
    • Returns a list of the names of methods publicly accessible in
    • obj. This will include all the methods accessible in
    • obj's ancestors.
    • class Klass
      
    •   def kMethod()
      
    •   end
      
    • end
      
    • k = Klass.new
      
    • k.methods[0..9]    #=> [:kMethod, :freeze, :nil?, :is_a?,
      
    •                    #    :class, :instance_variable_set,
      
    •                    #    :methods, :extend, :__send__, 
      

:instance_eval]

    • k.methods.length   #=> 42
      
  • */

-static VALUE
-rb_obj_methods(int argc, VALUE *argv, VALUE obj)
-{

  • retry:
  • if (argc == 0) {
  • VALUE args[1];
  • args[0] = Qtrue;
  • return rb_class_instance_methods(1, args, CLASS_OF(obj));
  • }
  • else {
  • VALUE recur;
  • rb_scan_args(argc, argv, “1”, &recur);
  • if (RTEST(recur)) {
  •  argc = 0;
    
  •  goto retry;
    
  • }
  • return rb_obj_singleton_methods(argc, argv, obj);
  • }
    -}

-/*

    • call-seq:
    • obj.protected_methods(all=true)   -> array
      
    • Returns the list of protected methods accessible to obj. If
    • the all parameter is set to false, only those
      methods
    • in the receiver will be listed.
  • */

-static VALUE
-rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj)
-{

  • if (argc == 0) { /* hack to stop warning */
  • VALUE args[1];
  • args[0] = Qtrue;
  • return rb_class_protected_instance_methods(1, args, CLASS_OF(obj));
  • }
  • return rb_class_protected_instance_methods(argc, argv,
    CLASS_OF(obj));
    -}

-/*

    • call-seq:
    • obj.private_methods(all=true)   -> array
      
    • Returns the list of private methods accessible to obj. If
    • the all parameter is set to false, only those
      methods
    • in the receiver will be listed.
  • */

-static VALUE
-rb_obj_private_methods(int argc, VALUE *argv, VALUE obj)
-{

  • if (argc == 0) { /* hack to stop warning */
  • VALUE args[1];
  • args[0] = Qtrue;
  • return rb_class_private_instance_methods(1, args, CLASS_OF(obj));
  • }
  • return rb_class_private_instance_methods(argc, argv,
    CLASS_OF(obj));
    -}

-/*

    • call-seq:
    • obj.public_methods(all=true)   -> array
      
    • Returns the list of public methods accessible to obj. If
    • the all parameter is set to false, only those
      methods
    • in the receiver will be listed.
  • */

-static VALUE
-rb_obj_public_methods(int argc, VALUE *argv, VALUE obj)
-{

  • if (argc == 0) { /* hack to stop warning */
  • VALUE args[1];
  • args[0] = Qtrue;
  • return rb_class_public_instance_methods(1, args, CLASS_OF(obj));
  • }
  • return rb_class_public_instance_methods(argc, argv, CLASS_OF(obj));
    -}
    +VALUE rb_obj_methods(int argc, VALUE *argv, VALUE obj);
    +VALUE rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj);
    +VALUE rb_obj_private_methods(int argc, VALUE *argv, VALUE obj);
    +VALUE rb_obj_public_methods(int argc, VALUE *argv, VALUE obj);

/*

  • call-seq:


Yusuke E. [email protected]

http://redmine.ruby-lang.org/issues/show/3445