Why does Module#include exclude the module's metaclass?

When classes are inherited in Ruby the singleton classes are also
inherited:

class A
  def self.hello
    puts "hello"
  end
end

class B < A
end

B.hello #=> "hello"
Yet with modules, this is not the case:

module M
  def self.goodbye
    puts "goodbye"
  end
end

class A
  include M
end

A.goodbye #=> NameError
To get around this limitation many ppl resort to this ugly hack:

module M
  def self.included(c)
    c.extend ClassMethods
  end

  module ClassMethods
    def goodbye
      puts "goodbye"
    end
  end
end
Ok, so my question: is there a theoretical/conceptual reason behind this
limitation on modules? or was it just an implementation difficulty?

After looking at the C source code (YARV/MRI) I can identify there is an
implementation difficulty (not insurmountable, but one all the same),
but is this the sole reason? Are there any other reasons for this
limitation?

thanks

···

--
Posted via http://www.ruby-forum.com/.

When classes are inherited in Ruby the singleton classes are also
inherited:

class A
def self.hello
puts "hello"
end
end

class B < A
end

B.hello #=> "hello"

ok. single inheritance

Yet with modules, this is not the case:

module M
def self.goodbye
puts "goodbye"
end
end

class A
include M
end

A.goodbye #=> NameError

class A
  include M
  include N
end

now, which goodbye??

To get around this limitation many ppl resort to this ugly hack:

sorry, ' prefer specs over hacks :slight_smile:

module ClassMethods
  def goodbye
    puts "goodbye"
  end
end
#=> nil

class A
  class << self
    include ClassMethods
  end
end
#=> #<Class:A>

A.goodbye
goodbye

clearer, if i may say.

best regards -botp

···

On Thu, Oct 7, 2010 at 7:33 AM, John Mair <jrmair@gmail.com> wrote:

(2010/10/07 8:33), John Mair wrote:

Ok, so my question: is there a theoretical/conceptual reason behind this
limitation on modules? or was it just an implementation difficulty?

The former.

1) So-called "class methods" are singleton methods of those Class class instances.

2) A module's class methods are hence, singleton methods of a Module class
instance. To say it in another word, they are instance methods of the
singleton class of such module.

3) So if you want a module inclusion to cause somewhat injecting a module's
singleton methods into a class's, there should be this relationship:

+---------+ +---------+

Meta A +---> Meta M |

+----^----+ +----^----+
     > >
  +--+--+ +--+--+
  > A +-------> M |
  +-----+ +-----+

4) But this is impossible, because Meta M is a class. A class cannot be
included into another class.

For no good reason other than a purely theoretical misconception
concerning single vs multiple inheritance --at least that's the only
reason I have ever been able to derive from my countless inquiries
I've made into the subject.

Over the years I have become increasing convinced that the distinction
between class and module in Ruby is simply an artifice that inhibits
the language unduly.

···

On Oct 6, 7:33 pm, John Mair <jrm...@gmail.com> wrote:

When classes are inherited in Ruby the singleton classes are also
inherited:

class A
def self.hello
puts "hello"
end
end

class B < A
end

B.hello #=> "hello"
Yet with modules, this is not the case:

module M
def self.goodbye
puts "goodbye"
end
end

class A
include M
end

A.goodbye #=> NameError
To get around this limitation many ppl resort to this ugly hack:

module M
def self.included(c)
c.extend ClassMethods
end

module ClassMethods
def goodbye
puts "goodbye"
end
end
end
Ok, so my question: is there a theoretical/conceptual reason behind this
limitation on modules? or was it just an implementation difficulty?

After looking at the C source code (YARV/MRI) I can identify there is an
implementation difficulty (not insurmountable, but one all the same),
but is this the sole reason? Are there any other reasons for this
limitation?

Hehe,

I don't know which question you were answering but it definitely wasn't
mine! :slight_smile:

I asked why, when including a module, the singleton class is not also
included. Whereas when performing class inheritance the singleton IS
inherited.

I am just curious to the difference in behaviour; as I can't think of a
reason why module inclusion would work differently to class inheritance
:frowning:

