Modules as namespaces

S

Sam Stephenson

I'm trying to nest modules to create namespaces, but I'm not having
much luck. Let's say I have

| module A
| module B
| def foo; @foo end
| end
| end
|
| class Foo
| include A
| def initialize; @foo = 'foo' end
| def bar; B::foo end
| end

Calling Foo#bar raises "NoMethodError: undefined method `foo' for
A::B.Module". I would like to get "foo". What am I doing wrong?

Sam
 
F

Florian Gross

Sam said:
I'm trying to nest modules to create namespaces, but I'm not having
much luck. Let's say I have

| module A
| module B
| def foo; @foo end
| end
| end
|
| class Foo
| include A
| def initialize; @foo = 'foo' end
| def bar; B::foo end
| end

Calling Foo#bar raises "NoMethodError: undefined method `foo' for
A::B.Module". I would like to get "foo". What am I doing wrong?

foo is an instance_method of the module B and not a method of B itself.
(This may sound odd, but modules can be instantiated indirectly by
include()ing them in a Class.)

Use module_function :foo or put an "extend self" at the beginning of the
module. (That will make all the methods module functions automatically.)

This is a problem that people have quite frequently and indeed, it is
also not obvious at first why Modules (which are used for Namespaces)
work this. Maybe it should be added to the FAQ and that traps for
newcomers list? (Was it on the Wiki? I'm not sure I remember correctly.)

Regards,
Florian Gross
 
J

Joel VanderWerf

Sam said:
I'm trying to nest modules to create namespaces, but I'm not having
much luck. Let's say I have

You need to make foo a module method of B:
| module A
| module B
| def foo; @foo end def B::foo; @foo; end
| end
| end
|
| class Foo
| include A
| def initialize; @foo = 'foo' end
| def bar; B::foo end
| end

Calling Foo#bar raises "NoMethodError: undefined method `foo' for
A::B.Module". I would like to get "foo". What am I doing wrong?

Sam

The way you had it originally, you were defining an _instance_ method of
B. If you had included B in some class, you could then call foo as an
method of instances of that class.
 
S

Sam Stephenson

You need to make foo a module method of B:
| module A
| module B
def B::foo; @foo; end
| end
| end
The way you had it originally, you were defining an _instance_ method of
B. If you had included B in some class, you could then call foo as an
method of instances of that class.

Okay, I see. But now Foo#bar gives nil.

So mixing in a module doesn't mix-in other modules "inside it" in the same way?

Sam
 
J

Joel VanderWerf

Sam said:
Okay, I see. But now Foo#bar gives nil.

So mixing in a module doesn't mix-in other modules "inside it" in the same way?

Nope. The namespace containment hierarchy is different from the
inheritance hierarchy.
 
D

David A. Black

[re-sending an answer that didn't seem to make it for some reason]

Hi --

I'm trying to nest modules to create namespaces, but I'm not having
much luck. Let's say I have

| module A
| module B
| def foo; @foo end
| end
| end
|
| class Foo
| include A
| def initialize; @foo = 'foo' end
| def bar; B::foo end
| end

Calling Foo#bar raises "NoMethodError: undefined method `foo' for
A::B.Module". I would like to get "foo". What am I doing wrong?

The notation B::foo mean's B's own foo method:

module B
def B.foo
puts "hi"
end
end

B::foo # hi

To get your Foo object to have the method B#foo in its path, you'd
have to include the module (A::B) in Foo, or extend your object with
it.


David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Modules as namespaces 2
Alias method in module 5
Question regarding interaction between modules and classes 2
modules and class methods. 3
Modules 2
modules 8
Rules for constant lookup 0
Dynamically mixins? 5

Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,244
Latest member
cryptotaxsoftware12

Latest Threads

Top