这是一个我无法解释的有趣案例。私人制定者看起来像'私人',但有时也有例外。常规私有方法似乎与私有设置者的行为不同:
class TestClass
def do
self.foo = :bar # fine
self.baz # error
end
private
def foo=(other)
@foo = other
end
def baz
end
end
TestClass.new.do
上面的代码设置@foo
就好了,尽管被调用了明确的self
。然后它无法调用#baz
,因为#baz
是私有方法。
这是怎么回事?
答案 0 :(得分:4)
私人制定者很特别,因为否则他们根本无法被召唤:
foo = :bar
分配给本地变量foo
,它不会发送消息foo=
。
请注意,如果没有显式接收器,setter不是唯一无法调用的东西。 +@
,-@
,!
,~
,[]
,[]=
,+
,-
,{{ 1}},*
,/
,%
,&
,|
,^
,**
,{{1} },<<
,>>
,==
,===
,=~
,!~
,!=
,<
, >
,<=
以及我忘记的其他一些人如果没有明确的接收者也无法召唤。然后是>=
,<=>
之类的内容,等等。
所有这些都需要例外。不幸的是,其中一些只有例外。
建议从
更改+=
的规则
只能在没有显式接收器的情况下调用,除了[这个很长的异常列表,这些异常真的很复杂,但仍然不完整]。
到
只能在没有显式接收器或文字特殊变量
<<=
作为接收器的情况下调用。
保留定义的所有当前属性(最重要的是可以在分析时静态确定)。
答案 1 :(得分:1)
如果在使用setter方法时不使用self
,则会将值分配给局部变量。 More details
在下面的代码中,我已将@foo
从作业中移除到foo,您可以看到未使用setter b / c nil
是 def do
foo = :bar # fine
baz # error
puts @foo # prints nil
puts foo # prints 'bar'
end
:< / p>
class Herbivore[F <: Vegetable](name :String) extends Animal[Vegetable](name)
答案 2 :(得分:1)
这就是private
的工作原理,它是ruby中private
和protected
方法的主要区别。您不能在类的实例上调用private
方法,即使在该类中也是如此,而protected
允许这样做。