亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Ruby > 正文

Ruby常量查找路徑問題深入研究

2020-10-29 19:41:57
字體:
來源:轉載
供稿:網友

Ruby 的常量查找路徑問題是一直困擾我的一個問題,在工作中遇到過好幾次,一直沒有徹底弄清楚到底為什么,最近在讀一本書《Ruby 元編程》,對 Ruby 對象模型有了更深入的認識,另外讀了一篇 blog《Everything you ever wanted to know about constant lookup in Ruby》, 讓我總算把 Ruby 常量查找路徑這個問題搞得比較清楚。

第一個遇到的問題,我還曾經在 Ruby-China 上發過帖。

復制代碼 代碼如下:

module M1
  CT = "ok"
end

class C1
  CK = "ck"
  include M1

  def self.method1
    puts self
    puts "#{CK} in method1"
    puts "#{CT} in method1"
  end

  class << self
    def method2
      puts self
      puts "#{CK} in method1"
      puts "#{CT} in method2"
    end
  end
end

C1.method1
C1.method2

輸出結果是

復制代碼 代碼如下:

C1
ck in method1
ok in method1
C1
ck in method2
NameError: uninitialized constant Class::CT
    from (irb):16:in `method2'

這是我在重構薄荷網代碼時候遇到的問題,method1 和 method2 都是常見的類方法的定義方面,我向來認為它們是等價可替換的寫法,但是從實際執行的結果看,它們里面的常量查找路徑不一樣。

如果我把 M1 的定義改成下面的樣子:

復制代碼 代碼如下:

module M1
  def self.included(base)
    base.extend(self)
  end
  CT = "ok"
end

執行結果是:

復制代碼 代碼如下:

C1
ck in method1
ok in method1
C1
ck in method2
ok in method2

還有一個問題是也是經常遇到的,抽象成問題代碼如下:

復制代碼 代碼如下:

module A
  module M
    def a_method
      #...
    end
  end
end

class A::B
  include M
end

會報異常:

復制代碼 代碼如下:

NameError: uninitialized constant A::B::M
  from (irb):10:in `<class:B>'

Ruby 常量查找時依據兩條路徑

A. Module.nesting
B. open class/module 的 ancestors

A 比 B 優先,A 找不到了才到 B 中查找。

A.Module.nesting 的概念比較容易理解,它是指代碼位置的 module 嵌套情況,它是一個數組,從最內層的嵌套一直到最外層的嵌套,如果沒有嵌套,數組為空。任何一處代碼位置都有 Module.nesting 值,可以通過下面的代碼打印出各個位置的 Module.nesting 值。

復制代碼 代碼如下:

p Module.nesting

module A
  module B
    p Module.nesting
    module C
      p Module.nesting
    end
  end
end

module A::B
  p Module.nesting
end

輸出是:

復制代碼 代碼如下:

[]
[A::B, A]
[A::B::C, A::B, A]
[A::B]

大家有沒有注意到,module A::B 這種快捷寫法會導致 A 不在 Module.nesting 里,這就是上述第二個問題的根源,因為 M 是 A module 下的常量,module A::B 寫法導致不會查找 A::M。

說完 A Module.nesting,再說一下 B open class/module 的 ancestors,這個問題相對復雜很多。簡單的說,在 Ruby 代碼的任何位置,都有一個 self 存在,同樣也有一個 open class/module 存在,在模塊和類定義處,它通常就是對應的模塊和類,在方法內部,它是方法對應的類。對于 ancestors,我們可以通過代碼位置 open class/module 的 ancestors 方法取得。

(備注:ancestors 在引入 singleton_class 概念之后變得有點復雜,如不清楚可參考《Ruby 元編程》)

上述第一個問題: 在method1 中 A 是 [C1] open class/module 是 C1,所以 ancestors 是 [C1, M1, Object, Kernel, BasicObject] CK 在 A 可以找到,CT 在 B 可以找到。

method2 中 A 是 [C1] open class/module 是 C1 的 singleton_class , 所以 ancestors 是 [Class, Module, Object, Kernel, BasicObject] CK 在 A 可以找到,CT 在 A 和 B 都找不到。

對于

復制代碼 代碼如下:

module M1
  def self.included(base)
    base.extend(self)
  end
  CT = "ok"
end

可運行,是因為這時,在 method2 中,open class/module C1 的 singleton_class 擴展了 M1,所以 ancestors 變成了 [M1, Class, Module, Object, Kernel, BasicObject]。

