Modules and class methods

Why does this not work!

########################################
module Foo
def self.foo a
puts a
end
end

class Bar
include Foo
foo “hello”
end

foo.rb:20: undefined method `foo’ for Bar:Class (NoMethodError)
####################################

but this does

class Bar
def self.foo a
puts a
end
foo “hello”
end

What am I misunderstanding about modules???

On 5/4/07, Brad P. [email protected] wrote:

class Bar
def self.foo a
Brad
http://xtargets.com

Module inclusion does not include singleton methods.

There are a few alternatives, the clearest one IMO being:

module Foo
def foo a # note no self.
puts a
end
end

class Bar
extend Foo # note extend, _not_include
foo “hello”
end

The other option is to augment the include procedure. Ruby provides a
hook
Module#included.

module Foo
def self.included(including_class_or_module)
class << including_class_or_module
def foo a
puts a
end
end
end
end

class Bar
include Foo
foo “hello”
end

Usually when people do this and a module contains both singleton methods
and
instance methods it will look something like:

module Foo
def inst_meth1
end

def inst_meth1
end

module ClassMethods
def foo a
puts a
end
end

def self.included(other)
other.extend ClassMethods
end
end

class Bar
include Foo
foo “hello”
end

Finally, you can of course use classes and plain old inheritance:

class Foo
def self.foo a
puts a
end
end

class Bar < Foo
foo “hello”
end

  puts "here"

David

Now that is the sneaky little hook I was looking for.

Thanks

Brad

Brad P. wrote:

include Foo
puts a
http://xtargets.com
The below code obviously work the way I wish

module Foo
def foo
puts “a”
end
end

class Bar
extend Foo
puts foo
end

however is there any way to get the same effect by using include. I
would like to mix in class and instance methods in one call. It seems
I can do one or the other but not both at the same time. Is that
correct?

Hi –

On Fri, 4 May 2007, Brad P. wrote:

class Bar
def self.foo a
Brad
class Bar
extend Foo
puts foo
end

however is there any way to get the same effect by using include. I would
like to mix in class and instance methods in one call. It seems
I can do one or the other but not both at the same time. Is that
correct?

Basically, yes: mixing in a module inserts the module in only one
method lookup path, and a class and its instances generally have very
different lookup paths.

You can use the inherited hook in Module to do both – for example:

module M
def self.included©
m = self
c.class_eval { extend m }
end

 def meth
   puts "here"
 end

end

class C
include M
end

C.meth # here
C.new.meth # here

David