I don’t think I understand you. Do you want to allow #include to
include classes? Without making it MI? Hmm.
It isn’t altogether obvious to me why a class passed to #include couldn’t be
interpreted as a module (since instances of Class are instances of Module
via inheritance).
module M
def initialize
‘ha’
end
end
module N
def initialize
‘ha ha’
end
end
class C
include M
include N
def initialize
‘hmmm’
end
end
with classes, this is always the situation. obviously it can be
dealt
with - but it’s a little less straight forward than the ‘normal’ mixin
effect.
not for or against here - but i do believe being able to mixin classes,
without some really slick handling of super/initialize, state, and
class_init
on ruby’s part would be confusing for most. in otherwords, ruby would
need to
become mi to do so.
end
be dealt
with - but it’s a little less straight forward than the ‘normal’
mixin effect.
I don’t see how your example is any different than the problem
presented by
nested includes. The ordering of ancestors and thus the resolution
of method
lookup is well defined in either case, no?
not for or against here - but i do believe being able to mixin
classes,
without some really slick handling of super/initialize, state, and
class_init
on ruby’s part would be confusing for most. in otherwords, ruby
would need to
become mi to do so.
Isn’t this already an issue with module-only includes? There was some
discussion on this recently I think.
We got to this point in the discussion because of the desire to auto-
mixin
module methods, which happen to reside inside a singleton class.
So this
raised the question of what does it mean to include a class? I still
don’t
like the idea of auto-mixin of module methods but to make sense of
that idea
you must somehow grapple with the notion that instance methods can
be implicitly extracted from a singleton class object (i.e. an
instance of Class).
Once you go down that road, it just begs the question of why you
can’t do that
with any class object.
In message “Re: Why the lack of mixing-in support for Class methods?”
on Wed, 14 Jun 2006 02:31:00 +0900, [email protected] writes:
|> I don’t think I understand you. Do you want to allow #include to
|> include classes? Without making it MI? Hmm.
|
|No no. You’d still only be able to include modules. I’m thinking a
|module’s “singleton class” could be a “singleton module”, so to speak,
|instead. It’s a bit difficult to communicate b/c the terminology is
|caught up in how it curently works. But it’s a lot less fancy than I
|think it sounds.
That makes modules too “special”. Every object has its own “singleton
class” (aka eigenclass) no matter what class it belongs to, under the
current implementation. After your proposal, modules should be
treated specially not to have ordinary singleton classes. I know its
purpose (to allow injecting a module’s singleton methods using #include), but I am not sure if it’s worth making object model
complex.
It seems Daniel’s API is good enough. What’s wrong with the idea?
Except for implementation issues, of course.
I don’t see how your example is any different than the problem presented by
nested includes. The ordering of ancestors and thus the resolution of
method lookup is well defined in either case, no?
yes. the problem is that mixin modules, by design, seldom have name
collisions with important instance methods, while mixin classes, if they
existed, always would. it’s a matter of degrees.
That makes modules too “special”. Every object has its own “singleton
class” (aka eigenclass) no matter what class it belongs to, under the
current implementation. After your proposal, modules should be
treated specially not to have ordinary singleton classes. I know its
purpose (to allow injecting a module’s singleton methods using #include), but I am not sure if it’s worth making object model
complex.
I see your point. This solution is kind of drastic in that respect.
Although I sort of liked the symmetry of a module being a module from
“head-to-toe” And it’s knid of too bad too, b/c this solution
limited the capability just to module’s class-level, where it’s needed
and no where else. Other solutions tend to be much broader and/or
hackish.
It seems Daniel’s API is good enough. What’s wrong with the idea?
Except for implementation issues, of course.
Well, that’s what I’ve been using already. In fact, as far as I can
tell the Facets’ implementation is the most complete around (not to say
it can’t be improved). But even so, it is hackish, inefficient, and
fragile, and that really can;t be hellped because of the naturr of
implementing it. And its’ made worse in that the techinque is without
standard, so nayone can run roughshod right over it. These are the
reasons why I’ve asked you directly about the issue. I’m essentially at
my wits end with it. I’ve spent more hours on this one problem than I
care to admit.
This evening is sadly no exception. I attempted another implementation,
which I think has a better overall interface (not as good as just being
able to include the singleton, but…)
module M
def meta.x
self
end
end
class X
meta_include M
end
X.x #=> X
Alas, an implementation of this appears to be impossible. Again those
singleton methods are just out of reach and it is frustrating to no
end.
In message “Re: Why the lack of mixing-in support for Class methods?”
on Wed, 14 Jun 2006 11:53:32 +0900, [email protected] writes:
|> It seems Daniel’s API is good enough. What’s wrong with the idea?
|> Except for implementation issues, of course.
|
|Well, that’s what I’ve been using already. In fact, as far as I can
|tell the Facets’ implementation is the most complete around (not to say
|it can’t be improved). But even so, it is hackish, inefficient, and
|fragile, and that really can;t be hellped because of the naturr of
|implementing it. And its’ made worse in that the techinque is without
|standard, so nayone can run roughshod right over it. These are the
|reasons why I’ve asked you directly about the issue. I’m essentially at
|my wits end with it. I’ve spent more hours on this one problem than I
|care to admit.
You got me wrong again. I asked you what if I’d add Daniel’s API to
the core.
|it can’t be improved). But even so, it is hackish, inefficient, and
|fragile, and that really can;t be hellped because of the naturr of
|implementing it. And its’ made worse in that the techinque is without
|standard, so nayone can run roughshod right over it. These are the
|reasons why I’ve asked you directly about the issue. I’m essentially at
|my wits end with it. I’ve spent more hours on this one problem than I
|care to admit.
You got me wrong again. I asked you what if I’d add Daniel’s API to
the core.
Ah yea, sorry for rambling. As I said, I already use that API, so, yea,
that works. I just don’t know the best solution and have been throwing
out ideas. I was hoping maybe you could tell us.
So if you did this, would #include handle the extending? Or would
another method need to be used?
Well, I hate to throw a wrench in the works at this point, but (by
God’s grace) I may have managed a better solution. It can be
implemented in either of two ways. Either by extending module with some
special methods like so:
class Module
def propagating_extensions
@propagating_extensions ||= []
end
def propagate( *mods )
propagating_extensions.concat mods
end
def extend_and_propagate( *mods )
propagate *mods
extend *mods
end
alias_method :append_features_without_propagation, :append_features
def append_features( base )
unless propagating_extensions.empty?
base.extend_and_propagate *propagating_extensions
end
append_features_without_propagation( base )
end
end
Or alternatively sepearating the capability into a subclass of module:
class Capsule < Module
def extensions
@extensions ||= []
end
def propagate( *mods )
extensions.concat mods
end
def extend( *mods )
propagate *mods
super
end
def append_features( base )
unless extensions.empty?
base.extend *extensions
end
super
end
end
The later is a little more elegant in implementation but requires the
use of the specialized class to continue the propogating behavior. The
former doesn’t need the special class, but does require an additional
special method.
Here’s an example of using the first implementation.
In message “Re: Why the lack of mixing-in support for Class methods?”
on Wed, 14 Jun 2006 15:34:43 +0900, “Phil T.” [email protected] writes:
|> class_extension do
|
|Maybe it could be called class_methods ?
I thought of the name first, but I changed my mind because it is too
similar to methods with different behavior e.g. private_methods.
Besides that class_extension can be used for something other than
methods, for example, constant definition.
|> Foo.im
|
|Do you mean Foo.cm ?
Yes. What a shame.
|Is this just a more automatic/nicer way to do:
|
|module Moo
| def self.included mod
| mod.extend ClassMethods
| end
| module ClassMethods
| def cm
| end
| end
| def im
| end
|end
|
|class Foo
| include Moo
|end
|
|?
I think I still prefer this approach, though the method thing is OK
with me too (as long as we don’t call it class_methods()).
If you allow #class_extension (or whatever you want to call it) to also
take a list of modules in addition to the block, then you’d effectively
have it both ways. Ex-
module Moo
module ClassMethods
def cm
end
end
class_extension ClassMethods
end
I think class_extension (or whatever) plus and include will do.
Nice point.
Okay, so I’m wondering, will the annonymous module this creates get a
name of some sort instead of the ususal “#Module:0xb7ca7e1c” and if
the class_extension method is used more than once will it create an
additional new module or just reuse the first?
In message “Re: Why the lack of mixing-in support for Class methods?”
on Wed, 14 Jun 2006 23:30:25 +0900, [email protected] writes:
|Okay, so I’m wondering, will the annonymous module this creates get a
|name of some sort instead of the ususal “#Module:0xb7ca7e1c” and if
|the class_extension method is used more than once will it create an
|additional new module or just reuse the first?
I am not thinking about implementation detail yet. What do you think
how it should behave?
Okay, so I’m wondering, will the annonymous module this creates get a
name of some sort instead of the ususal “#Module:0xb7ca7e1c”
I was thinking that the block would just be evaluated in the context of
the targeted singleton class as vs. the context of a new anonymous
module which is then included into the targeted singleton class.