簡(jiǎn)要解讀Ruby面向?qū)ο缶幊讨械淖饔糜?/h1>
更新時(shí)間:2016年05月19日 15:52:22 作者:日拱一卒
作用域在面向?qū)ο缶幊讨惺且粋€(gè)十分重要的概念,程序構(gòu)建時(shí)必須要理解清楚類(lèi)和方法以及對(duì)象的作用范圍,接下來(lái)就為大家簡(jiǎn)要解讀Ruby面向?qū)ο缶幊讨械淖饔糜?/div>
作用域
Ruby中不具備嵌套作用域(即在內(nèi)部作用域,可以看到外部作用域的)的特點(diǎn),它的作用域是截然分開(kāi)的,一旦進(jìn)入一個(gè)新的作用域,原先的綁定會(huì)被替換為一組新的綁定。
程序會(huì)在三個(gè)地方關(guān)閉前一個(gè)作用域,同時(shí)打開(kāi)一個(gè)新的作用域,它們是:
- 類(lèi)定義class
- 模塊定義 module
- 方法定義 def
上面三個(gè)關(guān)鍵字,每個(gè)關(guān)鍵字對(duì)應(yīng)一個(gè)作用域門(mén)(進(jìn)入),相應(yīng)的end則對(duì)應(yīng)離開(kāi)這道門(mén)。
扁平化作用域
從一個(gè)作用域進(jìn)入另一個(gè)作用域的時(shí)候,局部變量會(huì)立即失效,為了讓局部變量持續(xù)有效,可以通過(guò)規(guī)避關(guān)鍵字的方式,使用方法調(diào)用來(lái)代替作用域門(mén),讓一個(gè)作用域看到另一個(gè)作用域里的變量,從而達(dá)到目的。具體做法是,通過(guò)Class.new替代class,Module#define_method代替def,Module.new代替module。這種做法稱為扁平作用域,表示兩個(gè)作用域擠壓到一起。
示例代碼(Wrong)
my_var = “Success”
class MyClass
puts my_var #這里無(wú)法正確打印”Success”
def my_method
puts my_var #這里無(wú)法正確打印”Success”
end
end
示例代碼(Right)
my_var = “Success”
MyClass = Class.new do
puts “#{my_var} in the class definition”
define_method :my_method do
“#{my_var} in the method”
end
end
在一些語(yǔ)言中,比如java或C#,有內(nèi)部作用域(inner scope)的概念。在內(nèi)部作用域可以看到外部作用域(outer scope)中的變量。但ruby中沒(méi)有這種嵌套式作用域的概念,它的作用域是截然分開(kāi)的,一旦進(jìn)入一個(gè)新的作用域,原先的綁定就會(huì)被替代為一組新的綁定。
在ruby中,程序會(huì)在三個(gè)地方關(guān)閉前一個(gè)作用域,同時(shí)打開(kāi)一個(gè)新的作用域:類(lèi)定義、模塊定義、方法。
只要程序進(jìn)入類(lèi)、模塊或者方法的定義,就會(huì)發(fā)生作用域切換。這三個(gè)邊界分別用class,module和def關(guān)鍵字作為標(biāo)志,每一個(gè)關(guān)鍵字都充當(dāng)了一個(gè)作用域門(mén)(scope gate)。
怎樣讓綁定穿越一個(gè)作用域門(mén)呢?比如下面的代碼:
my_var = “hello”
class MyClass
#你希望在這里能打印my_var
def my_method
#...還有這里
end
end
在進(jìn)入另一個(gè)作用域時(shí),局部變量會(huì)立刻失效。如果把class關(guān)鍵字替換為某個(gè)非作用域門(mén)的東西,比如方法,就能在一個(gè)閉包中獲得my_var的值,并把這個(gè)閉包傳遞給該方法。代碼如下:
my_var = “hello”
MyClass = Class.new do
puts “#{my_var} in the class definition”
def my_method
#...這里怎樣打印出來(lái)呢?
end
end
用Module#define_method()方法可以替代def,代碼如下:
my_var = “hello”
MyClass = Class.new do
puts “#{my_var} in the class definition”
define_method :my_method do
puts “#{my_var} in the method”
end
end
MyClass.new.my_method
hello in the class definition
hello in the method
使用方法來(lái)替代作用域門(mén),可以讓一個(gè)作用域看到另一個(gè)作用域中的變量,這種技術(shù)可以稱之為“扁平作用域”。
共享作用域
將一組方法定義到,某個(gè)變量的扁平作用域中,可以保證變量?jī)H被有限的幾個(gè)方法所共享。這種方式稱為共享作用域。
相關(guān)文章
-
ruby迭代map的簡(jiǎn)潔寫(xiě)法實(shí)現(xiàn)原理分析
這篇文章主要介紹了ruby迭代map的簡(jiǎn)潔寫(xiě)法實(shí)現(xiàn)原理分析,本文著重對(duì)簡(jiǎn)潔寫(xiě)法的原理進(jìn)行解析,需要的朋友可以參考下 2014-11-11
-
Ruby中的public、private、protected區(qū)別小結(jié)
這篇文章主要介紹了Ruby中的public、private、protected區(qū)別小結(jié),即Ruby中訪問(wèn)控制符的區(qū)別總結(jié),需要的朋友可以參考下 2014-08-08
-
Rails bundle命令安裝mysql gem包出錯(cuò)的解決方法
這篇文章主要介紹了Rails bundle命令安裝mysql gem包出錯(cuò)的解決方法,本文原因是沒(méi)有安裝mysql開(kāi)發(fā)包,需要的朋友可以參考下 2014-08-08
-
Ruby中使用Block、Proc、lambda實(shí)現(xiàn)閉包
這篇文章主要介紹了Ruby中使用Block、Proc、lambda實(shí)現(xiàn)閉包,在編程領(lǐng)域我們可以通俗的說(shuō):子函數(shù)可以使用父函數(shù)中的局部變量,這種行為就叫做閉包,需要的朋友可以參考下 2014-06-06
-
Ruby中關(guān)于模塊的一些基礎(chǔ)知識(shí)
這篇文章主要介紹了Ruby中關(guān)于模塊的一些基礎(chǔ)知識(shí),是Ruby入門(mén)學(xué)習(xí)中的一些重要知識(shí)點(diǎn),需要的朋友可以參考下 2015-07-07
-
Jekyll靜態(tài)網(wǎng)站后臺(tái)引擎使用教程
今天,我就來(lái)示范如何在github上搭建Blog,你可以從中掌握github的Pages功能,以及Jekyll軟件的基本用法。更重要的是,你會(huì)體會(huì)到一種建立網(wǎng)站的全新思路。 2016-04-04
最新評(píng)論
作用域
Ruby中不具備嵌套作用域(即在內(nèi)部作用域,可以看到外部作用域的)的特點(diǎn),它的作用域是截然分開(kāi)的,一旦進(jìn)入一個(gè)新的作用域,原先的綁定會(huì)被替換為一組新的綁定。
程序會(huì)在三個(gè)地方關(guān)閉前一個(gè)作用域,同時(shí)打開(kāi)一個(gè)新的作用域,它們是:
- 類(lèi)定義class
- 模塊定義 module
- 方法定義 def
上面三個(gè)關(guān)鍵字,每個(gè)關(guān)鍵字對(duì)應(yīng)一個(gè)作用域門(mén)(進(jìn)入),相應(yīng)的end則對(duì)應(yīng)離開(kāi)這道門(mén)。
扁平化作用域
從一個(gè)作用域進(jìn)入另一個(gè)作用域的時(shí)候,局部變量會(huì)立即失效,為了讓局部變量持續(xù)有效,可以通過(guò)規(guī)避關(guān)鍵字的方式,使用方法調(diào)用來(lái)代替作用域門(mén),讓一個(gè)作用域看到另一個(gè)作用域里的變量,從而達(dá)到目的。具體做法是,通過(guò)Class.new替代class,Module#define_method代替def,Module.new代替module。這種做法稱為扁平作用域,表示兩個(gè)作用域擠壓到一起。
示例代碼(Wrong)
my_var = “Success” class MyClass puts my_var #這里無(wú)法正確打印”Success” def my_method puts my_var #這里無(wú)法正確打印”Success” end end
示例代碼(Right)
my_var = “Success” MyClass = Class.new do puts “#{my_var} in the class definition” define_method :my_method do “#{my_var} in the method” end end
在一些語(yǔ)言中,比如java或C#,有內(nèi)部作用域(inner scope)的概念。在內(nèi)部作用域可以看到外部作用域(outer scope)中的變量。但ruby中沒(méi)有這種嵌套式作用域的概念,它的作用域是截然分開(kāi)的,一旦進(jìn)入一個(gè)新的作用域,原先的綁定就會(huì)被替代為一組新的綁定。
在ruby中,程序會(huì)在三個(gè)地方關(guān)閉前一個(gè)作用域,同時(shí)打開(kāi)一個(gè)新的作用域:類(lèi)定義、模塊定義、方法。
只要程序進(jìn)入類(lèi)、模塊或者方法的定義,就會(huì)發(fā)生作用域切換。這三個(gè)邊界分別用class,module和def關(guān)鍵字作為標(biāo)志,每一個(gè)關(guān)鍵字都充當(dāng)了一個(gè)作用域門(mén)(scope gate)。
怎樣讓綁定穿越一個(gè)作用域門(mén)呢?比如下面的代碼:
my_var = “hello” class MyClass #你希望在這里能打印my_var def my_method #...還有這里 end end
在進(jìn)入另一個(gè)作用域時(shí),局部變量會(huì)立刻失效。如果把class關(guān)鍵字替換為某個(gè)非作用域門(mén)的東西,比如方法,就能在一個(gè)閉包中獲得my_var的值,并把這個(gè)閉包傳遞給該方法。代碼如下:
my_var = “hello” MyClass = Class.new do puts “#{my_var} in the class definition” def my_method #...這里怎樣打印出來(lái)呢? end end
用Module#define_method()方法可以替代def,代碼如下:
my_var = “hello” MyClass = Class.new do puts “#{my_var} in the class definition” define_method :my_method do puts “#{my_var} in the method” end end MyClass.new.my_method
hello in the class definition hello in the method
共享作用域
將一組方法定義到,某個(gè)變量的扁平作用域中,可以保證變量?jī)H被有限的幾個(gè)方法所共享。這種方式稱為共享作用域。
相關(guān)文章
ruby迭代map的簡(jiǎn)潔寫(xiě)法實(shí)現(xiàn)原理分析
這篇文章主要介紹了ruby迭代map的簡(jiǎn)潔寫(xiě)法實(shí)現(xiàn)原理分析,本文著重對(duì)簡(jiǎn)潔寫(xiě)法的原理進(jìn)行解析,需要的朋友可以參考下2014-11-11Ruby中的public、private、protected區(qū)別小結(jié)
這篇文章主要介紹了Ruby中的public、private、protected區(qū)別小結(jié),即Ruby中訪問(wèn)控制符的區(qū)別總結(jié),需要的朋友可以參考下2014-08-08Rails bundle命令安裝mysql gem包出錯(cuò)的解決方法
這篇文章主要介紹了Rails bundle命令安裝mysql gem包出錯(cuò)的解決方法,本文原因是沒(méi)有安裝mysql開(kāi)發(fā)包,需要的朋友可以參考下2014-08-08Ruby中使用Block、Proc、lambda實(shí)現(xiàn)閉包
這篇文章主要介紹了Ruby中使用Block、Proc、lambda實(shí)現(xiàn)閉包,在編程領(lǐng)域我們可以通俗的說(shuō):子函數(shù)可以使用父函數(shù)中的局部變量,這種行為就叫做閉包,需要的朋友可以參考下2014-06-06Ruby中關(guān)于模塊的一些基礎(chǔ)知識(shí)
這篇文章主要介紹了Ruby中關(guān)于模塊的一些基礎(chǔ)知識(shí),是Ruby入門(mén)學(xué)習(xí)中的一些重要知識(shí)點(diǎn),需要的朋友可以參考下2015-07-07Jekyll靜態(tài)網(wǎng)站后臺(tái)引擎使用教程
今天,我就來(lái)示范如何在github上搭建Blog,你可以從中掌握github的Pages功能,以及Jekyll軟件的基本用法。更重要的是,你會(huì)體會(huì)到一種建立網(wǎng)站的全新思路。2016-04-04