documentation for protected methods
I think it is correct before the change.
Which is correct?
Updated by jeremyevans0 (Jeremy Evans) 25 days ago
I don't think it is correct before or after the change, though after comes closer.
When calling a protected method the sender must be a subclass of the receiver or the receiver must be a subclass of the sender. Otherwise a NoMethodError will be raised.
When calling a protected method the receiver must inherit the Class or Module which defines the method. Otherwise a NoMethodError will be raised.
The problems with the before case:
- receiver and sender may not be a class, in which case it makes no sense as stated.
subclass of the (receiver|sender)means
subclass of the (receiver|sender)'s class, it is still wrong.
Consider this example:
module M protected def x; 1 end end c1 = Object.new c2 = Object.new c1.extend(M) def c2.y(c) c.x end c2.y(c1) rescue (p $!) # NoMethodError: protected method `x' called c2.extend(M) p c2.y(c1) # => 1
c2 are both instances of
Object. The first call to
c2.y raises because it calls
c1.x, a method defined in
c1 extends but
c2 does not. However, after
M, the protected call works.
So the new language is closer. The bug in the new language is
receiver should be changed to
sender. If the
receiver didn't inherit the class or module that defined the method, you couldn't call the method on the receiver (undefined method error, or it would call a different method).
Here's another example with more traditional subclassing:
class A def x1(b) b.x end def y1(b) b.y end protected def x; 0 end protected def y; 1; end end class B < A protected def x; 1; end end a = A.new b = B.new p a.x1(b) rescue (p $!) # NoMethodError: protected method `x' p a.y1(b) rescue (p $!) # 1 p b.x1(a) rescue (p $!) # 0 p b.y1(a) rescue (p $!) # 1
This shows that a superclass instance cannot call a protected method on a subclass instance, but a subclass instance can call a protected method on a superclass instance. Superclass instance cannot call subclass protected method because superclass instance does not inherit the class/module defining the method. Subclass instance can call superclass protected method because subclass instance does inherit the class/module defining the method. This again shows the before language was incorrect, but the after language is better.
sender to fix the issue in the current language.