为什么私有setter的行为与其他私有方法不同?

时间:2017-03-21 15:48:57

标签: ruby

这是一个我无法解释的有趣案例。私人制定者看起来像'私人',但有时也有例外。常规私有方法似乎与私有设置者的行为不同:

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是私有方法。

这是怎么回事?

3 个答案:

答案 0 :(得分:4)

私人制定者很特别,因为否则他们根本无法被召唤:

foo = :bar

分配给本地变量foo,它不会发送消息foo=

请注意,如果没有显式接收器,setter不是唯一无法调用的东西。 +@-@!~[][]=+-,{{ 1}},*/%&|^**,{{1} },<<>>======~!~!=<><=以及我忘记的其他一些人如果没有明确的接收者也无法召唤。然后是>=<=>之类的内容,等等。

所有这些都需要例外。不幸的是,其中一些只有例外。

建议从

更改+=的规则
  

只能在没有显式接收器的情况下调用,除了[这个很长的异常列表,这些异常真的很复杂,但仍然不完整]。

  

只能在没有显式接收器或文字特殊变量<<=作为接收器的情况下调用。

保留定义的所有当前属性(最重要的是可以在分析时静态确定)。

But so far, nothing has come of it.

答案 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中privateprotected方法的主要区别。您不能在类的实例上调用private方法,即使在该类中也是如此,而protected允许这样做。