Ruby Failure while calling an objects own private method?

The method puts is defined as private in the module Kernel. So nobody can execute an other objects puts – that’s clear. But why isn’t the following exmaple running although self and slf have the same ID? Aren’t they the same Object?

>> slf = self
>> slf.puts
(irb):206:in `<main>': private method `puts' called for main:Object (NoMethodError)
        from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/irb-1.3.5/exe/irb:11:in `<top (required)>'
        from C:/Ruby30-x64/bin/irb:25:in `load'
        from C:/Ruby30-x64/bin/irb:25:in `<main>'
>> p self.object_id
320
>> p slf.object_id
320

>Solution :

Private methods in Ruby can only be invoke via a receiverless message send, i.e. with self as the implicit receiver, or with the literal pseudo-variable self as the explicit receiver.

IOW, the two ways that are allowed are

  • foo(args) and
  • self.foo(args).

In your example, you are sending a message where the receiver is the local variable slf, i.e. neither implicit, nor the literal pseudo-variable self, therefore, invoking a private method is not allowed.

Leave a Reply