Bug #3350
closedProtected methods & documentation
Description
=begin
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.
=end
Updated by mame (Yusuke Endoh) over 14 years ago
=begin
Hi,
2010/5/27 Marc-Andre Lafortune redmine@ruby-lang.org:
Should I change the doc to reflect the current behavior, as per the patch below?
Agreed. It is more honest.
I'm curious: what examples exist where one would want to match public and protected methods but not private ones?
Because whether protected methods can be called are context-sensitive.
Consider this:
class X
def protected_method; end
protected :protected_method
def foo
X.new.protected_method # succeed to call
X.new.methods.include?(:protected_method) #=> true (as expected)
end
end
X.new.foo
If Object#methods returns only public methods, the above expectation
is not satisfied.
Object#methods may be also context-sensitive (IOW, Object#methods
returns different results depending on where it is called), but the
behavior is more difficult (for me) to understand than current one.
--
Yusuke Endoh mame@tsg.ne.jp
=end
Updated by mame (Yusuke Endoh) over 14 years ago
- Assignee set to marcandre (Marc-Andre Lafortune)
=begin
Hi,
Should I change the doc to reflect the current behavior, as per the patch below?
No objection. Please commit it.
--
Yusuke Endoh mame@tsg.ne.jp
=end
Updated by marcandre (Marc-Andre Lafortune) over 14 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
This issue was solved with changeset r28379.
Marc-Andre, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end