# Use of extend \<module\> from within a Class

**URL:** <https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836>\
**Category:** Ruby\
**Created:** [December 5, 2009, 12:37am UTC](https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836 "2009-12-05T00:37:29Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mperham](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47c2d/32.png) [@mperham](https://www.ruby-forum.com/u/mperham)\
**Post date:** [December 5, 2009, 12:37am UTC](https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836/1 "2009-12-05T00:37:29Z")

</div>

I would like to include a module into a ‘static’ class - such that all  
the modules methods are class methods. The problem is that code in the  
module that uses "self.class.XYZ’ breaks and when this code is included,  
ruby cannot find the XYZ method.

Here is an example:

module Basic  
def methoda  
puts “AAAAAAAAAAA”  
end

def mb  
self.class.cee  
end

module ClassMethods  
attr\_writer :cee

```
def cee
  puts "CCCCCCCCCCCCC"
end

```

end  
end

class Use  
extend Basic

def self.z  
mb  
end  
end

If I do the following:  
Use.z

I get this error:  
NoMethodError: undefined method `cee' for Class:Class from (irb):100:in`mb’  
from (irb):116:in `z’  
from (irb):119

* * *

The context for this is in Rails, I want to use  
ActionController::UrlWriter.url\_for outside of the controller. And  
within a static class. However, it complains with this error:

NoMethodError: undefined method `default\_url\_options’ for Class:Class

Heres the url\_for method in ActionController::UrlWriter  
def url\_for(options)  
options = self.class.default\_url\_options.merge(options) # ERROR  
OCCURS HERE

```
url = ''

```

## … … end

I think my understanding of modules and using extend (or include) is  
faulty or at least doesnt cover the subtleties of when a modle uses  
“self.class” and its included in another class, then what becomes of  
self.class in this case??

Any input into how this stuff works in Ruby is appreciated,

Mike

---

<div class="post-metadata">

**Author:** ![mperham](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47c2d/32.png) [@mperham](https://www.ruby-forum.com/u/mperham)\
**Post date:** [December 5, 2009, 1:00am UTC](https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836/2 "2009-12-05T01:00:46Z")

</div>

On Sat, Dec 5, 2009 at 12:37 AM, Mike P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> I would like to include a module into a ‘static’ class - such that all  
> the modules methods are class methods.

One basic way to do this is to have the class extend the module:

irb(main):017:0\> module Z  
irb(main):018:1\> def test; “testZ”; end  
irb(main):019:1\> end  
=\> nil  
irb(main):020:0\> class C  
irb(main):021:1\> extend Z  
irb(main):022:1\> end  
=\> C  
irb(main):023:0\> C.test  
=\> “testZ”

> def mb  
> self.class.cee

This is wrong. self.class is Class, and the Class class doesn’t have a  
method “cee”.

> end
> 
> module ClassMethods  
> attr\_writer :cee
> 
> def cee  
> puts “CCCCCCCCCCCCC”  
> end  
> end  
> end

I think you are confusing this usage. The name ClassMethods is a  
convention used to denote a set of methods that will be added to the  
class as class methods when you include this module. This is usually  
done as:

module Test  
module ClassMethods  
def test; “test”; end  
end

def self.included mod  
mod.extend ClassMethods  
end  
end

If you simply want a method defined in the singleton class of your  
module do:

module Basic  
def self.cee  
“CCCCCCC”  
end  
end

If you want to call it from a method of the module:

module Basic  
def mb  
Basic.cee  
end  
def self.cee  
“CCCCC”  
end  
end

If you then want mb to be a class method of the classes you choose,  
you can use extend instead of include:

irb(main):045:0\> module Basic  
irb(main):046:1\> def mb  
irb(main):047:2\> Basic.cee  
irb(main):048:2\> end  
irb(main):049:1\> def self.cee  
irb(main):050:2\> “CCCCCCCCCCCCC”  
irb(main):051:2\> end  
irb(main):052:1\> end  
=\> nil  
irb(main):053:0\> class YY  
irb(main):054:1\> extend Basic  
irb(main):055:1\> end  
=\> YY  
irb(main):056:0\> YY.mb  
=\> “CCCCCCCCCCCCC”

> I think my understanding of modules and using extend (or include) is  
> faulty or at least doesnt cover the subtleties of when a modle uses  
> “self.class” and its included in another class, then what becomes of  
> self.class in this case??

You can ask Ruby 🙂

irb(main):036:0\> module Basic  
irb(main):037:1\> def mb  
irb(main):038:2\> puts self  
irb(main):039:2\> end  
irb(main):040:1\> end  
=\> nil  
irb(main):041:0\> class XX  
irb(main):042:1\> extend Basic  
irb(main):043:1\> end  
=\> XX  
irb(main):044:0\> XX.mb  
XX

So, how it works is that when a class extends a module, the methods  
get added to the singleton class of the class. This means that the  
method is now in the lookup path of the class methods. But (and this  
is the same with the normal inheritance) self inside those methods is  
still the original object that received the method call, so in this  
case the class XX. Another example:

irb(main):058:0\> class Class  
irb(main):059:1\> def test\_class; puts self; end  
irb(main):060:1\> end  
=\> nil  
irb(main):061:0\> XX.test\_class  
XX

This is with simple inheritance (XX inherits from Class). With  
extended modules it’s the same, as shown above.  
Basically:

1.- extend includes the methods in that module to the singleton class  
of the receiving object.  
2.- classes are objects  
3.- so when a class extends a module, the module instance methods (is  
that the correct way to refer to those?) get added to the singleton  
class of the class (commonly known as class methods).

This stuff is tricky, and I don’t know if I explained myself very  
well, so please ask if there’s something not clear enough.

Hope this helps,

Jesus.

---

<div class="post-metadata">

**Author:** ![mperham](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47c2d/32.png) [@mperham](https://www.ruby-forum.com/u/mperham)\
**Post date:** [December 5, 2009, 1:37am UTC](https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836/3 "2009-12-05T01:37:51Z")

</div>

Hi and thanks, please note that I am extending the module from within my  
class. the problem is exactly with the call of the form self.class…

concerning what you said about self.class (inside the module):

def mb  
self.class.cee

I used this in my example because the rails module that I am extending  
does this. It is included using the method named ‘helper’ and that must  
do special things to make it work in the context of rails+controller.

What I really want to do is use url\_for of the rails’  
ActionController::UrlWriter. as it happens, that module does have  
ClassMethods and within there a method that calls self.class (which  
fails when I extend the module).

## Mike

JesÃºs Gabriel y GalÃ¡n wrote:

> On Sat, Dec 5, 2009 at 12:37 AM, Mike P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> wrote:
> 
> > I would like to include a module into a ‘static’ class - such that all  
> > the modules methods are class methods.
> 
> One basic way to do this is to have the class extend the module:
> 
> irb(main):017:0\> module Z  
> irb(main):018:1\> def test; “testZ”; end  
> irb(main):019:1\> end  
> =\> nil  
> irb(main):020:0\> class C  
> irb(main):021:1\> extend Z  
> irb(main):022:1\> end  
> =\> C  
> irb(main):023:0\> C.test  
> =\> “testZ”
> 
> > ï¿½def mb  
> > ï¿½ ï¿½self.class.cee
> 
> This is wrong. self.class is Class, and the Class class doesn’t have a  
> method “cee”.
> 
> > ï¿½end
> > 
> > ï¿½module ClassMethods  
> > ï¿½ ï¿½attr\_writer :cee
> > 
> > ï¿½ ï¿½def cee  
> > ï¿½ ï¿½ ï¿½puts “CCCCCCCCCCCCC”  
> > ï¿½ ï¿½end  
> > ï¿½end  
> > end

---

<div class="post-metadata">

**Author:** ![mperham](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47c2d/32.png) [@mperham](https://www.ruby-forum.com/u/mperham)\
**Post date:** [December 7, 2009, 10:26pm UTC](https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836/4 "2009-12-07T22:26:29Z")

</div>

Thanks for the clarification and sample.

So, I cannot simply extend the ActionController::UrlWriter module in my  
class because that module does this:

self.class.default\_url\_options.merge(options)

However, within a rails controller, this module can be included as a  
“helper”. Does anyone know how the magic rails helper function makes  
this call to self.class.default\_url work? I’ve looked at the code for  
helper but cannot really make any sense of it.

Mike

…

> The normal pattern is
> 
> module SomeModule
> 
> # define any instance methods here
> 
> module ClassMethods  
> # define any class methods here  
> end
> 
> # and here is the crucial step this gets called when some class
> 
> # includes the module
> 
> def self.included(some\_class)  
> some\_class.extend(ClassMethods)  
> end  
> end
> 
> So if you want to make a module which adds only class methods either
> 
> 1. define the module ‘normally’ and in the class which wants the  
> methods as class methods
> 
> or
> 
> 1. Use the pattern above, leave the instance methods out, and put all  
> of the methods in the inner ClassMethods module (actually the name of  
> this module is irrelevant except for clarity. then in the using class
> 
> HTH
> 
> –  
> Rick DeNatale
> 
> Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
> WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
> LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![mperham](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47c2d/32.png) [@mperham](https://www.ruby-forum.com/u/mperham)\
**Post date:** [December 5, 2009, 3:49am UTC](https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836/5 "2009-12-05T03:49:56Z")

</div>

On Fri, Dec 4, 2009 at 6:37 PM, Mike P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> end  
> end  
> end  
> end

> class Use  
> extend Basic

Okay, at this point in the class definition self == Use

and extend Basic

mixes the Basic module into the singleton class of Use, so all of the  
methods of Basic (i.e. mb and methoda) are now CLASS methods of Use

There is no actual usage of Basic::ClassMethods

> def self.z  
> This is a class method of Use (because of def self.z) inside this  
> method self is also the class object Use  
> from (irb):116:in `z’  
> from (irb):119

so what happened.

in Basic#mb we have

def mb  
self.class.cee  
end

and self is still the class object Use, but Use.class is class, which  
is one issue. Even if the mb method had self.cee, Use doesn’t have cee  
as a class method because although Basic::ClassMethods was defined, it  
was never referenced.

As Jesus pointed out, you appeared to be confused with the way Rails,  
and lots of other ruby code causes modules to add both instance and  
class methods to classes which include them.

The normal pattern is

module SomeModule

# define any instance methods here

module ClassMethods  
# define any class methods here  
end

# and here is the crucial step this gets called when some class

# includes the module

def self.included(some\_class)  
some\_class.extend(ClassMethods)  
end  
end

So if you want to make a module which adds only class methods either

1. define the module ‘normally’ and in the class which wants the  
methods as class methods

or

1. Use the pattern above, leave the instance methods out, and put all  
of the methods in the inner ClassMethods module (actually the name of  
this module is irrelevant except for clarity. then in the using class

HTH

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![mperham](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47c2d/32.png) [@mperham](https://www.ruby-forum.com/u/mperham)\
**Post date:** [December 8, 2009, 3:02am UTC](https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836/6 "2009-12-08T03:02:00Z")

</div>

Hi and thanks for explaining the helper method. I understand whats going  
on except for

master\_helper\_module.module\_eval

-what is master\_helper\_module ? (Presumably it has the effect of  
"include ModuleName - but how that makes self.class.XYZ work is still  
not understood).

* * *

Back to the UrlWriter module…

I did some tests and noticed that self.included is not called when a  
module is extended (versus included). For UrlWriter, this means that  
this code doesnt get executed:  
def self.included(base) #:nodoc:  
ActionController::Routing::Routes.install\_helpers(base)  
base.mattr\_accessor :default\_url\_options  
base.default\_url\_options ||= default\_url\_options  
end

I changed my code to explicitly call that method after I extended, ala:  
def self.staticmethod  
extend ActionController::UrlWriter  
ActionController::UrlWriter.included(self) # the class  
self.default\_url\_options = {} # doesnt seem to do much

but still this line from UrlWriter.url\_for fails:

self.class.default\_url\_options.merge(options)

As you said, self.class refers to Class so I dont see how that line  
works when the module is included as a helper. Can you explain this??

Mike

Rick Denatale wrote:

> On Mon, Dec 7, 2009 at 4:26 PM, Mike P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> wrote:
> 
> > helper but cannot really make any sense of it.  
> > MyController \< ActionController::Base  
> > include UrlWriter # include not extend  
> > end
> 
> If you read the code in actionpack/lib/action\_controller/helpers.rb it  
> really isn’t that hard to see what’s going on
> 
> if in the controller you write say
> 
> helper :url\_writer
> 
> then the helper method takes the case branch for a symbol. which is:
> 
> ```
> file_name = arg.to_s.underscore + '_helper'
> class_name = file_name.camelize
> 
> begin
> require_dependency(file_name)
> rescue LoadError => load_error
> requiree = / -- 
> 
> ```
> 
> (.\*?)(.rb)?$/.match(load\_error.message).to\_a[1]  
> if requiree == file\_name  
> msg = “Missing helper file helpers/#{file\_name}.rb”  
> raise LoadError.new(msg).copy\_blame!(load\_error)  
> else  
> raise  
> end  
> end
> 
> ```
> add_template_helper(class_name.constantize)
> 
> ```
> 
> So it computes a file name from the argument, in this case  
> “url\_writer.rb”, and a class (actually a Module) name “UrlWriter”
> 
> Then require dependency loads the file if necessary, and finally.
> 
> class\_name.constantize turns teh class name into the actual module,  
> and passes it as the argument to add\_template\_helper which is defined  
> above as:
> 
> ```
> def add_template_helper(helper_module) #:nodoc:
> master_helper_module.module_eval { include helper_module }
> end
> 
> ```
> 
> So it is effectively the same thing as what I first wrote.
> 
> –  
> Rick DeNatale
> 
> Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
> WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
> LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![mperham](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e47c2d/32.png) [@mperham](https://www.ruby-forum.com/u/mperham)\
**Post date:** [December 8, 2009, 12:36am UTC](https://www.ruby-forum.com/t/use-of-extend-module-from-within-a-class/179836/7 "2009-12-08T00:36:33Z")

</div>

On Mon, Dec 7, 2009 at 4:26 PM, Mike P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> helper but cannot really make any sense of it.  
> MyController \< ActionController::Base  
> include UrlWriter # include not extend  
> end

If you read the code in actionpack/lib/action\_controller/helpers.rb it  
really isn’t that hard to see what’s going on

if in the controller you write say

helper :url\_writer

then the helper method takes the case branch for a symbol. which is:

```
          file_name = arg.to_s.underscore + '_helper'
          class_name = file_name.camelize

          begin
            require_dependency(file_name)
          rescue LoadError => load_error
            requiree = / -- 

```

(.\*?)(.rb)?$/.match(load\_error.message).to\_a[1]  
if requiree == file\_name  
msg = “Missing helper file helpers/#{file\_name}.rb”  
raise LoadError.new(msg).copy\_blame!(load\_error)  
else  
raise  
end  
end

```
          add_template_helper(class_name.constantize)

```

So it computes a file name from the argument, in this case  
“url\_writer.rb”, and a class (actually a Module) name “UrlWriter”

Then require dependency loads the file if necessary, and finally.

class\_name.constantize turns teh class name into the actual module,  
and passes it as the argument to add\_template\_helper which is defined  
above as:

```
  def add_template_helper(helper_module) #:nodoc:
    master_helper_module.module_eval { include helper_module }
  end

```

So it is effectively the same thing as what I first wrote.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)
