簡體   English   中英

Ruby - 多次包含單個模塊和祖先層次結構

[英]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

在此處輸入圖片說明

總而言之 - 我仍然不知道它是如何發生的

模塊#prepend_feature

如果此模塊尚未添加到 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM