了解Ruby中的私有方法
class Example private def example_test puts 'Hello' end end e = Example.new e.example_test
这当然是行不通的,因为我们指定了示例( e
)的显式接收者实例,而这是针对“私有规则”的。
但是我不明白,为什么在Ruby中不能这样做:
class Foo def public_m self.private_m # <= end private def private_m puts 'Hello' end end Foo.new.public_m
public_m
方法定义中的当前对象(即self
)是Foo的实例。 那么为什么不允许? 要解决这个问题,我必须将self.private_m
更改为private_m
。 但是为什么这个不一样,是不是self
是public_m
里的Foo的一个实例呢? 谁是裸字private_m
电话的接收者? 不是那个self
– 你实际上忽略了什么,因为Ruby会为你做(将自己调用private_m)?
我希望我没有太多混淆,对于Ruby我还是很新鲜的。
编辑:谢谢你的所有答案。 把它们放在一起,我终于能够明白(对于从未见过像Ruby这样的人的人来说并不那么明显): self
本身可以是明确的和隐含的接受者,并且能够产生变化。 所以有两个规则,如果你想调用一个私有方法: self
必须是隐式的接收方,而且这个self必须是当前类的一个实例(在这种情况下是例子 – 而且只有在内部实例方法定义的时候才发生,在这个方法执行期间)。 如果我错了,请纠正我。
class Example # self as an explicit receiver (will throw an error) def explicit self.some_private_method end # self as an implicit receiver (will be ok) def implicit some_private_method end private def some_private_method; end end Example.new.implicit
任何人都可以在谷歌path中find这个问题的消息:这可能是有帮助的 – http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby
这是短而长的。 Ruby中的私有方法是不能用明确的接收方来调用的,例如some_instance.private_method(value)。 因此,即使隐式接收者是自己的,在你的例子中,你明确地使用self,所以私有方法是不可访问的。
想想这样,你会期望能够使用你已经分配给一个类的实例的variables来调用私有方法吗? 自我是一个variables,所以它必须遵循相同的规则。 然而,当你只是调用实例内的方法,那么它按预期工作,因为你没有明确声明接收器。
Ruby实际上可以使用instance_eval调用私有方法:
class Foo private def bar(value) puts "value = #{value}" end end f = Foo.new begin f.bar("This won't work") rescue Exception=>e puts "That didn't work: #{e}" end f.instance_eval{ bar("But this does") }
希望有一点更清楚。
– 编辑 –
我假设你知道这将工作:
class Foo def public_m private_m # Removed self. end private def private_m puts 'Hello' end end Foo.new.public_m
Ruby中的private
定义是“只能在没有明确接收者的情况下调用”。 这就是为什么你只能在没有明确接收者的情况下调用私有方法。 没有其他解释。
请注意,该规则实际上存在一个例外:由于局部variables和方法调用之间的不确定性,下面将始终parsing为对局部variables的赋值:
foo = :bar
那么,如果你想叫一个叫foo=
的作家,你会怎么做呢? 那么你必须添加一个明确的接收者,因为没有接收者,Ruby根本就不知道你想调用方法foo=
而不是分配给局部variablesfoo
:
self.foo = :bar
但是,如果你想打电话给一个叫做foo=
的private
作家,你会怎么做呢? 你不能写self.foo =
因为foo=
是private
,因此不能用明确的接收者来调用。 那么,实际上对于这个特定的情况(以及这种情况),实际上可以使用明确的self
接收者来调用private
作家。
这很奇怪,但许多关于Ruby可见性修饰符的东西都很奇怪。 即使self
是隐式的接收者,但实际上拼写出来使得它在Ruby运行时眼中是明确的。 当说私人方法不能用一个明确的接收者来调用的时候,那就是这个意思,甚至是self
计数。
IIRC,私人方法只允许隐式接收器(当然,它总是自我)。
对不起,我先前的答案。 我只是不明白你的问题。
我改变你的代码是这样的:
class Foo def public_m private_m # <= end def Foo.static_m puts "static" end def self.static2_m puts "static 2" end private def private_m puts 'Hello' end end Foo.new.public_m Foo.static_m Foo.static2_m
这里是一个实例方法的调用:
def public_m private_m # <= end
这里是一个类方法的调用:
def Foo.static_m puts "static" end def self.static2_m puts "static 2" end Foo.static_m Foo.static2_m
不完全回答问题,但可以这样调用私有方法
class Example private def example_test puts 'Hello' end end e = Example.new e.send(:example_test)