Why must I know whether I extend a class or a module?

Hi.

I have one module and one class.

module Foo
def test
puts ‘This is method test() from module Foo.’
end
end

class Bar
def test
puts ‘This is method test() from class Bar.’
end
end

If I want to modify that at a later time, I need
to do something like:

module Foo
def test
puts ‘Yes, still testing’.
end
end

Or

class Bar

etc…

My question is:

  • Why do I need to KNOW that it is a module or a class?

Can’t I simply say “I do not care what it is a class or a module, simply
add this method to it.”?

I don’t understand why I need to explicitely know that one is a module
and the other is a class.

Was there a reason this distinction was used?

I don’t have a good alternative though. I thought about:

modify Bar
modify Class

but that would require a new keyword I suppose. And typing “modify” is
also longer than typing class. So there is no real advantage.

So my real question is not so much about that I want a change (I don’t
think there is a good change for it, so the current way is probably good
enough), but my question is:

  • Why are things this way? Does anyone know?

PS: On the other hand, when we can god-patch a class or a module, and
undo these changes, perhaps we could also overcome the separation
between classes and modules when I want to modify their behaviour. From
a design point of view, I dont really think it should be needed to know
whether one modifies a module or a class. (Ruby’s behaviour could be to
first search for class, then for module.)

Marc H. wrote in post #1057208:

Hi.

I have one module and one class.

module Foo
def test
puts ‘This is method test() from module Foo.’
end
end

class Bar
def test
puts ‘This is method test() from class Bar.’
end
end

If I want to modify that at a later time, I need
to do something like:

module Foo
def test
puts ‘Yes, still testing’.
end
end

Or

class Bar

etc…

My question is:

  • Why do I need to KNOW that it is a module or a class?

Can’t I simply say “I do not care what it is a class or a module, simply
add this method to it.”?

Yes you can:

class Foo; end
=> nil

module Bar; end
=> nil

Foo.module_eval { def xxx; puts “xxx”; end }
=> nil

Bar.module_eval { def yyy; puts “yyy”; end }
=> nil

Foo.new.xxx
xxx
=> nil

Object.new.extend(Bar).yyy
yyy
=> nil

Note that module_eval and class_eval both exist, but I have not been
able to find a case where they behave differently; as far as I know they
are interchangeable.

I don’t understand why I need to explicitely know that one is a module
and the other is a class.

I guess it’s just a syntax choice, and a safety feature - you don’t
accidentally add methods to a module when you meant a class, or vice
versa.

After all, when you write

module Foo ...

then you are talking about a single thing, “Foo”, so you almost
certainly know what kind of thing it is. If you want to do it
dynamically (e.g. the module or class is in a variable) then you need a
different syntax anyway:

var = Foo
var.module_eval { … }

or:

var = :Foo
m = Object.const_get(var)
m.module_eval { … }

Regards,

Brian.

Hi,

The syntax you’re talking about is used both for defining and modifying
a class/module. That’s why there’s an explicit “class” or “module”
keyword in it.

If you don’t want to distinguish between a class and a module, use the
class_eval method. This works for both:

module M; end

M.class_eval do
def test
puts 1
end
end

However, I can barely imagine this problem will ever occur in reality. I
mean: Do you really add methods to objects you don’t even know?

Hi,

On Wed, Apr 18, 2012 at 1:13 PM, Marc H. [email protected]
wrote:

class Bar
def test

I don’t have a good alternative though. I thought about:

  • Why are things this way? Does anyone know?

PS: On the other hand, when we can god-patch a class or a module, and
undo these changes, perhaps we could also overcome the separation
between classes and modules when I want to modify their behaviour. From
a design point of view, I dont really think it should be needed to know
whether one modifies a module or a class. (Ruby’s behaviour could be to
first search for class, then for module.)

You may be able to use class_eval:

#! /usr/bin/env ruby

class Foo
def self.quux
puts “Foo#quux”
end
end

module Bar
def self.quux
puts “Bar#quux”
end
end

Foo.quux # => “Foo#quux”
Bar.quux # => “Bar#quux”

Foo.class_eval do
def self.quux
puts “Foo overridden”
end
end

Bar.class_eval do
def self.quux
puts “Bar overridden”
end
end

Foo.quux # => “Foo overridden”
Bar.quux # => “Bar overridden”

Eric C. wrote in post #1057249:

Also, I see huge disadvantages to metaprogramming because
it hides you logic in a puzzle.

Just because you can do something tricky, doesn’t mean its advisable.

Sure. But the code above I wouldn’t really call “metaprogramming”. It’s
simply an alternative to the standard way of adding new methods. If you
don’t like it, you’ll actually have to reject the whole idea of dynamic
classes.

But I do agree that metaprogramming should be used with caution (or
maybe even avoided), since it can make the code hard to understand to a
point where the behaviour is almost unpredictable.

