Modules are inserted into the inheritance chain. So if you do something like:
class A
def x
"x"
end
end
module X
def x
"y"
end
end
class A
include X
end
a = A.new
a.x (Look for #x in my singleton class, can't find it? Ok, look for it in A, aha! found it! return "x")
class B
include X
end
b = B.new
b.x (Look for #x in my singleton class, can't find it? Ok, look for it in B, can't find it? Ok, look for it in X, aha! found it return "y")
As you can see, it doesn't really have anything to do with the fact that it's a singleton class, it's just how modules work.
The reason why using #extend can override something declared in an objects class is because the singleton class is earlier in the inheritance chain than the actual class of the object. extend includes the module into the singleton class which puts it earlier than the object's real class.
···
On Jun 28, 2006, at 1:13 PM, Jonas Pfenniger wrote:
... in the particular case where the method already exists.
== Example
class Cls; end
class Cls2; end
def Cls.somemethod
"defined in Cls"
end
Cls.somemethod #=> "defined in Cls"
module Mod
def somemethod
"defined in Mod"
end
end
Cls.extend Mod
Cls2.extend Mod
Cls.somemethod #=> "defined in Cls"
Cls2.somemethod #=> "defined in Mod"
Not sure if I read it correctly but in both cases the singleton method
is the first looked for, than the class and than any included modules,
so considering the chain of inheritance I would say that the singleton
is the leaf.
On 6/28/06, Logan Capaldo <logancapaldo@gmail.com> wrote:
On Jun 28, 2006, at 1:13 PM, Jonas Pfenniger wrote:
> ... in the particular case where the method already exists.
>
> == Example
>
> class Cls; end
> class Cls2; end
>
> def Cls.somemethod
> "defined in Cls"
> end
>
> Cls.somemethod #=> "defined in Cls"
>
> module Mod
> def somemethod
> "defined in Mod"
> end
> end
>
> Cls.extend Mod
> Cls2.extend Mod
>
> Cls.somemethod #=> "defined in Cls"
> Cls2.somemethod #=> "defined in Mod"
>
> Why doesn't Cls.somemethod gets overrided ?
>
> --
> Cheers,
> zimbatm
>
> http://zimbatm.oree.ch
>
Modules are inserted into the inheritance chain. So if you do
something like:
class A
def x
"x"
end
end
module X
def x
"y"
end
end
class A
include X
end
a = A.new
a.x (Look for #x in my singleton class, can't find it? Ok, look for
it in A, aha! found it! return "x")
class B
include X
end
b = B.new
b.x (Look for #x in my singleton class, can't find it? Ok, look for
it in B, can't find it? Ok, look for it in X, aha! found it return "y")
As you can see, it doesn't really have anything to do with the fact
that it's a singleton class, it's just how modules work.
The reason why using #extend can override something declared in an
objects class is because the singleton class is earlier in the
inheritance chain than the actual class of the object. extend
includes the module into the singleton class which puts it earlier
than the object's real class.
Well I have some legacy class methods that I want to extend. Therefor,
I'd like to use `super` in my extension module and not vice-versa.
···
On 29/06/06, transfire@gmail.com <transfire@gmail.com> wrote:
Jonas Pfenniger wrote:
> Last question : do you know if there is a workaround to make class
> extension work like class inclusion ? Where the module is BEFORE the
> eigenclass ?
Not possible. And I'm not sure why you want to do that? You can get a
module in BEFORE it class by including it into the object's singleton.
On 29/06/06, transfire@gmail.com <transfire@gmail.com> wrote:
> Jonas Pfenniger wrote:
> > Last question : do you know if there is a workaround to make class
> > extension work like class inclusion ? Where the module is BEFORE the
> > eigenclass ?
>
> Not possible. And I'm not sure why you want to do that? You can get a
> module in BEFORE it class by including it into the object's singleton.
Well I have some legacy class methods that I want to extend. Therefor,
I'd like to use `super` in my extension module and not vice-versa.
trans was asking, if you wanted to use "super" why not just subclass them? Really, sometimes inheritance really is the solution.
That said, the usual way to wrap a method like that is:
class LegacyClass
alias original_version_of_some_method some_method
def some_method
...
original_version_of_some_method(...) # effectively 'super'
end
end
···
On Jun 29, 2006, at 12:13 PM, Jonas Pfenniger wrote:
On 29/06/06, transfire@gmail.com <transfire@gmail.com> wrote:
subclass the legacy classes (?)
No, change the classes themselves trough module inclusion.
trans was asking, if you wanted to use "super" why not just subclass
them? Really, sometimes inheritance really is the solution.
Ah sorry I didn't understood it that way. This is not possible in my
situation. I'm using Camping. And Camping does funky stuff. It defines
a bunch of modules with class methods, etc.. trough evaling it's own
code. If you want to run a Camping app, you have to use the evaled
code.
That said, the usual way to wrap a method like that is:
class LegacyClass
alias original_version_of_some_method some_method
def some_method
...
original_version_of_some_method(...) # effectively 'super'
end
end
Hmm that seems to be feasible.
I've just had a devil idea
class Cls4; end
class << Cls4
def somemethod; "legacy"
end
mod = Module.new
mod.module_eval do
define_method :somemethod, &Cls4.method(:somemethod).to_proc
end
Cls4.extend mod
class << Cls4
def somemethod; super + " redefined !"; end
end
Cls4.somemethod #=> "legacy redefined !"
Thanks everybody
···
On 29/06/06, Logan Capaldo <logancapaldo@gmail.com> wrote: