Ruby保护可见性从超类调用

时间:2015-07-30 15:54:43

标签: ruby protected nomethoderror

我有一些似乎与某种方式相矛盾的小代码Ruby's documentation

  

第二种可见性是protected。当调用受保护的方法时,发送方必须是接收方的子类,或者接收方必须是发送方的子类。否则将引发NoMethodError

class Test
  def publico(otro)
    otro.prot
  end  
end

class Hija < Test
  protected def prot; end
end

Test.new.publico(Hija.new)

我得到了以下输出:

  

NoMethodError:受保护的方法`prot&#39;呼吁 #     检察署

我错过了什么?显然是选项&#34;接收者必须是发送者的子类&#34;不可用。

2 个答案:

答案 0 :(得分:2)

虽然它对于对保护方法一无所知的父类不起作用,但它适用于定义受保护方法的子类的子类。例如

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

我们可以得出结论,这种行为类似于&#34;发件人或收件人必须继承方法&#34;。有了那个behivaour,我们可以解释一下,既然A(不知道m的存在)和B(它知道存在而不是继承它)都没有使用该方法,它就会引起错误。

虽然这可能是一个错误。

答案 1 :(得分:2)

受保护的方法只能从同一个类或子类的实例中调用。 Hija是Test的子类。测试不是Hija的子类。因此,Hija中受保护的方法不适用于Test的实例。

所以如果你的例子是另一种方式:

class Hija
  protected def prot; end
end
class Test < Hija
  def publico(otro)
    otro.prot
  end
end
Test.new.publico(Hija.new)

工作正常。