Mysterious behavior of mixins

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?

On Aug 29, 1:26 pm, i3dmaster [email protected] wrote:

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):022:0> class D
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.

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

On Aug 29, 11:17 am, Trans [email protected] wrote:

irb(main):154:2> end
irb(main):162:1> end
irb(main):164:0> B.new.showself
irb(main):172:1> include A
irb(main):024:1> end
Does mixins allow mixin class methods or not? If not, what’s the
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.

On Aug 29, 11:25 am, “Thomas B.” [email protected] wrote:

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)

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