[英]Ruby - including single module multiple times and ancestry hierarchy
我现在正在阅读“元编程 Ruby”并同时编写一些代码来阐明概念。 我已经读过,当您多次包含/添加单个模块时,所有进一步的包含都不会改变所述模块在祖先链中的位置。
我编写了一些以我没想到的方式工作的代码 - 那里实际发生了什么?
module GreatGrandfather; end
module Grandfather
include GreatGrandfather
end
module Father
include Grandfather
prepend GreatGrandfather
end
module Son
include Father
end
Son.ancestors # => [Son, Father, Grandfather, GreatGrandfather]
我假设当我运行Son.ancestors
,Son 将包括父亲,父亲将包括祖父并在 GreatGrandfather 前面加上祖先树,并且祖先树将设置为[Son, GreatGrandfather, Father, Grandfather]
。 显然这并没有发生。
一旦 Son 包含了Father,它就会开始在Father 模块中查找并找到include Grandfather
并在prepend GratGrandfather
。 其实是否“进入” Grandfather
那里包括曾祖父,然后才执行prepend GreatGrandfather
线(因为它已经在祖先存在可以忽略它)?
说实话,我怀疑我会从中得到多少用处,但知道这些模块如何确切地“链接”在一起并没有什么坏处。
@edit - 我已经玩过更多了,似乎我的直觉在任何一种情况下都不正确。 我已经包含了我认为可以采用的两种方式的图片,一个接一个的指令,关于创建继承层次结构 - 图片中出现的那个与给出的原始示例背道而驰,所以 #1 或 #2 都不能正在发生。
修改示例代码(仅曾祖父更改)
module GreatGrandfather
include Grandfather
end
module Grandfather
include GreatGrandfather
end
module Father
prepend GreatGrandfather
include Grandfather
end
module Son
include Father
end
Son.ancestors # => Son, GreatGrandfather, Father, Grandfather
总而言之 - 我仍然不知道它是如何发生的
如果此模块尚未添加到 mod 或其祖先之一,Ruby 的默认实现是将此模块的常量、方法和模块变量覆盖到 mod。
但是您已经通过祖父将曾祖父添加到父亲。
这样它就会像你期望的那样工作:
module GreatGrandfather; end
module Grandfather
include GreatGrandfather
end
module Father
prepend GreatGrandfather
include Grandfather
end
module Son
include Father
end
p Son.ancestors # => [Son, GreatGrandfather, Father, Grandfather]
更新
1.您不能像这样修改示例:
module GreatGrandfather
include Grandfather
end
module Grandfather
include GreatGrandfather
end
原因当您定义 GreatGrandfather 时,Grandfather 未定义。
2.This is, 当你将模块添加到另一个模块时会发生什么。 注释说明了模块层次结构在时间上会发生什么:
module GreatGrandfather
# GG
end
module Grandfather
# GG
# G
include GreatGrandfather
# GG
# G -> GG
end
module Father
# GG
# G -> GG
# F
prepend GreatGrandfather
# GG
# G -> GG
# GG -> F
include Grandfather
# Don't change the position of GG in Father hierarchy, cause it is already in ancestors
# GG
# G -> GG
# GG -> F -> G
end
module Son
# GG
# G -> GG
# GG -> F -> G
# S
include Father
# GG
# G -> GG
# GG -> F -> G
# S -> GG -> F -> G
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.