澄清“私人"的定义和“受保护"在红宝石? [英] Clarify definitions of "private" and "protected" in Ruby?

查看:65
本文介绍了澄清“私人"的定义和“受保护"在红宝石?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果一个方法是受保护的,它可以被定义的任何实例调用类或其子类.如果一个方法是私有的,它只能在内部调用调用对象的上下文——永远不可能访问另一个直接调用对象的私有方法,即使对象属于同一个类作为来电者.

If a method is protected, it may be called by any instance of the defining class or its subclasses. If a method is private, it may be called only within the context of the calling object—it is never possible to access another object’s private methods directly, even if the object is of the same class as the caller.

Ruby 编程,类、对象和变量:访问控制"

Programming Ruby, "Classes, Objects, and Variables: Access Control"

这个定义是我在搜索 ruby​​ 中私有方法和受保护方法之间的区别时从网络得到的.

This definition i got from net when searching for the difference between private and protected methods in ruby.

我对此有两个疑问

class Abc
  def abc
    xyz
  end
 protected 
  def xyz
    p "hai"
  end
end

a=Abc.new
a.abc

在这里,我在对象 a 上隐式调用 xyz,这就是我将如何调用 xyz,即使它是私有的.所以它可以被定义类的任何实例调用";这是什么意思??????

In this i am calling xyz implicitly on object a, this is how i will call xyz even if it is private.So "it may be called by any instance of the defining class" what does this mean ?????

其次,

 class Abc
   def abc(obj)
     obj.xyz1
     obj.xyz2
     obj.xyz3
   end
 end

 class Xyz
   def xyz1
     p "called"
   end

  private 
   def xyz2
     p "called"
   end

  protected
   def xyz3
     p "called"
   end

 end

 a=Abc.new
 b=Xyz.new
 a.abc(b)

在这里我可以在对象 a 上调​​用 obj b 的 xyz1 方法.但是我不能在对象 a 上调​​用 obj b 的受保护的 xyz3 和私有方法 xyz2 方法.所以永远不可能直接访问另一个对象的私有方法,即使该对象与调用者属于同一类."这到底是什么意思???

In this i can call obj b's xyz1 method on object a.But i cant call obj b's protected xyz3 and private method xyz2 method on object a.So "it is never possible to access another object’s private methods directly, even if the object is of the same class as the caller." what does this exact mean???

谁能用更好的例子帮助我理解这一点????

can anybody help me to understand this one with better examples????

推荐答案

私有方法

为了定义私有方法,我们使用了private 关键字,它实际上是一个在名为Module 的类中实现的内置方法.私有方法只能由定义它的类(或其子类之一)中的另一个方法调用.

Private Methods

To define a private method, we use the private keyword, which is actually a built-in method implemented in a class called Module. A private method can only be called by another method within the class on which it was defined (or one of its subclasses).

class Koan
  def call_say_koan
    say_koan
  end

  private
    def say_koan
      puts "What is the sound of one hand clapping?"
    end
end

k = Koan.new
k.say_koan    # Output: NoMethodError: private method `say_koan' called for #<Koan:0x000000021e7380>
k.call_say_koan        # Output: What is the sound of one hand clapping?

在上面的例子中,我们不能直接(从类外部)调用 say_koan 私有方法,但我们可以调用 call_say_koan 公共方法,而后者又调用 say_koan.

In the above example, we could not call the say_koan private method directly (from outside the class), but we could call the call_say_koan public method which, in turn, called say_koan.

同样在上面的例子中,使用了没有参数的内置私有方法.因此,它下面定义的所有方法都被设为私有.

Also in the above example, the built-in private method was used with no arguments. Hence, all methods defined below it were made private.

私有方法也可以与先前定义的方法名称(作为符号传递)一起用作参数.

The private method can also be used with previously defined method names (passed as symbols) as arguments.

class Foo
  def some_method
  end

  private :some_method
end

为了使类方法私有,请使用 private_class_method 关键字/方法而不是私有.

In order to make a class method private, use the private_class_method keyword/method instead of private.

不能用接收者调用私有方法,比如 self.尝试在 call_say_koan 中以 self 作为接收者 (self.say_koan) 调用 say_koan 方法将导致以下异常:

Private methods can't be called with a receiver, such as self. Trying to call the say_koan method with self as a receiver (self.say_koan) within call_say_koan would result in the following exception:

NoMethodError: private method `say_koan' called for #<Koan:0x000000021eb548>

从 Ruby 2.0 开始,respond_to?当给定私有方法作为参数时,方法将返回 false.

As of Ruby 2.0, the respond_to? method will return false when given a private method as an argument.

k.respond_to? :say_koan  # Output: => false

要列出类中的所有私有实例方法,请使用 private_instance_methods 内置方法.对于私有类方法,请使用 private_methods.

To list all private instance methods in a class, use the private_instance_methods built-in method. For private class methods, use private_methods.

Koan.private_instance_methods(false)  # Output => [:say_koan]

受保护的方法

要定义受保护的方法,我们使用 protected 关键字(实际上是一个方法).与私有方法一样,受保护的方法也可以由定义它的类(或其子类之一)中的其他方法调用.不同的是,受保护的方法也可以从同一个类的其他实例中调用.

Protected Methods

To define a protected method, we use the protected keyword (which is actually a method). Like private methods, protected methods can also be called by other methods within the class on which it was defined (or one of its subclasses). The difference is, protected methods can also be called from within other instances of the same class.

没有受保护的类方法,Ruby 只支持受保护的实例方法.

There is no such thing as a protected a class method, Ruby only supports protected instance methods.

假设我们需要选择一些冥想者来参与一项研究.要找到最有经验的冥想者,我们需要比较他们的冥想总时间.但是,我们不希望小时数可见.

Let's suppose we need to select a few meditators to participate in a study. To find the most experienced meditators, we need to compare their total hours of meditation. However, we don't want the number of hours to be visible.

class Meditator
  def initialize(hours)
    @hours = hours
  end

  def more_experienced?(other_person)
    hours > other_person.hours
  end

  protected
    attr_reader :hours  # We have made the accessor protected
end

m1 = Meditator.new 3000
m2 = Meditator.new 5000

m2.more_experienced? m1  # Output: => true
m1.more_experienced? m2  # Output: => false

类似的代码可用于保护任何类型的敏感数据免受外部访问(类及其实例之外),尽管受保护的方法在 Ruby 中并不常用.

Similar code could be used to protect any kind of sensitive data from outside access (outside the class and its instances), although protected methods are not commonly employed in Ruby.

当不带参数调用时(如上例所示),protected 方法会将其下定义的所有方法都转换为 protected 方法.它还可以用于保护先前定义的方法,如下例所示.

When called with no arguments (as in the above example), the protected method turns all methods defined below it into protected methods. It can also be used to protect previously defined methods, as in the following example.

class Foo
  def some_method
  end

  protected :some_method
end

要列出类中所有受保护的实例方法,请使用 protected_instance_methods 内置方法.对于受保护的类方法,请使用 protected_methods.

To list all protected instance methods in a class, use the protected_instance_methods built-in method. For protected class methods, use protected_methods.

Meditator.protected_instance_methods(false)  # Output: => [:hours]

这篇关于澄清“私人"的定义和“受保护"在红宝石?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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