From: Marc-Andre Lafortune Date: 2010-05-27T15:28:51+09:00 Subject: [ruby-core:30449] [Bug #3350] Protected methods & documentation Bug #3350: Protected methods & documentation http://redmine.ruby-lang.org/issues/show/3350 Author: Marc-Andre Lafortune Status: Open, Priority: Normal Category: core, Target version: 1.9.2 ruby -v: trunk The official doc currently states that Object#methods "returns a list of the names of methods publicly accessible". Similarly, Module#instance_methods states that it returns "the public methods" of the Module. Note that the doc was modified in r19900, but I feel the wording "instance method that is callable from outside" still implies public only. The current behavior doesn't fit the doc, since protected methods are also matched: class X def protected_method; end protected :protected_method end X.new.methods.include?(:protected_method) #=> true X.instance_methods.include?(:protected_method) #=> true The documentation for Module#method_defined? on the other states it matches public and protected methods. Should I change the doc to reflect the current behavior, as per the patch below? I'm asking in part because I lack experience with protected methods and I am surprised by the fact that protected methods are matched by these "default" methods. The fact that Object#respond_to? also matches protected is even less practical since there is no "public-only" equivalent. I might be mistaken, but I believe that the only way of knowing if obj responds publicly to :foo is to do something like publicly_responds = obj.public_method(:foo) rescue false I dislike the fact that obj.respond_to?(:foo) && obj.foo might raise a NoMethodError. It looks like this was discussed a in [ruby_dev:40461], but I don't know the outcome. I'm curious: what examples exist where one would want to match public and protected methods but not private ones? Matz, is there any chance the handling of #respond_to?, #methods, etc..., with regards to protected methods will change (in 1.9.2 or later)? -- Marc-Andr�� diff --git a/class.c b/class.c index c586f7a..683fa7b 100644 --- a/class.c +++ b/class.c @@ -865,8 +865,8 @@ class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, lo * call-seq: * mod.instance_methods(include_super=true) -> array * - * Returns an array containing the names of instance methods that is callable - * from outside in the receiver. For a module, these are the public methods; + * Returns an array containing the names of the public and protected instance + * methods in the receiver. For a module, these are the public and protected methods; * for a class, they are the instance (not singleton) methods. With no * argument, or with an argument that is false, the * instance methods in mod are returned, otherwise the methods @@ -954,6 +954,7 @@ rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod) * Returns an array of the names of singleton methods for obj. * If the optional all parameter is true, the list will include * methods in modules included in obj. + * Only public and protected singleton methods are returned. * * module Other * def three() end diff --git a/object.c b/object.c index a7f05a1..351d16f 100644 --- a/object.c +++ b/object.c @@ -1755,7 +1755,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod) * call-seq: * obj.methods -> array * - * Returns a list of the names of methods publicly accessible in + * Returns a list of the names of public and protected methods of * obj. This will include all the methods accessible in * obj's ancestors. * ---------------------------------------- http://redmine.ruby-lang.org