On 19/04/2012, at 8:22 AM, “Eric C.” [email protected] wrote:

I can’t pretend to know everything about Ruby, but I’ve read a bit about
metaprogramming, and I’ve never been sold on it being a good way to
write code. There may be uses that I don’t know about, but I haven’t
found them.

Ever used attr_reader, attr_writer or attr_accessor? All excellent uses
of metaprogramming.

Henry

I can’t pretend to know everything about Ruby, but I’ve read a bit about
metaprogramming, and I’ve never been sold on it being a good way to
write code. There may be uses that I don’t know about, but I haven’t
found them. Also, I see huge disadvantages to metaprogramming because
it hides you logic in a puzzle.

Just because you can do something tricky, doesn’t mean its advisable.

W dniu 19 kwietnia 2012 07:59 użytkownik Intransition
[email protected] napisał:

On Wednesday, April 18, 2012 1:13:17 PM UTC-4, Marc H. wrote:

  • Why do I need to KNOW that it is a module or a class?

I concur. I have been a long advocate of removing the distinction between
class and module. It’s not really a necessary distinction.

I disagree. You are not supposed to instantiate modules; you do are
supposed to instantiate classes. Even if the difference between the
two is small in your code or in Ruby source, the conceptual gap is
huge.

– Matma R.

On Wed, Apr 18, 2012 at 3:22 PM, Eric C. [email protected] wrote:

I think they make sense for gems, where you don’t know who or how it is
going to need this code. But for my own code, I rarely use
metaprogramming.

As an aside, the names seem backwards. Using “class XXX” and “def xxx”
is
more metaprogramming than “const_set XXX, Class.new” and “define_method
xxx”

On Wednesday, April 18, 2012 1:13:17 PM UTC-4, Marc H. wrote:

  • Why do I need to KNOW that it is a module or a class?

I concur. I have been a long advocate of removing the distinction between
class and module. It’s not really a necessary distinction.

On Thursday, April 19, 2012 1:18:05 PM UTC-4, Bartosz Dziewoński wrote:

I disagree. You are not supposed to instantiate modules; you do are
supposed to instantiate classes. Even if the difference between the
two is small in your code or in Ruby source, the conceptual gap is
huge.

No, not really. You just summed it up in one sentence. So instantiate it
as needs be, and don’t when you don’t. It is how you use it.

The forced distinction only serves to take that flexibility away from
the
programmer.

There are other benefits too in that removing the distinction would
allow
auto instantiation, e.g.

class Foo::Bar
end

Would work just fine, even though no Foo has been defined separately.
This can be especially nice when requiring sub-files.

On 20 April 2012 13:53, Intransition [email protected] wrote:

The forced distinction only serves to take that flexibility away from the
programmer.

Is there not overhead associated with that distinction? I haven’t
actually looked into it, but I’d assume that Modules are a lot more
light-weight than Classes, because of the things that can’t be done
with them.

There are other benefits too in that removing the distinction would allow
auto instantiation, e.g.

class Foo::Bar
end

Would work just fine, even though no Foo has been defined separately. This
can be especially nice when requiring sub-files.

I can see that this would be convenient, but it also makes me cringe.
You’re defining a namespace Foo without ever explicitly defining it.
Why? What’s its purpose? How and where is it documented? I can’t
make my gut instinct accept this as anything but a bad idea.


Matthew K., B.Sc (CompSci) (Hons)
http://matthew.kerwin.net.au/
ABN: 59-013-727-651

“You’ll never find a programming language that frees
you from the burden of clarifying your ideas.” - xkcd

On 21/04/2012, Intransition [email protected] wrote:

actually looked into it, but I’d assume that Modules are a lot more
light-weight than Classes, because of the things that can’t be done
with them.

The Class class is subclass of Module and is almost devoid of it’s own
methods.

Fair enough. Must be a pragmatism issue then. Unless the cost of
discovering and defining constructors and initializers is somehow more
than we’d expect.

What about multiple inheritance? Is/should it be valid to mix in a
class instead of a module? Actually, what happens right now if you
define a class with no initializer, and mix in a module that defines
__initialize ?

...

I don’t like requires at the bottom.

Or the alternative:

require ‘myapp/adapters/core’
require ‘myapp/adapters/foo’
require ‘myapp/adapters/bar’
module MyApp::Adapters

stuff that uses foo and bar

end

Even so, there are times when it doesn’t really matter. If for instance my
MyApp::Adapters module had no contents other then the adapter classes, then
it really makes no difference.

I guess I have a hole in my instinctive response for the right
approach to ‘modules as a namespace’, since I usually use them as
interfaces/multiple-inheritance/mixins.


Matthew K., B.Sc (CompSci) (Hons)
http://matthew.kerwin.net.au/

