Hi Xavier

Having "include Base" in both the Interface::xxx modules does remove the
current error message.
But the problem is that the code in the "add_interface_methods" then runs
with Interface::xxx modules as self, and not MyClass.
So the methods are not collected in the @interface_methods attribute of
MyClass but in the separate Interface::xxx modules, causing
enforce_interface to fail, because of @interface_methods in MyClass is nil.

With regards to your code (I have just skimmed through it), I think you are
limiting yourself to just one interface when you are using inheritage.
My idea was to enforce compliance with a set of interfaces, by ensuring tha=
t
the correct methods (and maybe later on, the correct attributes) are
implemented.
I understand what you were trying to do by using a hook method to
automatically run the "enforce" part at the end, but I guess that the
inherited hook method will be called before the methods are defined, as you
suspected yourself.
I was actually thinking along these lines myself when I first wrote the
code. But I concluded that I needed a class macro to be called after I
defined the methods in MyClass.
Now, I could have done all the work in this one class macro (doing both the
implement_interface and enforce_interface parts in one call), but I also
would like to have the definitions at the top of the class for esthetic
reasons.

But then, as I said, I also thought about hook method to replace the call t=
o
enforce_interface, but I couldn't find one that fits...
Maybe Module.closing would be a good idea to have in Ruby core??? :o)
Module.closing would be called just before closing a class, and could be
used to do some checking.

Ok, I hope that potential new readers of this thread understand that I'm no=
t
advocating interface checking in Ruby, It's all just a little thought
experiment to explore the possibilities of class macros.

Kind regards,
Rolf

On Tue, Jul 27, 2010 at 11:42 AM, Xavier No=EBlle <xavier.noelle / gmail.com>=
wrote:

> 2010/7/25 Rolf Pedersen <rolfhsp / gmail.com>:
> > module Interface
> >  module ILockable
> >    add_interface_methods :lock, :unlock
> >  end
> >
> >  module IDrivable
> >    add_interface_methods :drive, :break
> >  end
> > end
>
> add_interface_methods is not defined for these modules.
> "include Base" in both should remove this error, but I'm not sure
> that's what you want in the end.
>
> I take the opportunity of this topic to provide my own version of
> interface implementation and to ask a question about it (if it's off
> topic, don't hesitate to tell me). My goal is to use your code to
> perform an automatic interface check and not bother with calling
> enforce_interface everytime:
>
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> module Interface
>  def inherited(base)
>        puts "#{base} inherited from me"
>        enforce_interface(base)
>  end
>
>  def enforce_interface(base)
>        instanceMethods =3D base.public_instance_methods()
>
>        if (!@interface_methods.nil?())
>          @interface_methods.each() do |method|
>                throw "No method #{method}" unless
> instanceMethods.include?(method)
>          end
>        end
>  end
>
>  def add_interface_methods(*methods)
>       methods.each do |method|
>         (@interface_methods ||=3D []) << method.to_s
>       end
>  end
> end
>
> class Mother
>        extend Interface
>
>        add_interface_methods :pwet, :ziou
> end
>
> class Child < Mother
>        def pwet()
>                puts "Method pwet"
>        end
>
>        def initialize()
>                puts "Child ctor"
>        end
> end
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>
> This piece of code almost works (so, doesn't work :-)), but ends up
> (logically) with a "No method pwet" exception. I suppose that it's due
> to the fact that Child inherits from Mother before to be able to
> define any method. Is there a way around this problem ?
>
> I like Paolo's proposal (which could maybe be extended to allow to
> check methods arity as well), but dislike the need to call explicitely
> enforce_interface.
>
> --
> Xavier NOELLE
>
>