1
class Foo
  @@first_time = true

  def self.private_bar
    if @@first_time
      puts "Hi"
    else
      puts "Oi, you don't work here"
    end
    @@first_time = false
  end

  private_class_method :private_bar

  public
  def calling_private_method
    self.class.send :private_bar
    another_private_bar
  end
end

f=Foo.new
f.calling_private_method
f.class.send :private_bar

The output should be something like this:

Hi
NoMethodError: private method `private_bar'

However, the output is:

Hi
Oi, you don't work 

Why is this happening? This must be a bug otherwise it is an important violation of the encapsulation of information, right?

Bechma
  • 425
  • 6
  • 11

2 Answers2

2

What do you expect from a language that lets you write

String = Array
puts String.new.inspect
#=> []

or

class Fixnum
  def +(b)
    self-b
  end
end

puts 1+2
#=> -1

?

On a more serious note, almost nothing is forbidden in Ruby : it makes it easier to experiment and to learn Ruby inner workings. In some cases, it makes it possible to write more concise code or get "magical" behaviors that would be harder or impossible to reproduce with a stricter language.

In your example, it's possible to call a private method, but you cannot use the usual syntax.

Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
2

Why is this happening? This must be a bug otherwise it is an important violation of the encapsulation of information, right?

Using Object#send allows you to call methods despite of their visibility. Simple as that.

Andrey Deineko
  • 51,333
  • 10
  • 112
  • 145