John

botp wrote:

···

On Thu, Oct 7, 2010 at 7:33 AM, John Mair <jrmair@gmail.com> wrote:

end

B.hello #=> "hello"

ok. single inheritance

end

A.goodbye #=> NameError

class A
  include M
  include N
end

now, which goodbye??

To get around this limitation many ppl resort to this ugly hack:

sorry, ' prefer specs over hacks :slight_smile:

module ClassMethods
  def goodbye
    puts "goodbye"
  end
end
#=> nil

class A
  class << self
    include ClassMethods
  end
end
#=> #<Class:A>

A.goodbye
goodbye

clearer, if i may say.

best regards -botp

--
Posted via http://www.ruby-forum.com/\.

Thanks for your reply.

But this argument seems too subtle for me.

1) I agree that singleton class of the module is actually a 'class' but
(if we allowed this behavior) it would only be included when and only
when the module is included. We can just consider this a special
exception, no?

This exception would only apply to singleton class of modules, of
course, normal classes cannot be included in this way.

2) Given that class inheritance does include the singleton, do you not
think it 'surprising' that module inclusion does not? I found it
surprising.

3) Many people get around this limitation in module inclusion by abusing
the included() hook and then extending a ClassMethods submodule, I think
this is ugly.

3) Out of curiosity, are there any other reasons (besides the one you
gave) for why modules do not include the singleton? What reason did Matz
give?

Thanks in advance,

John

Urabe Shyouhei wrote:

···

(2010/10/07 8:33), John Mair wrote:

Ok, so my question: is there a theoretical/conceptual reason behind this
limitation on modules? or was it just an implementation difficulty?

The former.

1) So-called "class methods" are singleton methods of those Class class
instances.

2) A module's class methods are hence, singleton methods of a Module
class
instance. To say it in another word, they are instance methods of the
singleton class of such module.

3) So if you want a module inclusion to cause somewhat injecting a
module's
singleton methods into a class's, there should be this relationship:

+---------+ +---------+
> Meta A +---> Meta M |
+----^----+ +----^----+
     > >
  +--+--+ +--+--+
  > A +-------> M |
  +-----+ +-----+

4) But this is impossible, because Meta M is a class. A class cannot be
included into another class.

--
Posted via http://www.ruby-forum.com/\.

matz has humbly commented on this...

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274242

and was open and kind enough...

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274247

best regards -botp

···

On Thu, Oct 7, 2010 at 12:31 PM, Intransition <transfire@gmail.com> wrote:

For no good reason other than a purely theoretical misconception
concerning single vs multiple inheritance --at least that's the only
reason I have ever been able to derive from my countless inquiries
I've made into the subject.

Over the years I have become increasing convinced that the distinction
between class and module in Ruby is simply an artifice that inhibits
the language unduly.

@Thomas,

I agree, in fact I wrote a little C extension to bring this
functionality to modules http://github.com/banister/real_include
Use it like this:

module M
  def self.hello
    puts "hello from class"
  end

  def bye
    puts "bye from instance"
  end
end

class A
  real_include M
end

A.hello #=> "hello from class"
A.new.bye #=> "bye from instance"

I would love to hear from Matz himself why this limitation is built in;
as most of the explanations i've heard have just been along the lines of
"that's not how modules work". In my opinion the current behavior does
violate the principle of least surprise.

@botp

Thanks for the links :slight_smile: But I don't see how they are on point at all.
He's talking there about a 'traits' system, he didn't say *anything*
about traits bringing in singleton methods or not. Sorry but i can't see
the relevance :frowning: (though maybe i just don't know enough about traits?!)

John

Thomas Sawyer wrote:

···

On Oct 6, 7:33�pm, John Mair <jrm...@gmail.com> wrote:

end
class A

implementation difficulty (not insurmountable, but one all the same),
but is this the sole reason? Are there any other reasons for this
limitation?

For no good reason other than a purely theoretical misconception
concerning single vs multiple inheritance --at least that's the only
reason I have ever been able to derive from my countless inquiries
I've made into the subject.

Over the years I have become increasing convinced that the distinction
between class and module in Ruby is simply an artifice that inhibits
the language unduly.

--
Posted via http://www.ruby-forum.com/\.

single inheritance for class includes their singletons. single class
inclusion easy to track.
mixin is many modules inclusion. if ruby includes mods singletons,
then it would not be different to multiple inheritance, no. difficult
to track on dynamic lang. ..confusing as to design of ruby... matz
has final say

best regards -botp

···

On Thu, Oct 7, 2010 at 8:59 AM, John Mair <jrmair@gmail.com> wrote:

I asked why, when including a module, the singleton class is not also
included. Whereas when performing class inheritance the singleton IS
inherited.
I am just curious to the difference in behaviour; as I can't think of a
reason why module inclusion would work differently to class inheritance
:frowning:

(2010/10/07 10:59), John Mair wrote:

1) I agree that singleton class of the module is actually a 'class' but
(if we allowed this behavior) it would only be included when and only
when the module is included. We can just consider this a special
exception, no?

This exception would only apply to singleton class of modules, of
course, normal classes cannot be included in this way.

So you were actually not asking why, but claiming this is wrong. Not sure for
that. Your real_include gem breaks Class#ancestor in a strange way so I guess
there are some pitfalls, though noting particular.

2) Given that class inheritance does include the singleton, do you not
think it 'surprising' that module inclusion does not? I found it
surprising.

Tips: principle of least surprise is a wrong way for you to persuade matz
because at any moment he can say "I don't think so". Try a different route.

3) Many people get around this limitation in module inclusion by abusing
the included() hook and then extending a ClassMethods submodule, I think
this is ugly.

Maybe. But I think a module's having class method is itself ugly. It tends
to smell like a API design mistake. I would recommend you to rethink why you
need such things.

3) Out of curiosity, are there any other reasons (besides the one you
gave) for why modules do not include the singleton? What reason did Matz
give?

No, I do not know other reasons. It is rather obvious to me. Of course that
does not ensure there is not reason though.

@Urabe,

sorry if my reply seemed rude or snarky, i did not mean it that way :slight_smile:

yeah #ancestors behave strange with real_include, I think this is due to
the fact that normal T_ICLASS store the actual module in the klass
pointer but real_include store a singleton class there, which #ancestors
does not expect.

I think the best approach (if real_include or something like it accepted
as a patch) would be to store the actual module in a hidden __module__
instance variable on the ICLASS (just like __attached__ for singleton
class) and #ancestors can look at this instead of klass pointer.

I can see some other arguments for not bringing in module singleton
methods with #include, one for example is that the hook methods
included() and extended() will be accessible to the class too, which is
ugly.

I think there are OK arguments either way; but it's not such a serious
issue really - to be honest i was just curious why it is that way :slight_smile:

Thanks for your time:)

John

Urabe Shyouhei wrote:

···

(2010/10/07 10:59), John Mair wrote:

1) I agree that singleton class of the module is actually a 'class' but
(if we allowed this behavior) it would only be included when and only
when the module is included. We can just consider this a special
exception, no?

This exception would only apply to singleton class of modules, of
course, normal classes cannot be included in this way.

So you were actually not asking why, but claiming this is wrong. Not
sure for
that. Your real_include gem breaks Class#ancestor in a strange way so I
guess
there are some pitfalls, though noting particular.

2) Given that class inheritance does include the singleton, do you not
think it 'surprising' that module inclusion does not? I found it
surprising.

Tips: principle of least surprise is a wrong way for you to persuade
matz
because at any moment he can say "I don't think so". Try a different
route.

3) Many people get around this limitation in module inclusion by abusing
the included() hook and then extending a ClassMethods submodule, I think
this is ugly.

Maybe. But I think a module's having class method is itself ugly. It
tends
to smell like a API design mistake. I would recommend you to rethink
why you
need such things.

3) Out of curiosity, are there any other reasons (besides the one you
gave) for why modules do not include the singleton? What reason did Matz
give?

No, I do not know other reasons. It is rather obvious to me. Of course
that
does not ensure there is not reason though.

--
Posted via http://www.ruby-forum.com/\.