了解Ruby中的私有方法 [英] Understanding private methods in Ruby

查看:116
本文介绍了了解Ruby中的私有方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class Example
 private
 def example_test
  puts 'Hello'
 end
end

e = Example.new
e.example_test

这当然是行不通的,因为我们指定的显式接收者-Example( e )的实例,并且违反了私有规则。

This of course will not work, because we specified explicit receiver - instance of Example (e), and that is against a "private rule".

但是我不明白,为什么不能在Ruby中做到这一点:

But I cannot understand, why one cannot do in Ruby this:

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将为您做到这一点(将对self调用private_m)?

The current object inside public_m method definition (i.e. self) is the instance of Foo. So why it is not allowed? To fix that I have to change self.private_m to just private_m. But why this differ, isn't the self an instance of Foo inside public_m? And who is the receiver of bare-word private_m call? Isn't that self - what actually you omit because, Ruby will do it for you (will call private_m on self)?

我希望我不要混淆太多,我对Ruby还是很新鲜。

I hope I didn't confuse it too much, I am still fresh to Ruby.

编辑:
感谢您提供所有答案。将它们放在一起,我能够(最终)看到明显的东西(对于从未见过Ruby的人来说不是那么明显): self 本身可以是
显式和隐式接收器,这有所作为。因此,如果要调用私有方法,有两个规则: self 必须是隐式接收者,并且self必须是当前类的实例(示例-仅在self(如果在实例方法定义内,则在此方法执行期间)才会发生。如果我错了,请纠正我。

Thank you for all the answers. Putting them all together I was able (finally) to grok the obvious (and not so obvious for someone, who have never seen things like Ruby): that self itself can be explicit and implicit receiver and that make the difference. So there are two rules, if you want to call a private method: self must be implicit receiver, and that self must be an instance of current class (Example in that case - and that takes place only when self if inside instance method definition, during this method execution). Please correct me if I am wrong.

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

消息任何在Google跟踪中发现此问题的人:可能会有所帮助- http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby

Message for anyone who could find this question during the google trails: this may be helpful - http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby

推荐答案

这是长短。在Ruby中,private的意思是一种方法,无法通过显式的接收方调用,例如some_instance.private_method(value)。因此,即使隐式接收者是self,在您的示例中您也显式使用self,因此私有方法不可访问。

Here's the short and the long of it. What private means in Ruby is a method cannot be called with an explicit receivers, e.g. some_instance.private_method(value). So even though the implicit receiver is self, in your example you explicitly use self so the private methods are not accessible.

以这种方式考虑,您是否希望能够使用已分配给类实例的变量来调用私有方法?不可以。Self是变量,因此必须遵循相同的规则。但是,当您仅在实例内部调用该方法时,它便会按预期工作,因为您没有显式声明接收方。

Think of it this way, would you expect to be able to call a private method using a variable that you have assigned to an instance of a class? No. Self is a variable so it has to follow the same rules. However when you just call the method inside the instance then it works as expected because you aren't explicitly declaring the receiver.

Ruby是它的实名,您实际上可以调用私有方法使用instance_eval的方法:

Ruby being what it is you actually can call private methods using 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") }

希望更加清晰。

-编辑-

我假设您知道这会起作用:

I'm assuming you knew this will work:

class Foo
 def public_m
  private_m # Removed self.
 end
 private
 def private_m
  puts 'Hello'
 end
end

Foo.new.public_m

这篇关于了解Ruby中的私有方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