为什么我可以在Ruby中使用Object#send访问私有/受保护的方法? [英] Why can I access private/protected methods using Object#send in Ruby?

查看:111
本文介绍了为什么我可以在Ruby中使用Object#send访问私有/受保护的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class A

  private
  def foo
    puts :foo
  end

  public
  def bar
    puts :bar
  end

  private
  def zim
    puts :zim
  end

  protected
  def dib
    puts :dib
  end
end

A的实例

a = A.new

测试

a.foo rescue puts :fail
a.bar rescue puts :fail
a.zim rescue puts :fail
a.dib rescue puts :fail
a.gaz rescue puts :fail

测试输出

fail
bar
fail
fail
fail

.发送测试

[:foo, :bar, :zim, :dib, :gaz].each { |m| a.send(m) rescue puts :fail }

.发送输出

foo
bar
zim
dib
fail

问题

标为测试输出"的部分是预期的结果.那么,为什么我只能通过Object#send访问私有/受保护的方法?

The question

The section labeled "Test Output" is the expected result. So why can I access private/protected method by simply Object#send?

在Ruby中public/private/protected有什么区别?什么时候使用每个?有人可以提供privateprotected用法的真实示例吗?

What is the difference between public/private/protected in Ruby? When to use each? Can someone provide real world examples for private and protected usage?

推荐答案

技术上:因为send不执行任何操作来检查方法的可见性. (这样做会做更多的工作.)

Technically: Because send doesn't do anything to check method visibility. (It would be more work to do so.)

从哲学上讲:Ruby是一种非常宽松的语言.您已经可以打开一个类并公开您想要的任何方法.语言设计者以允许其覆盖private通常施加的限制的方式来实现send. Ruby 1.9最初将具有两个变体,一个是private-尊敬的send和一个不安全的变体,称为send!,但是为了向后兼容,显然删除了它.

Philosophically: Ruby is a very permissive language. You can already just open up a class and make any method you want public. The language designers implemented send in a way that allows it to override the restrictions normally imposed by private. Ruby 1.9 was originally going to have two variants, a private-respecting send and an unsafe variant called send!, but this was apparently dropped for backwards compatibility.

关于privateprotectedpublic的含义:

  • public方法可以被任何发送者调用
  • protected方法不能在该方法的类的实例或子类的实例之外调用.
  • private方法不能用显式接收器调用(有两个例外,例如setter方法,它们总是必须有一个显式接收器,因此可以在类中以这种方式调用)
  • public methods can be called by any sender
  • protected methods cannot be called outside of an instance of the method's class or an instance of a subclass
  • private methods cannot be called with an explicit receiver (with a couple of exceptions, such as setter methods, which always have to have an explicit receiver, and so can be called within the class that way)

这篇关于为什么我可以在Ruby中使用Object#send访问私有/受保护的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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