# Module inclusion and class macro problem

**URL:** <https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184>\
**Category:** Ruby\
**Created:** [July 25, 2010, 9:14pm UTC](https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184 "2010-07-25T21:14:59Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 25, 2010, 9:14pm UTC](https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184/1 "2010-07-25T21:14:59Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 26, 2010, 12:45am UTC](https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184/2 "2010-07-26T00:45:42Z")

</div>

Hello, Rolf. Let’s wrap up what happened and why. The issue comes from  
these lines:

> module Interface  
> module ILockable  
> add\_interface\_methods :lock, :unlock  
> end
> 
> # …
> 
> end

Coming from C#, you’re probably tempted to assume that the code inside  
ILockable (and IDrivable) is executed only when a class/module is  
“loaded”. Actually, that code is executed immediately as Ruby goes  
through the definition.

So, at this point (and independently of all the other code in your  
example), Ruby tries to execute add\_interface\_methods() in the scope  
of Interface::ILockable. Inside that scope, the role of self is taken  
by Interface::ILockable itself - so that’s the implicit receiver of  
any method call. So Ruby tries to call  
Interface::ILockable.add\_interface\_methods(), doesn’t find that  
method, and fails.

In the real world, I’d go for something simpler (and I’d be a real  
prick in questioning the notion of strongly typed interfaces in  
Ruby 😉 ). However, because this is a great learning exercise, here’s  
something along your own lines that probably works as you expect:

* * *

module Interface  
module Base  
def self.included(base)  
base.extend ClassMethods  
end  
module ClassMethods  
def implement\_interfaces(\*interfaces)  
interfaces.each do |interface|  
@interface\_methods = (@interface\_methods || []) +  
interface.instance\_methods  
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  
def lock; end  
def unlock; end  
end

module IDrivable  
def drive; end  
def end; end  
end  
end

class MyClass  
include Interface::Base  
implement\_interfaces Interface::ILockable, Interface::IDrivable

# methods and other stuff

enforce\_interfaces  
end

* * *

Paolo “Nusco” Perrotta  
Metaprogramming Ruby ([Pragmatic Bookshelf: By Developers, For Developers](http://www.pragprog.com/titles/ppmetr))

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 27, 2010, 11:43am UTC](https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184/3 "2010-07-27T11:43:04Z")

</div>

2010/7/25 Rolf P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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:

=====================================  
module Interface  
def inherited(base)  
puts “#{base} inherited from me”  
enforce\_interface(base)  
end

def enforce\_interface(base)  
instanceMethods = 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 ||= []) \<\< 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

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.

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 27, 2010, 9:30pm UTC](https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184/4 "2010-07-27T21:30:17Z")

</div>

Hi Paolo

Thanks for answering :o)  
I understand that the code is executed immediately. (After all, I did  
read  
your book! ;o) )

The code you proposed actually matches exactly what I had in the  
previous  
iteration.

But in this next iteration, instead of defining the methods in the  
Interface::xxx modules, and thereby repeat code (def…end, and possibly  
in  
other cases even the body of the methods), my goal was to use a similar  
technique to the class macros, only in the modules instead.

So is this possible to accomplish?

Kind regards,  
-Rolf

On Mon, Jul 26, 2010 at 12:45 AM, Paolo Perrotta \<

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 28, 2010, 12:30am UTC](https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184/5 "2010-07-28T00:30:36Z")

</div>

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  
that  
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 to  
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  
not  
advocating interface checking in Ruby, It’s all just a little thought  
experiment to explore the possibilities of class macros.

Kind regards,  
Rolf

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 28, 2010, 3:22pm UTC](https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184/6 "2010-07-28T15:22:44Z")

</div>

2010/7/28 Rolf P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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.

Indeed, that’s what I meant by “I’m not sure that’s what you want in  
the end” 🙂

> 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 that  
> the correct methods (and maybe later on, the correct attributes) are  
> implemented.

I was trying to get something as simple as possible and only use class  
inheritance, so yes: only one possible.

> reasons.  
> That’s what we’re all looking for 🙂

> But then, as I said, I also thought about hook method to replace the call to  
> enforce\_interface, but I couldn’t find one that fits…

Me neither. The only way I could think of would be to hook on allocate  
or new, but, uh…this is ugly !

> 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.

That’d be great. Anyhow, I don’t know if it would really make sense,  
since Ruby classes and modules may be reopened and methods added  
dynamically.

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

I understand that it’s not the Ruby way of life, due to its dynamic  
component, but sometimes I miss this feature. In my case, I would like  
to define a class which must be extended with mandatory methods. The  
way I’m dealing with it is by providing a template .rb file with empty  
mandatory methods, but that’d be great if one could just extend my  
class and see by himself which methods are missing, without needing to  
rerun the script a zillion times.

---

<div class="post-metadata">

**Author:** ![Rolf\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/dec6dc/32.png) [@Rolf\_P](https://www.ruby-forum.com/u/Rolf_P)\
**Post date:** [July 28, 2010, 5:05pm UTC](https://www.ruby-forum.com/t/module-inclusion-and-class-macro-problem/192184/7 "2010-07-28T17:05:48Z")

</div>

On Jul 27, 9:29 pm, Rolf P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> So is this possible to accomplish?

You might add add\_interface\_methods to the Module class. It would then  
be available to all modules.

* * *

Paolo “Nusco” Perrotta  
Metaprogramming Ruby ([Pragmatic Bookshelf: By Developers, For Developers](http://www.pragprog.com/titles/ppmetr))
