Search code examples
rubymethodsnomethoderror

Ruby Koans about_methods line 119 how to get error on a private method in IRB


I try to run this method in IRB and do not get anything. Just a new line for a new command. I understand that it's a private method, but I don't understand how people get the required error.

def my_private_method
    "a secret"
end
private :my_private_method

and expected result: (NoMethodError) and /private method/

def test_calling_private_methods_with_an_explicit_receiver
    exception = assert_raise(__) do
        self.my_private_method
    end
    assert_match /__/, exception.message
end

Solution

  • If you are literally just pasting this method into an irb session without including it into a class, then you're defining the method within the scope of Object:

    2.2.1 :001 > def my_private_method 2.2.1 :002?> "a secret" 2.2.1 :003?> end => :my_private_method 2.2.1 :004 > private :my_private_method => Object 2.2.1 :005 > my_private_method => "a secret"

    The reason you can call the private method is because when you call the method, you are still within the scope of Object. This makes sense...you SHOULD be able to call a private method from within the same scope.

    Private methods in a class may not be called by another class' instances. Here's an example that may help:

    class PrivateMethodClass
    
      def my_private_method
        "a secret"
      end
    
      def puts_my_private_method
        puts my_private_method
      end
    
      private :my_private_method
    end
    
    class AnotherClass
    
      def that_private_method
        PrivateMethodClass.new.my_private_method
      end
    end
    

    Paste the above into irb and then create instances of each of these classes and try calling their methods. Note that PrivateMethodClass instances can call :puts_my_private_method and it will execute, but that AnotherClass instances cannot successfully call :that_private_method.