Ruby advanced features — Mix ins, Module include and Object extend
- Published April 2nd, 2007 in Ruby
I've been programming Ruby for a year and a half now, mainly due to my interest in the Rails framework. I soon realized that Rails' greatest advantage lies in its language, Ruby.
And other people are starting to realize how Ruby is an amazing language, too. Here, in Silicon Valley, every single company is going crazy trying to find out what can be the next step using Ruby. I've heard about several dozens of projects from several different companies and the majority involves Ruby. There are two words over here: Java and Ruby. And as time goes by, you start hearing more Ruby and less Java.
Regardless of whether Ruby is ready for the enterprise, question that I've addressed myself already, it definitely has enterprise-level features.
One amazing thing that's usually used to virtualize multiple inheritance (which is a bad practice whatsoever) is Mix ins. But mix ins are truly useful for other kind of things. Providing functionality.
Imagine you'd like to implement the Gang-of-Four's Observer pattern. This is a quite useful design pattern that provides extra functionality to your class and it's frequently used in UI for event notifications. Moreover, you'd want it to be easily reusable -- after all, that's one of the gaps Design Patterns try to fill: reusable good approaches to common problems. So, wouldn't it be great if you could separate it and simply add functionality?
In Ruby, you can. This is how the Observable/Subject role in the Observer design pattern would look in Ruby
-
module Observable
-
def observers
-
@observer_list ||= []
-
end
-
def add_observer(obj)
-
observers <<obj
-
end
-
def notify_observers
-
observers.each {|o| o.update }
-
end
-
end
In Java, you'd have to implement the behavior on the class you'd like to become an Observable.
In Ruby, you can simply include the functionality.
-
class IWannaBeAnObservable
-
include Observable
-
end
Yeah it's cool, but sometimes you only know the object's role and behavior at runtime. Other times, it doesn't even make sense to become an Observable when there's no Observers to observe. Ruby overcomes this situation.
-
a = SomedayIllBeAnObservable.new
-
a.extend(Observable)
Yes, that object gains functionality at runtime.
Lesson of the day: Ruby ROCKS!
Later on I'll address why dynamic typed languages are a Good Thing.




No Responses to “Ruby advanced features — Mix ins, Module include and Object extend”