Why specify module names redundantly in Modules?

C

Chris

<RubyNubyAlert>
Doing my best to convert from Perl to Ruby, and mainly loving every
minute of it.

But I have a question about Modules... Why when I declare a Module, do
I have to prefix all the routines in that module with the module name
(or routines outside the module don't see it)? I don't get that?
Isn't this kind of redundant? For instance, I can't do this:

Module Foo
def bar
"bar"
end
end

puts Foo.bar

I have to do this:

Module Foo
def Foo.bar
"bar"
end
end

What's up with that? Seems redundant to me. (Oh, I already said
that!) :) But I thought I would ask. Maybe there is a good reason
for this? Or, maybe there is a way around this?
</RubyNubyA;ert>

Thanks!
-ceo
 
E

Evan Webb

The reason the methods aren't available as methods of the module
itself is because a module is a method container, ie it has a seperate
method table for all the methods defined inside it. But that method
table IS NOT the objects method table! By doing "extend self" you set
the module to be a superclass of itself and thus it's own methods are
available as methods of the module object by inheritence. "def
self.bar" works the same way, but injects the method into the module's
singleton superclass (it's singular metaclass), which is the first
class listed in the objects inheritence list. Hope that helps clear it
up and doesn't just add more confusion.

Evan
 
J

Jacob Fugal

<RubyNubyAlert>
Doing my best to convert from Perl to Ruby, and mainly loving every
minute of it.

But I have a question about Modules... Why when I declare a Module, do
I have to prefix all the routines in that module with the module name
(or routines outside the module don't see it)? I don't get that?
Isn't this kind of redundant? For instance, I can't do this:

Module Foo
def bar
"bar"
end
end

puts Foo.bar

I have to do this:

Module Foo
def Foo.bar
"bar"
end
end

I know there's a reason for this, but I'll leave it to the experts to
explain that. Meanwhile, let me show some alternate uses:

#------------------------------------

module Foo
def bar
puts "bar"
end
end

# Add bar as a singleton method of class A's metaobject.

class A
extend Foo
end

A.bar # => prints "bar"

begin
A.new.bar # => raises "undefined method `bar'"
rescue Exception => e
puts e
end

# Add bar as a public instance method of B.

class B
include Foo
end

B.new.bar # => prints "bar"

begin
B.bar # => raises "undefined method `bar'"
rescue Exception => e
puts e
end

# Add bar as a singleton method of c. Won't exist for other objects
of the same class.

class C
end

C.new.extend( Foo ).bar # => prints "bar"

begin
C.bar # => raises "undefined method `bar'"
rescue Exception => e
puts e
end

begin
C.new.bar # => raises "undefined method `bar'"
rescue Exception => e
puts e
end

#------------------------------------

Hope that helps make things a little clearer.

Jacob Fugal
 
L

Lionel Thiry

Hello.

I had the same problem in my beginnings.

But in fact, it is quite simple. Really simple when you realize that the main
and first purpose of modules is to extend classes. It is as if modules were just
class patches you can apply to the classes you want.

Then, now, using modules as namespaces for some classes or functions is just a
practical side effect. So practical that it is used all the time, but it is
still a side effect.
 
N

Neil Stevens

I have to do this:

Module Foo
def Foo.bar
"bar"
end
end

What's up with that? Seems redundant to me. (Oh, I already said
that!) :) But I thought I would ask. Maybe there is a good reason
for this? Or, maybe there is a way around this?

It is redundant, but you can do this:

Module Foo
def self.bar
"bar"
end
end

All that class and extend stuff some people are doing here is unnecessary,
as far as I can tell.
 
P

Paul Battley

All that class and extend stuff some people are doing here is unnecessary,
as far as I can tell.

Once you have three or more methods, 'extend self' once makes for less
typing than 'self.' prepended to each method name. Is that a good
reason? You choose.

Paul.
 
B

Bertram Scharpf

Hi,

Am Samstag, 16. Apr 2005, 04:34:36 +0900 schrieb Chris:
But I have a question about Modules... Why when I declare a Module, do
I have to prefix all the routines in that module with the module name
(or routines outside the module don't see it)? I don't get that?
Isn't this kind of redundant? For instance, I can't do this:

Module Foo
def bar
"bar"
end
end

puts Foo.bar

I have to do this:

Module Foo
def Foo.bar
"bar"
end
end

What's up with that? Seems redundant to me. (Oh, I already said
that!) :) But I thought I would ask. Maybe there is a good reason
for this? Or, maybe there is a way around this?

Say what you mean, understand what you say.

`bar' is a modules instance method. `Foo.bar' is a modules
classes singleton instance method, shortly a class method.

Please continue asking if you don't see it.

Bertram
 
R

Robert Klemme

Paul Battley said:
Once you have three or more methods, 'extend self' once makes for less
typing than 'self.' prepended to each method name. Is that a good
reason? You choose.

It's different from a semantical point of view: if you make a module extend
itself then you have those methods as instance methods (i.e. instances of
classes that include this module) as well as class methods. If you just
define them using def "sef.foo()..." then there are no instance methods.

Personal note: I don't like the idiom "module X; ... extend self end"
because it mixes module usage as mixin and namespace. You define instance
methods only to conveniently define them as class methods. Using "module X;
class<<self; def ... end end" or using "def self.foo..." is only slightly
more verbose but avoids this problem. I normally use a module *either* as
mix in (in that case I define instance methods) *or* as a namespace (in that
case I define class methods and classes inside the module).

# note the spelling "module" not "Module".
module Foo
def bar() "instance" end

# note: self == Foo, so these
# two are equivalent:
def self.bar() "class" end
def Foo.bar() "class" end
end

class X
include Foo
end

in IRB:
=> "instance"

HTH

Kind regards

robert
 

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


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top