Top Level Private Methods

In this chapter, you will learn how the top level context and private methods work together.

Implicit Receiver

Let's print hello in the standard output.

puts 'hello'

As expected, this prints:

hello

Explicit Receiver

Goal Keeper

If you use an explicit receiver, the self to call the puts:

self.puts 'hi'

We get:

NoMethodError: private method ‘puts’ called for main:Object

This is because puts is a private method in Object. In Ruby you cannot have an explicit receiver to call a private method. Why? Because, when the sender and receiver are the same, you cannot use an explicit receiver to send a message.

Sending a Message to Private Method

The Kernel Module

Where does the private method puts() live? Let's search for methods that begin with put.

 Kernel.methods.grep(/put/)

This prints:

[:putc, :puts]

It lives in Kernel module. Ruby mixes in the Kernel module into the Object class. That's how it is available as a private method on the Object.

Private Method and Explicit Receiver

How do we grab the main, the top level default object? Let's grab the value of the current object from the self and assign it to our own variable m.

m = self
m.puts 'hi'

We get the same error message as we did in step 2.

NoMethodError: private method ‘puts’ called for main:Object

Why do we get this error? You can think of the code that gives error to be equal to this:

class Object
  private

  def puts(arg)
   # Implementation for printing to standard output
  end
end

We cannot call the puts private method with an explicit receiver.

Forcing an Explicit Receiver

We can use send() method to send the puts() message to the main object:

m = self
m.send(:puts,'hi')

This will work. This is the same as:

self.send(:puts,'hi')

But, this breaks encapsulation and is generally not a good idea unless you have a good reason to do so.

Using Method Object

We can also do this:

 m = self.method(:puts)
 => #<Method: Object(Kernel)#puts> 
 > m.call('hello')
hello
 => nil

You can see how using the method object displays the relationship between the Kernel module and Object class. The puts() method is available by mixing in the Kernel module into the Object class.

Summary

In this chapter we saw how the private methods and the top level context work together. The concept you learned in the previous chapter is a generalized concept of the concept in this chapter.

results matching ""

    No results matching ""