module M1
class A
def fun
puts "module M1 class A method fun()"
end
end
end
module M2
class A
def fun
puts "module M2 class A method fun()"
end
end
end
class MyClass
include M1
include M2
end
obj1 = MyClass::M1::A.new
puts obj1.class
puts obj1.object_id
obj1.fun
obj2 = MyClass::M2::A.new
puts obj2.class
puts obj2.object_id
obj2.fun
输出为
r20.rb:22: warning: toplevel constant M1 referenced by MyClass::M1
M1::A
13996360
module M1 class A method fun()
r20.rb:27: warning: toplevel constant M2 referenced by MyClass::M2
M2::A
13996120
module M2 class A method fun()
我不明白为什么会出现此警告消息。请解释一下。如果有这种必要性,以这种方式进行嵌套是否不好?
还有一个问题是,当我在两个对象(即Obj1和Obj2)上调用超类方法时,不会出现方法错误,不知道为什么,我的意思是毕竟它们也是对象,为什么它们没有超对象的所有对象有。
实际上,ruby会打印出足够多的消息以供理解,这是怎么回事。
首先,这是重新编写代码以不产生警告的方式:
- obj1 = MyClass::M1::A.new
+ obj1 = M1::A.new
这可能不是您想要的,但这是您指示ruby要做的。
这很简单。模块和类名是ruby中的常量。经过
include M1
你几乎行内(不完全,但不同的是出于对这个问题的范围)内容的M1
插入MyClass
。
M1
内联的内容之后,可以通过以下方式引用它
MyClass::M1
可是等等!M1
常量已经在Object
(顶层)上定义。默认情况下,MyClass
它是从Object
ruby中其他任何用户生成的类派生的。尝试引用常量(Object::M1
因为它属于MyClass
名称空间)会产生警告。
该MyClass::M1::A
实际上是不正确的,但工作代名词M1::A
。MyClass::A
被重新定义由第二include
。那么你:
M1::A
并且M2::A
都与之无关MyClass
;MyClass
命名空间的类M1::A
和M2::A
;MyClass::A
类,其fun
功能来自M2
,因为MyClass::A
该类是打开的(请参见“ ruby中打开的类”),并且MyClass::A#fun
定义由第二个include语句进行了猴子修补。由于include
实际上是内联内容,因此这是您可以实现可能想要实现的行为的方式:
module MM
module M1
class A
def fun ; puts "module M1 class A method fun()" ; end
end
end
module M2
class A
def fun ; puts "module M2 class A method fun()" ; end
end
end
end
class MyClass
include MM
end
obj1 = MyClass::M1::A.new
puts obj1.class
puts obj1.object_id
obj1.fun
obj2 = MyClass::M2::A.new
puts obj2.class
puts obj2.object_id
obj2.fun
#⇒ MM::M1::A
#⇒ 100355060
#⇒ module M1 class A method fun()
#⇒ MM::M2::A
#⇒ 100354990
#⇒ module M2 class A method fun()
希望能帮助到你。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句