“You’ll never find a programming language that frees
you from the burden of clarifying your ideas.” - xkcd

On Friday, April 20, 2012 11:15:50 PM UTC-4, Matthew K. wrote:

than we’d expect.

What about multiple inheritance? Is/should it be valid to mix in a
class instead of a module? Actually, what happens right now if you
define a class with no initializer, and mix in a module that defines
__initialize ?

Well, it’s funny you should ask. That has always been Matz’ goto reason
against the idea. He “hates” multiple inheritance and he sees this as
such.
I don’t see it that way for a few reasons. Mainly b/c mixins already
effectively serve the same purpose. In deed one could technically write
all
their code using modules.

module Bar
def self.new
Class.new{ include Bar }
end
def initialize
end
end

And yes, there is nothing stopping one from mixing in an #initialize
method.

require ‘myapp/adapters/core’
require ‘myapp/adapters/foo’
require ‘myapp/adapters/bar’
module MyApp::Adapters

stuff that uses foo and bar

end

In the case myapp/adapters/core.rb is creating Adapters module.

Even so, there are times when it doesn’t really matter. If for instance
my
MyApp::Adapters module had no contents other then the adapter classes,
then
it really makes no difference.

I guess I have a hole in my instinctive response for the right
approach to ‘modules as a namespace’, since I usually use them as
interfaces/multiple-inheritance/mixins.

I have considered forking Rubinius and implementing this --but I am not
100% sure how involved it would be.

On 22 April 2012 18:01, Intransition [email protected] wrote:

Well, it’s funny you should ask. That has always been Matz’ goto reason
against the idea. He “hates” multiple inheritance and he sees this as such.

That’s … absurd; the ‘include’ statement is the paragon of multiple
inheritance. I always thought that the search path from class to
modules to superclass and so on was a brilliant solution to such a
frequently murky and messy topic.

My worldview is somewhat shaken now.

I guess I have a hole in my instinctive response for the right
approach to ‘modules as a namespace’, since I usually use them as
interfaces/multiple-inheritance/mixins.

I have considered forking Rubinius and implementing this --but I am not 100%
sure how involved it would be.

I’m sorry, implementing what, precisely?


Matthew K., B.Sc (CompSci) (Hons)
http://matthew.kerwin.net.au/
ABN: 59-013-727-651

“You’ll never find a programming language that frees
you from the burden of clarifying your ideas.” - xkcd

On Sunday, April 22, 2012 9:01:53 AM UTC-4, Matthew K. wrote:

My worldview is somewhat shaken now.

Pretty much my sentiments exactly.

I guess I have a hole in my instinctive response for the right
approach to ‘modules as a namespace’, since I usually use them as
interfaces/multiple-inheritance/mixins.

I have considered forking Rubinius and implementing this --but I am not
100%
sure how involved it would be.

I’m sorry, implementing what, precisely?

Basically:

  1. Allow classes to be included.
  2. Allow modules to be instantiated.
  3. Allow module’s class-methods to be “inherited” just like class’
    class-methods.

This would effectively make classes and modules exactly same.

Also,

  1. Auto-instantiate namespaces.
  2. Make toplevel a self extended module that doesn’t infect all objects.

On Friday, April 20, 2012 8:12:37 PM UTC-4, Matthew K. wrote:

On 20 April 2012 13:53, Intransition [email protected] wrote:

The forced distinction only serves to take that flexibility away from the
programmer.

Is there not overhead associated with that distinction? I haven’t
actually looked into it, but I’d assume that Modules are a lot more
light-weight than Classes, because of the things that can’t be done
with them.

The Class class is subclass of Module and is almost devoid of it’s own
methods.

I can see that this would be convenient, but it also makes me cringe.
You’re defining a namespace Foo without ever explicitly defining it.
Why? What’s its purpose? How and where is it documented? I can’t
make my gut instinct accept this as anything but a bad idea.

Typically that would be the case – the encasing module/class would be
defined ultimately. This way it just doesn’t have to be done prior to
classes/module internal to it.

For example in project I often need adapters.

class MyApp::Adapters::Foo
class MyApp::Adapters::Bar

In the myapp/adapters.rb I’ve would like to write:

require ‘myapp/adapters/foo’
require ‘myapp/adapters/bar’

module MyApp::Adapters

end

But instead I have to do:

module MyApp::Adapters

end

require ‘myapp/adapters/foo’
require ‘myapp/adapters/bar’

I don’t like requires at the bottom.

Even so, there are times when it doesn’t really matter. If for instance
my
MyApp::Adapters module had no contents other then the adapter classes,
then
it really makes no difference.

On Sun, Apr 22, 2012 at 3:01 AM, Intransition [email protected]
wrote:

And yes, there is nothing stopping one from mixing in an #initialize
method.

You’d have to also extend class methods.