Why can I access private/protected methods using Object#send in Ruby?

Deadly 提交于 2019-12-21 17:02:08

问题


The class

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

instance of A

a = A.new

test

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

test output

fail
bar
fail
fail
fail

.send test

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

.send output

foo
bar
zim
dib
fail

The question

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

Perhaps more important:

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?


回答1:


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

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.

As for what private, protected and public mean:

  • 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)


来源:https://stackoverflow.com/questions/2519136/why-can-i-access-private-protected-methods-using-objectsend-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!