Eigenclass not extensible?

… 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

IMO because Cls is already having its particular singleton class (when
you defined the somemethod). (but I may be completely wrong).

./alex

.w( the_mindstorm )p.

(http://themindstorms.blogspot.com)

Jonas P. wrote:

Cls.somemethod #=> “defined in Cls”
Cls2.somemethod #=> “defined in Mod”

Why doesn’t Cls.somemethod gets overrided ?

B/c of what #extend actually does. It is the same as:

class << Cls
include Mod
end

Try this:

def Cls.somemethod
super + “defined in Cls”
end

T.

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.

./alex

.w( the_mindstorm )p.

(http://themindstorms.blogspot.com)

On Jun 28, 2006, at 1:13 PM, Jonas P. wrote:

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.

Jonas P. 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.

T.

Effectively :

module Mod
def somemethod
“defined in Mod”
end
end

class Cls3
def self.somemethod
super + " and in Cls3"
end
end

Cls3.somemethod #=> NoMethodError: super: no superclass method
`somemethod’

Cls3.extend Mod

Cls3.somemethod #=> “defined in Mod and in Cls3”

But…

Cls3.ancestors #=> [Cls3, Object, Kernel]
class << Cls3
ancestors
end #=> [Mod, Class, Module, Object, Kernel]

So in theory, the eigenclass is effectively BEFORE anything else but
in doesn’t show up in the ancestors.

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 ?


Cheers,
zimbatm

http://zimbatm.oree.ch

On 29/06/06, [email protected] [email protected] wrote:

Jonas P. 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.


Cheers,
zimbatm

http://zimbatm.oree.ch

Jonas P. wrote:

I’d like to use super in my extension module and not vice-versa.
subclass the legacy classes (?)

T.

On 29/06/06, [email protected] [email protected] wrote:

subclass the legacy classes (?)

No, change the classes themselves trough module inclusion.


Cheers,
zimbatm

http://zimbatm.oree.ch

On Jun 29, 2006, at 12:13 PM, Jonas P. wrote:

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 29/06/06, Logan C. [email protected] wrote:

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 :smiley:

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 :slight_smile:


Cheers,
zimbatm

http://zimbatm.oree.ch

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs