mysterious behavior of mixins

Discussion in 'Ruby' started by i3dmaster, Aug 29, 2008.

  1. i3dmaster

    i3dmaster Guest

    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?
    i3dmaster, Aug 29, 2008
    #1
    1. Advertising

  2. i3dmaster

    Trans Guest

    On Aug 29, 1:26=A0pm, i3dmaster <> 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.
    Trans, Aug 29, 2008
    #2
    1. Advertising

  3. i3dmaster

    Thomas B. Guest

    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-forum.com/.
    Thomas B., Aug 29, 2008
    #3
  4. i3dmaster

    i3dmaster Guest

    On Aug 29, 11:17 am, Trans <> wrote:
    > On Aug 29, 1:26 pm, i3dmaster <> 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, Aug 29, 2008
    #4
  5. i3dmaster

    i3dmaster Guest

    On Aug 29, 11:25 am, "Thomas B." <> 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-forum.com/.


    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)
    i3dmaster, Aug 29, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Martin Maney

    Calling __init__ for all mixins

    Martin Maney, Aug 18, 2004, in forum: Python
    Replies:
    4
    Views:
    418
    Michael Hudson
    Aug 19, 2004
  2. Sean McIlroy

    mysterious buggy behavior

    Sean McIlroy, Jan 9, 2005, in forum: Python
    Replies:
    2
    Views:
    313
    Andrea Griffini
    Jan 9, 2005
  3. Joshua Spoerri

    mixins that don't down-call?

    Joshua Spoerri, Aug 10, 2005, in forum: Python
    Replies:
    0
    Views:
    279
    Joshua Spoerri
    Aug 10, 2005
  4. Tony Zuse

    mysterious overriding behavior

    Tony Zuse, Dec 13, 2006, in forum: Java
    Replies:
    17
    Views:
    555
    Mike Schilling
    Dec 15, 2006
  5. Replies:
    2
    Views:
    85
Loading...

Share This Page