class Class alias_method :old_new, :new def abstract_class @is_abstract = true @abstract_methods = [] end def is_abstract? return !@is_abstract.nil? end def new(*params) raise Exception, "#{self} is an abstract class" if is_abstract? if self.superclass.is_abstract? sc = self.superclass sc.abstract_methods.each do |method| if !method_defined?(method) methods = sc.abstract_methods.join(", ") raise Exception, "#{self} must implement the inherited abstract " + "methods from #{sc}: #{methods}" end end end return old_new(*params) end def abstract_method(method) raise Exception, "#{self} is not an abstract class" if !is_abstract? if @abstract_methods.include?(method) raise Exception, "#{method} is already defined as an abstract method" end if method_defined?(method) raise Exception, "Abstract methods do not specify a body" end @abstract_methods << method end def abstract_methods return @abstract_methods end def method_added(method) if is_abstract? && @abstract_methods.include?(method) raise Exception, "Abstract methods do not specify a body" end end end