Focus on Messages
In this chapter, you will learn how to write message centric Ruby programs.
Avoid Over Emphasis on Objects
Alan Kay coined the term Object Oriented Programming. He has expressed regret that he overemphasized the benefits of objects.
I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea. The big idea is "messaging". The Japanese have a small word - ma - for "that which is in between" - perhaps the nearest English equivalent is "interstitial".
The key in making great and grow-able systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.
-- Alan Kay
Sending a Message
In Smalltalk, you can send factorial message to a number object. In Ruby, when you do the same:
3.factorial
You will get an error:
NoMethodError: undefined method ‘factorial’ for 3:Fixnum
Open Fixnum Class
Ruby is flexible, it has open classes. We can open the Fixnum class and define factorial method.
class Fixnum
def factorial
(1..self).reduce(1, :*)
end
end
We can now send factorial method to the Fixnum object.
p 3.factorial
This prints:
6
The above solution looks much more elegant than doing:
Factorial.compute(3)
Using Refinements
It is debatable whether opening a Fixnum class to define factorial is a good idea. It is better to use refinements instead to avoid global impact in your programs.
module MyModule
refine Fixnum do
def factorial
(1..self).reduce(1, :*)
end
end
end
using MyModule
p 3.factorial
This prints the same value 6. There is a drawback to this approach. We need to know the name of the module in the using declaration before we can call the factorial method. This creates a dependency. It's a trade-off you need to make between reducing the impact vs knowing the name of a module.
Summary
In this chapter, you learned how you can make your Ruby programs more message centric. We can use open classes and refinements for this purpose. The real power is in the messaging.