From: transfire@... Date: 2006-06-13T22:35:14+09:00 Subject: Re: Why the lack of mixing-in support for Class methods? 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.