至此,這兩個困擾我多時的問題終于徹底搞清楚了。這個過程給我的一個體會是:面對技術上的一些疑問,如果只是淺嘗輒止,是永遠不能夠真正掌握它的,只有深入專研,透徹理解它的原理,才能夠真正掌握它,獲得真正的能力提升。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品一区二区三区成人| 亚洲国产精品一区二区久| 日韩在线资源网| 91精品国产91久久久久久最新| 色综合天天综合网国产成人网| 日韩av网址在线观看| 亚洲人线精品午夜| 国产精品成人久久久久| 国产免费一区二区三区在线能观看| 成人激情视频小说免费下载| 黑人巨大精品欧美一区二区一视频| 国产日韩精品在线| 国产又爽又黄的激情精品视频| 日韩欧美中文字幕在线播放| 国产一区二区三区视频在线观看| 国产在线视频不卡| 国产91久久婷婷一区二区| 91久久精品美女| 黑人巨大精品欧美一区二区| 国产精品美女在线| 日日骚久久av| 欧美国产日韩一区二区三区| 欧美午夜精品久久久久久人妖| 久久大大胆人体| 高潮白浆女日韩av免费看| 国产亚洲精品久久久久久| 久久好看免费视频| 亚洲自拍偷拍色图| 久久777国产线看观看精品| 91精品国产综合久久香蕉的用户体验| 成人国产精品久久久久久亚洲| 亚洲人成网在线播放| 亚洲最大福利视频网| 91在线直播亚洲| 欧美国产在线视频| 久久精品国产96久久久香蕉| 国产成人精品日本亚洲专区61| 国产欧美日韩最新| 日韩视频欧美视频| 黑人狂躁日本妞一区二区三区| 欧美大成色www永久网站婷| 日韩av在线一区二区| 日韩国产一区三区| 中文字幕不卡av| 亚洲精品视频免费在线观看| 欧美精品一本久久男人的天堂| 插插插亚洲综合网| 国产福利精品在线| 九九九热精品免费视频观看网站| 亚洲影院在线看| 欧美精品免费播放| 成人写真福利网| 久久精品国产综合| 性欧美在线看片a免费观看| 国产日本欧美一区| 91深夜福利视频| 亚洲精品国产精品自产a区红杏吧| 亚洲国产精品久久久久久| 91av在线免费观看| 欧美在线视频一二三| 91久久久久久久久久久久久| 日韩av电影在线播放| 全球成人中文在线| 亚洲男人天堂手机在线| 欧美一区二区三区四区在线| 久久久免费观看视频| 麻豆成人在线看| 色av吧综合网| 国产丝袜精品第一页| 日韩高清电影免费观看完整版| 国产一区二区欧美日韩| 97视频在线观看免费高清完整版在线观看| 91在线观看免费观看| 国产成人精品视频在线| 久久久精品免费视频| 国产精品国产三级国产专播精品人| 欧美日韩成人免费| 国产色综合天天综合网| 中文在线资源观看视频网站免费不卡| 国产精品扒开腿做| 久久久精品2019中文字幕神马| 欧美日韩成人免费| 成人xvideos免费视频| 欧美电影免费观看电视剧大全| 91在线色戒在线| 国产精品电影在线观看| 国产成人精品久久亚洲高清不卡| 午夜精品视频网站| 久久精品国产一区二区三区| 欧美日韩视频免费播放| 久久久久久香蕉网| 中文字幕九色91在线| 怡红院精品视频| 日韩欧美中文字幕在线观看| 欧美国产日产韩国视频| 久久成人精品电影| 色多多国产成人永久免费网站| 国产精品丝袜一区二区三区| 97av在线影院| 国产精品白丝av嫩草影院| 日韩网站免费观看高清| 国产精品白丝av嫩草影院| 91av在线国产| 欧美xxxx做受欧美.88| 国产精品视频一区二区高潮| 久久av红桃一区二区小说| 91香蕉嫩草神马影院在线观看| 久久人人爽人人爽人人片亚洲| 日韩欧美在线免费观看| 国产精品一区二区三区免费视频| 国产精品久久中文| 在线亚洲国产精品网| 日韩禁在线播放| 亚洲天堂2020| 成人av在线天堂| 日本精品视频网站| 欧美夜福利tv在线| 国产精品视频内| 69av在线视频| 亚洲美女在线观看| 国产精品久久久久久久午夜| 午夜免费在线观看精品视频| 欧美另类暴力丝袜| 亚洲成**性毛茸茸| 欧美激情网友自拍| 69av成年福利视频| 欧美在线亚洲一区| 亚洲欧美日韩一区在线| 亚洲香蕉成人av网站在线观看| 国产精品大陆在线观看| 亚洲欧美国产精品va在线观看| 日韩一区二区三区国产| 国产日韩av在线播放| 日本不卡免费高清视频| 久久久久久久电影一区| 亚洲精品免费一区二区三区| 亚洲精品在线看| 欧美精品久久久久a| 日韩av免费在线观看| 国产z一区二区三区| 97在线精品国自产拍中文| 亚洲精品美女在线观看| 九九久久久久久久久激情| 亚洲一区二区三区视频播放| 日韩一级裸体免费视频| 欧美韩国理论所午夜片917电影| 懂色av影视一区二区三区| 欧美黄色片在线观看| 欧美在线一区二区视频| 国产精品白嫩初高中害羞小美女| 国产成人精品免高潮在线观看| 亚洲一区免费网站| 国产成人精品久久二区二区91| 欧美日韩成人免费| 国产色视频一区| 久久精品久久久久电影| 欧美资源在线观看| 国产精品午夜国产小视频| 国内精品小视频在线观看| 国产精品www网站| 亚洲第一福利网| 在线成人激情黄色| 欧美在线观看网址综合| 麻豆国产va免费精品高清在线|