[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

mysterious behavior of mixins

i3dmaster

8/29/2008 5:30:00 PM

I am trying to learn how mixins are behaved and encountered a strange
behavior and got me even confused...

irb(main):151:0> module A
irb(main):152:1> def self.showself
irb(main):153:2> puts "self is #{self.inspect}"
irb(main):154:2> end
irb(main):155:1> def showself
irb(main):156:2> puts "self is #{self.inspect}"
irb(main):157:2> end
irb(main):158:1> end
=> nil
irb(main):159:0> A.showself
self is A
=> nil
irb(main):160:0> class B
irb(main):161:1> include A
irb(main):162:1> end
=> B
irb(main):163:0> B.showself
self is B
=> nil
irb(main):164:0> B.new.showself
self is #<B:0x4ce78>
=> nil
irb(main):165:0> class C
irb(main):166:1> def self.showself
irb(main):167:2> puts "in C's showself"
irb(main):168:2> end
irb(main):169:1>
irb(main):170:1* end
=> nil
irb(main):171:0> class B < C
irb(main):172:1> include A
irb(main):173:1> end
TypeError: superclass mismatch for class B
from (irb):171
from :0

Then I tried another several times and it always throws out TypeError,
then I tried this:

irb(main):022:0> class D
irb(main):023:1> include A
irb(main):024:1> end
=> D
irb(main):025:0> D.showself
NoMethodError: undefined method `showself' for D:Class
from (irb):25
from :0
irb(main):026:0> ^C
irb(main):026:0> quit

I was able to minxin A's class method (using class B) just a moment
ago. What the heck is going on? Questions:
Does mixins allow mixin class methods or not? If not, what's the
common idiom to mixin class methods?
Is there a concept of protected or private mixins? I see mixins be
able to just mixed in with arbitrary classes. Is there possible to
force some certian mixins only be able to be mixed in with a certain
classes or other modules?
4 Answers

Trans

8/29/2008 6:17:00 PM

0



On Aug 29, 1:26=A0pm, i3dmaster <i3dmas...@gmail.com> wrote:
> I am trying to learn how mixins are behaved and encountered a strange
> behavior and got me even confused...
>
> irb(main):151:0> module A
> irb(main):152:1> =A0 def self.showself
> irb(main):153:2> =A0 =A0 puts "self is #{self.inspect}"
> irb(main):154:2> =A0 end
> irb(main):155:1> =A0 def showself
> irb(main):156:2> =A0 =A0 puts "self is #{self.inspect}"
> irb(main):157:2> =A0 end
> irb(main):158:1> end
> =3D> nil
> irb(main):159:0> A.showself
> self is A
> =3D> nil
> irb(main):160:0> class B
> irb(main):161:1> =A0 include A
> irb(main):162:1> end
> =3D> B
> irb(main):163:0> B.showself
> self is B

Are you sure about this? Ruby doesn't do that. (Which I've never been
completely happy about, but that's another story...)

> =3D> nil
> irb(main):164:0> B.new.showself
> self is #<B:0x4ce78>
> =3D> nil
> irb(main):165:0> class C
> irb(main):166:1> =A0 def self.showself
> irb(main):167:2> =A0 =A0 puts "in C's showself"
> irb(main):168:2> =A0 end
> irb(main):169:1>
> irb(main):170:1* end
> =3D> nil
> irb(main):171:0> class B < C
> irb(main):172:1> =A0 include A
> irb(main):173:1> end
> TypeError: superclass mismatch for class B
> =A0 =A0 =A0 =A0 from (irb):171
> =A0 =A0 =A0 =A0 from :0
>
> Then I tried another several times and it always throws out TypeError,
> then I tried this:
>
> irb(main):022:0> class D
> irb(main):023:1> =A0 include A
> irb(main):024:1> end
> =3D> D
> irb(main):025:0> D.showself
> NoMethodError: undefined method `showself' for D:Class
> =A0 =A0 =A0 =A0 from (irb):25
> =A0 =A0 =A0 =A0 from :0
> irb(main):026:0> ^C
> irb(main):026:0> quit
>
> I was able to minxin A's class method (using class B) just a moment
> ago. What the heck is going on? Questions:
> Does mixins allow mixin class methods or not? If not, what's the
> common idiom to mixin class methods?
> Is there a concept of protected or private mixins? I see mixins be
> able to just mixed in with arbitrary classes. Is there possible to
> force some certian mixins only be able to be mixed in with a certain
> classes or other modules?

Look into Module#included and Module#append_features. Eg.

module X
def self.included(base)
base.extend MetaX
end

module MetaX
# class method here
end

extend MetaX
end

T.

TPReal

8/29/2008 6:26:00 PM

0

Jim Xu wrote:
> irb(main):171:0> class B < C
> irb(main):172:1> include A
> irb(main):173:1> end
> TypeError: superclass mismatch for class B
> from (irb):171
> from :0

Of course you cannot do it, because a moment ago you declared the method
B as an immediate descendant of Object, and now you want it to be the
descendant of C. The error has nothing to do with mixins.

irb(main):046:0> class A;end
=> nil
irb(main):047:0> class B;end
=> nil
irb(main):048:0> class B<A;end
TypeError: superclass mismatch for class B
from (irb):48
--
Posted via http://www.ruby-....

i3dmaster

8/29/2008 8:03:00 PM

0

On Aug 29, 11:17 am, Trans <transf...@gmail.com> wrote:
> On Aug 29, 1:26 pm, i3dmaster <i3dmas...@gmail.com> wrote:
>
>
>
> > I am trying to learn how mixins are behaved and encountered a strange
> > behavior and got me even confused...
>
> > irb(main):151:0> module A
> > irb(main):152:1>   def self.showself
> > irb(main):153:2>     puts "self is #{self.inspect}"
> > irb(main):154:2>   end
> > irb(main):155:1>   def showself
> > irb(main):156:2>     puts "self is #{self.inspect}"
> > irb(main):157:2>   end
> > irb(main):158:1> end
> > => nil
> > irb(main):159:0> A.showself
> > self is A
> > => nil
> > irb(main):160:0> class B
> > irb(main):161:1>   include A
> > irb(main):162:1> end
> > => B
> > irb(main):163:0> B.showself
> > self is B
>
> Are you sure about this? Ruby doesn't do that. (Which I've never been
> completely happy about, but that's another story...)
>
>
>
> > => nil
> > irb(main):164:0> B.new.showself
> > self is #<B:0x4ce78>
> > => nil
> > irb(main):165:0> class C
> > irb(main):166:1>   def self.showself
> > irb(main):167:2>     puts "in C's showself"
> > irb(main):168:2>   end
> > irb(main):169:1>
> > irb(main):170:1* end
> > => nil
> > irb(main):171:0> class B < C
> > irb(main):172:1>   include A
> > irb(main):173:1> end
> > TypeError: superclass mismatch for class B
> >         from (irb):171
> >         from :0
>
> > Then I tried another several times and it always throws out TypeError,
> > then I tried this:
>
> > irb(main):022:0> class D
> > irb(main):023:1>   include A
> > irb(main):024:1> end
> > => D
> > irb(main):025:0> D.showself
> > NoMethodError: undefined method `showself' for D:Class
> >         from (irb):25
> >         from :0
> > irb(main):026:0> ^C
> > irb(main):026:0> quit
>
> > I was able to minxin A's class method (using class B) just a moment
> > ago. What the heck is going on? Questions:
> > Does mixins allow mixin class methods or not? If not, what's the
> > common idiom to mixin class methods?
> > Is there a concept of protected or private mixins? I see mixins be
> > able to just mixed in with arbitrary classes. Is there possible to
> > force some certian mixins only be able to be mixed in with a certain
> > classes or other modules?
>
> Look into Module#included and Module#append_features. Eg.
>
>   module X
>     def self.included(base)
>       base.extend MetaX
>     end
>
>     module MetaX
>       # class method here
>     end
>
>     extend MetaX
>   end
>
> T.

I know that's why I am quite confused about this. the ruby-doc really
didn't clearly say that class methods can't be mixed in.

"Ruby‘s default implementation is to add the constants, methods, and
module variables of this module to mod if this module has not already
been added to mod or one of its ancestors"

Is there an violation for mixing in class methods from module?
Conceptually, I can't think of one though.

i3dmaster

8/29/2008 8:17:00 PM

0

On Aug 29, 11:25 am, "Thomas B." <tpr...@gmail.com> wrote:
> Jim Xu wrote:
> > irb(main):171:0> class B < C
> > irb(main):172:1>   include A
> > irb(main):173:1> end
> > TypeError: superclass mismatch for class B
> >         from (irb):171
> >         from :0
>
> Of course you cannot do it, because a moment ago you declared the method
> B as an immediate descendant of Object, and now you want it to be the
> descendant of C. The error has nothing to do with mixins.
>
> irb(main):046:0> class A;end
> => nil
> irb(main):047:0> class B;end
> => nil
> irb(main):048:0> class B<A;end
> TypeError: superclass mismatch for class B
>         from (irb):48
> --
> Posted viahttp://www.ruby-....

Yes, my mistake. I am still trying to get comfortable that Ruby allows
extending existing classes in runtime... I always thought that when
defining a new class, it points the symbol to a new object instead of
opening up the existing object... (under the same scope of course)