I have this little code that seems to contradict in some way Ruby's documentation:
The second visibility is
protected
. 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 aNoMethodError
will be raised.
class Test
def publico(otro)
otro.prot
end
end
class Hija < Test
protected def prot; end
end
Test.new.publico(Hija.new)
I get the folowing output:
NoMethodError: protected method `prot' called for # publico
What am I missing? Apparently the option " the receiver must be a subclass of the sender" is not available.
Although it does not work on Parent Class which know nothing of the protected method, it works on the Subclasses of Subclass which define the protected method. Eg.
class A
def n(other)
other.m
end
end
class B < A
def m
1
end
protected :m
end
class C < B
end
class D < C
end
a = A.new
b = B.new
c = C.new
d = C.new
c.n b #=> 1 -- sender C is a subclass of B
b.n b #=> 1 -- m called on defining class
a.n b # raises NoMethodError although reciever B is a subclass of sender A
b.n c #=> 1 -- reciever C is subclass of sender B
c.n d #=> 1 -- reciever D is sublcass of sender C
We can probably conclude that the behaviour is something like " either the sender or the reciever must have inherited the method". With that behivaour, we can explain that since neither A (which does not know the existence of m) nor B (which knows the existence but not inherited it) ineherited the method, it raises the error.
Although there is also a possibility that this could be a bug.