The Passionate Craftsman

Ruby, PHP, MySql, Software engineering and more.

Sunday, 2 December 2012

Abstract classes in Ruby

Ruby is not a traditional OOP language like Java and C++. An abstract class provides and interface for a programmer, the implementation of some generic methods (useful for subclasses) and abstract methods (to be implemented by subclasses). Usually with Ruby you use mixins, but sometimes you need to provide a class with some generic methods and some stub methods to be implemented by more specialised subclasses; the template pattern just does this. In a Ruby class you just can do this:

def create_html_header
  raise "You cannot call this abstract method"
end

This will block a programmer to use a method that should be implemented in a subclass, a class specialised in HTML generation. If you have many methods like that one, you could use a module to reduce the amount of methods with a raise statement. One solution could be to declare the abstract methods in this way:

class AClass
   abstract_methods :foo, :bar
end

A solution to block a user to instantiate a class is:

module Abstract
  def self.append_features(klass)
    # access an object's copy of its class's methods & such
    metaclass = lambda { |obj| class << obj; self ; end }

    metaclass[klass].instance_eval do
      old_new = instance_method(:new)
      undef_method :new

      define_method(:inherited) do |subklass|
        metaclass[subklass].instance_eval do
          define_method(:new, old_new)
        end
      end
    end
  end
end

class A
  include Abstract
end
class B < A
end

B.new #=> #
A.new # raises #

So if you just include 'include Abstract' you will prevent that class to be instantiated. For more information read this StackOverflow question: http://stackoverflow.com/questions/512466/how-to-implement-an-abstract-class-in-ruby. The template pattern is explained here: http://designpatternsinruby.com/

2 Comments:

At 2 December 2012 15:19 , Blogger Craig Ambrose said...

Nice one Riccardo, that's really handy.

 
At 3 December 2012 00:25 , Blogger Riccardo Tacconi said...

I am glad you liked it :-)

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home