How to access private methods

I understand what it privatemeans to be private to an instance. Private methods cannot be called with an explicit receiver, even self. To call a private method, I have to go through the process as shown below:

class Sample
  def foo
    baz
  end

  private
  def baz

  end
 end 

Sample.new.foo

This will call a private method baz. Is there a way to directly call a private method with an explicit receiver?

+4
source share
4 answers

Yes, this is possible with Kernel#send:

receiver.send :method_name, parameters

Although there are workarounds, for example BasicObject#instance_eval, or Kernel#binding, a common way to call a private method is to call sendon the receiver.

+6
source

Using BasicObject#instance_eval, you can call a private method.

class Sample
  private
  def baz
    'baz called'
  end
end

Sample.new.instance_eval('baz')
# => 'baz called'
Sample.new.instance_eval { baz }
# => 'baz called'
+2
source

, send . .

, , reset . , , :

class Sample
  public :baz
end

:

s = Sample.new
s.baz
# => 'baz called'
+1

: .

, :

?

, , "", .

However, at a reflective meta level, the answer is "Yes." In fact, you can do almost anything at the meta level and bypass almost any restriction of access, protection, hiding and encapsulation.

Object#send, whose main purpose is to call a method whose name you do not know before execution, also has an additional side effect of circumventing access restrictions such as privateand protected. (He also ignores Refinements, which is an important limitation you should be aware of!)

+1
source

Source: https://habr.com/ru/post/1620971/


All Articles