[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Simple metaclass question

bob zee

10/9/2007 7:47:00 PM

Code 1:
-------
module Mod
def hello
"Hello from Mod.\n"
end
end
class Klass
def hello
"Hello from Klass.\n"
end
end

k = Klass.new
p k.hello #=> "Hello from Klass.\n"
k.extend(Mod)
p k.hello #=> "Hello from Mod.\n"

Code 2:
--------
module Mod
def hello
"Hello from Mod.\n"
end
end
class Klass
include Mod
def hello
"Hello from Klass.\n"
end
end
k = Klass.new
p k.hello #=> "Hello from Klass.\n"
k.extend(Mod)
p k.hello #=> "Hello from Klass.\n"

Why last k.hello is "Hello from Klass" Not "Hello from Mod"? After
Klass mixin with Mod, I am extending k object to include Mod so k's
metaclass methods now point to Mod methods.. right? they should get
called first before Klass instance methods if I am thinking right.
--
Posted via http://www.ruby-....

5 Answers

Giles Bowkett

10/9/2007 8:11:00 PM

0

IIRC, the reason it doesn't work the way you expected is that adding a
mixin gives you a new point on a tree. Ruby searches the tree for
methods. If you tell it to go to the method hello, it finds that right
away, right there in the class, so it never bothers to check further
up the tree. It looks first in the class, and then in the module.

--
Giles Bowkett

Blog: http://gilesbowkett.bl...
Portfolio: http://www.gilesg...
Tumblelog: http://giles.t...

Giles Bowkett

10/9/2007 8:17:00 PM

0

To get what you want, you have to do this:

module Mod
def self.included(base)
base.class_eval do
def hello
"module"
end
end
end
end

class Klass
def hello
"klass"
end
include Mod
end

include triggers the self.included, which then triggers a class_eval
within Klass, which redfines the method.

--
Giles Bowkett

Blog: http://gilesbowkett.bl...
Portfolio: http://www.gilesg...
Tumblelog: http://giles.t...

MenTaLguY

10/9/2007 8:28:00 PM

0

On Wed, 10 Oct 2007 04:46:37 +0900, bob zee <nlakkakula@gmail.com> wrote:
> Why last k.hello is "Hello from Klass" Not "Hello from Mod"? After
> Klass mixin with Mod, I am extending k object to include Mod so k's
> metaclass methods now point to Mod methods.. right? they should get
> called first before Klass instance methods if I am thinking right.

Ruby inheritance is linearized so that each module only appears once.
Since Mod is already present in k's class ancestry, adding it again
has no effect.

-mental


Rick DeNatale

10/9/2007 9:00:00 PM

0

On 10/9/07, MenTaLguY <mental@rydia.net> wrote:
> On Wed, 10 Oct 2007 04:46:37 +0900, bob zee <nlakkakula@gmail.com> wrote:
> > Why last k.hello is "Hello from Klass" Not "Hello from Mod"? After
> > Klass mixin with Mod, I am extending k object to include Mod so k's
> > metaclass methods now point to Mod methods.. right? they should get
> > called first before Klass instance methods if I am thinking right.
>
> Ruby inheritance is linearized so that each module only appears once.
> Since Mod is already present in k's class ancestry, adding it again
> has no effect.

For a while, about a year ago, Ruby 1.9 had changed the semantics of
re-inclusion:
http://talklikeaduck.denh...articles/2006/10/09/a-subtle-change-to-mixin-semantics-i...

But as far as I know it's now back to the 1.8 definition.

I still don't understand why since it seems unnatural to me.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

bob zee

10/10/2007 3:49:00 AM

0

Giles Bowkett wrote:
> IIRC, the reason it doesn't work the way you expected is that adding a
> mixin gives you a new point on a tree. Ruby searches the tree for
> methods. If you tell it to go to the method hello, it finds that right
> away, right there in the class, so it never bothers to check further
> up the tree. It looks first in the class, and then in the module.
>
> --
> Giles Bowkett
>
> Blog: http://gilesbowkett.bl...
> Portfolio: http://www.gilesg...
> Tumblelog: http://giles.t...

Giles ...I think Search path is like this Singleton Object then any
modules mixin by singleton object then the Class then Mixed Modules
then Super classes. But as I am mixin same Module for singleton object
which is mixin by Class already, it is skipping it as Rick and mental
points out.
--
Posted via http://www.ruby-....