Daniel Schierbeck wrote:

> you suggesting we replace module objects' singleton classes with such a
> "module-level", or would the singleton methods and constants be defined
> in both?

You have to understand a little about how modules are tied into the
inhertiance chain. Modules are linked via virtual classes. (There are
some good diagrams of this in the Pickaxe, I believe it's under
"Classes and Objects").  The idea is then to replace a module's current
"metaclass" with a virtual class linking in a "metamodule". Anything in
a module's "class << self" then is defined in this metamodule instead.

> What I thought would be great about allowing #include and #extend to
> accept Class objects is that it would make it much easier for a module
> (or, well, class) author to decide for himself whether or not he wishes
> to have the module methods included as well.

Well, one can argue the merits for or against that. But it goes beyond
the need at hand. The division between module and class I think suits
Ruby. Allowing classes to be included outright, while not MI
underthehood, nonetheless appears as such on the surface b/c a class
than appears to be a child of a more than one class. But having modules
distinct, it can only be the child of one class and instead agumented
with extra modular behaviors.

> I agree with you that
> multiple inheritance would mean a non-linear line of inheritance, and
> that allowing Class objects to be included would not have such a
> consequence. Basically, I think module authors should be able to write this:
>
>    module MyModule
>      def self.included(mod)
>        mod.extend(class << self; self; end)
>      end
>
>      def self.foo
>        "a class method"
>      end
>
>      def bar
>        "an instance method"
>      end
>    end
>
>    class Test
>      include MyModule
>    end
>
>    Test.foo      #=> "a class method"
>    Test.new.bar  #=> "an instance method"
>
> I think module authors should be able to make that decision (as they do
> now, with the hacks and all.)

While I'm for 'mod.extend(class << AModule; self; end)'. I think the
use of #included is done nowadays b/c there is no other obvious way to
achieve the same thing. I think it's unfortuate to have to depend on a
callback --and as things stand it goes beyond what a module user
generally expects from #include. So in that respect it's not really a
good practice. What we really need is a good practice to replace this
callback pattern.

> This would also allow module "users" to
> opt-in on the module methods:
>
>    class Module
>      def inherit(*mods)
>        include *mods
>        mods.each{|mod| extend(class << mod; self; end)}
>      end
>    end

Yes, I think that's a fair option. And IMHO would say that it's the 2nd
best choice, behind the ability to specify 'extensible' and
'uninheritable' sections in ones modules. I still tend to think that
the the control is best left to a module itself. But short of that,
then this would be a good way. Of course, matz, doesn't like the term
"inherit" bc/ it invokes ideas of MI, but any name will do.

> (geez, it sure would be nice with a shorthand for singleton classes...)

I agree. I've been toying with "own" and "owner" lately myself.

T.