Hi

I was reading the book "Metaprogramming Ruby" which I found quite good for a
guy trying to improve on his novice Ruby skills.
Parts of the book describes the creation of Class macros, and I got
intrigued by this, and I tried to create a small project to practice a
little bit.

Not that I know that this is a particular good idea in Ruby, I started to
make a small framework to enforce the creation of certain methods.
I call it interfaces, since that's what I know from C#.

Anyway, I soon stumbled into a dead end... as expected ;o)

Here is the code:

module Interface
  module Base
    def self.included(base)
      base.extend ClassMethods
    end
    module ClassMethods
      def add_interface_methods(*methods)
        methods.each do |method|
          (@interface_methods ||= []) << method.to_s
        end
      end
      def implement_interfaces(*interfaces)
        (@interfaces = interfaces).each do |interface|
          puts "self: " + self.inspect.to_s
        end
      end
      def enforce_interfaces
        if not (not_implemented_interface_methods = @interface_methods -
self.instance_methods).empty?
          raise RuntimeError, "The following interface methods are not
implemented in class #{self.to_s}:\n " +
not_implemented_interface_methods.inspect
        end
      end
    end
  end
end

module Interface
  module ILockable
    add_interface_methods :lock, :unlock
  end

  module IDrivable
    add_interface_methods :drive, :break
  end
end

class MyClass
  include Interface::Base
  implement_interfaces Interface::ILockable, Interface::IDrivable
  # methods and other stuff
  enforce_interfaces
end

When I run this I get:
interface.rb:28: undefined method `add_interface_methods' for
Interface::ILockable:Module (NoMethodError)

I do understand why I get this error, but I can't see how to go about fixing
it given that I want it structurally to be along the lines already laid out.
Do not bother to much about the code being bloated or otherwise not in
accordance with "standard Ruby thinking"... :o)

And I do realize I didn't have to use the included hook script since I'm
only adding class methods, but it's part of a learning process :o)

So, where did I go wrong?
Any input/solution/discussion on this issue is most welcome!

Kind regards,
Rolf