From: Rolf Pedersen Date: 2010-07-28T07:30:13+09:00 Subject: Re: Module inclusion and class macro problem --0016364ef6106786d5048c65f07c Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable 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 = wrote: > 2010/7/25 Rolf Pedersen : > > 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 > > --0016364ef6106786d5048c65f07c--