国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Ruby - Ruby常量查找路徑問題深入研究

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

2020-04-24 10:46腳本之家 Ruby

這篇文章主要介紹了Ruby常量查找路徑問題深入研究,本文給出了多個例子來探討Ruby的常量查找路徑,并給出了總結(jié)結(jié)論,需要的朋友可以參考下

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

第一個遇到的問題,我還曾經(jīng)在 Ruby-China 上發(fā)過帖。

復制代碼 代碼如下:


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

 

輸出結(jié)果是

 

復制代碼 代碼如下:

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

 

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

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

復制代碼 代碼如下:

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

 

執(zhí)行結(jié)果是:

復制代碼 代碼如下:

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

 

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

復制代碼 代碼如下:


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 常量查找時依據(jù)兩條路徑

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

A 比 B 優(yōu)先,A 找不到了才到 B 中查找。

A.Module.nesting 的概念比較容易理解,它是指代碼位置的 module 嵌套情況,它是一個數(shù)組,從最內(nèi)層的嵌套一直到最外層的嵌套,如果沒有嵌套,數(shù)組為空。任何一處代碼位置都有 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 存在,在模塊和類定義處,它通常就是對應的模塊和類,在方法內(nèi)部,它是方法對應的類。對于 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]。

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

延伸 · 閱讀

精彩推薦
  • RubyRuby設計模式編程中使用Builder建造者模式的實例

    Ruby設計模式編程中使用Builder建造者模式的實例

    這篇文章主要介紹了Ruby設計模式編程中使用Builder建造者模式的實例,建造者模式將一個復雜對象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過程可以創(chuàng)建不同的表...

    范孝鵬2192020-05-07
  • RubyRuby迭代器的7種技巧分享

    Ruby迭代器的7種技巧分享

    這篇文章主要介紹了Ruby迭代器的7種技巧分享,Ruby中的迭代器非常人性化,本文既是講解了7個技巧也是講解了7種迭代器,需要的朋友可以參考下 ...

    腳本之家4782020-04-20
  • RubyCentOS中配置Ruby on Rails環(huán)境

    CentOS中配置Ruby on Rails環(huán)境

    經(jīng)過一個上午的折騰,終于把ROR環(huán)境在CentOS中搞定,繞了很多彎路,把文章寫下來總結(jié)一下 ...

    可樂加糖4762020-04-12
  • RubyRuby進行文件信息輸出實例代碼

    Ruby進行文件信息輸出實例代碼

    Ruby進行文件信息輸出實例代碼,數(shù)據(jù)是隨機的,所以每次的記錄都會不同。 ...

    ruby教程網(wǎng)2962020-04-10
  • RubyRuby簡潔學習筆記(一):字符串、數(shù)字、類和對象

    Ruby簡潔學習筆記(一):字符串、數(shù)字、類和對象

    這篇文章主要介紹了Ruby簡潔學習筆記(一):字符串、數(shù)字、類和對象,本文是學習筆記第一篇,需要的朋友可以參考下 ...

    腳本之家2472020-04-20
  • RubyRuby環(huán)境下安裝使用bundler來管理多版本的gem

    Ruby環(huán)境下安裝使用bundler來管理多版本的gem

    這篇文章主要介紹了Ruby環(huán)境下安裝使用bundler來管理多版本的gem的方法,舉了Ruby On Rails中的應用實例來進行演示,需要的朋友可以參考下 ...

    日拱一卒4332020-05-10
  • Ruby簡要說明Ruby中的迭代器

    簡要說明Ruby中的迭代器

    這篇文章主要介紹了Ruby中的迭代器,迭代器的概念在動態(tài)語言的編程中十分重要,文章中介紹了Ruby中的each迭代器和collect迭代器,需要的朋友可以參考下 ...

    goldensun2772020-04-25
  • Ruby剖析 Ruby 訪問控制

    剖析 Ruby 訪問控制

    前面,我們說 Ruby 沒有函數(shù),只有方法.而且實際上有不止一種方法.這一節(jié)我們介紹 訪問控制 (accesscontrols). 想想當我們在最高層而不是在一個類的定義里定義...

    ruby教程網(wǎng)3572020-04-08
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 精品国产乱码久久久久久久 | 欧美日韩在线电影 | 国产福利电影 | 在线a视频网站 | 免费视频爱爱太爽了 | 久久久天堂国产精品女人 | 久久综合九色 | 一区二区三区四区在线播放 | 狠狠的日 | 免费看黄在线网站 | 高清hd写真福利在线播放 | 精品国产一区二区三区四区 | 国产色秀视频在线观看 | 风间由美一区二区 | 久久国产精品久久久久久久久久 | 色婷婷欧美 | 午夜视频在线观看网站 | 午夜精品福利一区二区三区蜜桃 | 久久伊人成人网 | 黄色av电影 | 操操操干干 | 国产精品视屏 | 欧美精品在线一区二区三区 | 中文精品在线 | 欧美亚洲激情 | 久综合网 | 中文字幕在线观看 | 日本一区二区免费在线播放 | 亚洲在线影院 | 欧美性一区二区三区 | 亚洲欧美一区二区三区久久 | 国精产品99永久一区一区 | 日韩成人av在线 | 国产免费一区二区三区 | 欧美视频免费在线 | 亚洲热视频在线观看 | 国产一区二区三区免费观看 | 精品国产乱码一区二区三区 | 免费三级黄色片 | 久久久无码精品亚洲日韩按摩 | 韩国成人精品a∨在线观看 欧美精品综合 |