Ruby中的Proc類及Proc的類方法Proc.new的使用解析
Proc是對(duì)塊及其context(局部變量的作用域以及??蚣?進(jìn)行對(duì)象化處理之后得到的過(guò)程對(duì)象。您可以像使用無(wú)名函數(shù)那樣來(lái)使用Proc,但它不會(huì)導(dǎo)入局部變量的作用域(可以把動(dòng)態(tài)局部變量用作Proc局部變量)。
在下例中,正因?yàn)镻roc一直保持著局部變量的作用域,所以才能調(diào)用var變量。
var = 1
$foo = Proc.new { var }
var = 2
def foo
$foo.call
end
p foo # => 2
從生成Proc的方法中返回以后,若Proc中出現(xiàn)return或retry的話,會(huì)引發(fā)LocalJumpError異常。
def foo
proc { return }
end
foo.call
# => in `call': return from proc-closure (LocalJumpError)
def foo
proc { retry }
end
foo.call
# => in `call': retry from proc-closure (LocalJumpError)
若在Proc前面加上"&"并將其傳給一個(gè)帶塊的方法時(shí),其運(yùn)作情形類似于調(diào)用塊。但從嚴(yán)格意義上講,其間還存在以下不同。
# 沒(méi)問(wèn)題
(1..5).each { break }
# 在ruby 1.6.7, 1.8中沒(méi)問(wèn)題。在1.6.8中則發(fā)生異常
proc = Proc.new { break }
(1..5).each(&proc)
# 在ruby 1.6 中是 LocalJumpError
# 在ruby 1.8 中,再次運(yùn)行each
proc = Proc.new { retry }
(1..5).each(&proc)
#=> retry from proc-closure (LocalJumpError)
這正是Proc對(duì)象用作調(diào)用塊時(shí)的限制。
Proc.new
Proc.new { ... }
對(duì)塊及其context進(jìn)行對(duì)象化處理之后返回結(jié)果。
若沒(méi)有給出塊的話,就會(huì)把調(diào)用該方法的方法所帶的塊轉(zhuǎn)換為Proc對(duì)象并將其返回。
def foo
pr = Proc.new
pr.call(1,2,3)
end
foo {|args| p args }
# => [1, 2, 3]
Proc.new方法深入
Proc.new對(duì)塊及其context進(jìn)行對(duì)象化處理之后返回結(jié)果。
若沒(méi)有給出塊的話,就會(huì)把調(diào)用該方法的方法所帶的塊轉(zhuǎn)換為Proc對(duì)象并將其返回。
def foo
pr = Proc.new
pr.call(1,2,3)
end
foo {|args| p args }
# => [1, 2, 3]
這與下例相同
def foo
yield(1,2,3)
end
foo {|args| p args }
# => [1, 2, 3]
若主調(diào)方法并沒(méi)有帶塊時(shí),則引發(fā)ArgumentError異常。
def foo
Proc.new
end
foo
# => -:2:in `new': tried to create Proc object without a block (ArgumentError)
from -:2:in `foo'
from -:4
在使用Proc.new時(shí),若定義了Proc#initialize方法的話,就在對(duì)象初始化時(shí)調(diào)用該方法。除此以外,它和proc是相同的。
利用 Proc.new 方法,或者對(duì) proc 方法指定塊,都可以創(chuàng)建代表塊的 Proc 對(duì)象。
通過(guò)調(diào)用 Proc#call 方法執(zhí)行塊。調(diào)用 Proc#call 方法時(shí)的參數(shù)會(huì)作為塊變量,塊中最后一個(gè)表達(dá)式的值則為 Proc#call 的返回值。Proc#call 還有一個(gè)名稱叫 Proc#[]。
# 判斷西歷的年是否為閏年的處理 leap = Proc.new do |year| year % 4 == 0 && year % 100 != 0 || year % 400 ==0 end p leap.call(2000) #=> true p leap[2013] #=> false p leap[2016] #=> true
將塊變量設(shè)置為 |* 數(shù)組 | 的形式后,就可以像方法參數(shù)一樣,以數(shù)組的形式接收可變數(shù)量的參數(shù)。
double = Proc.new do |*args|
args.map{|i| i * 2 } # 所有元素乘兩倍
end
p double.call(1, 2, 3) #=> [2, 3, 4]
p double[2, 3, 4] #=> [4, 6, 8]
除此以外,定義普通方法時(shí)可使用的參數(shù)形式,如默認(rèn)參數(shù)、關(guān)鍵字參數(shù)等,幾乎都可以被用于塊變量的定義,并被指定給 Proc#call 方法。
相關(guān)文章
以MVC的思維方式來(lái)理解Ruby on Rails框架的設(shè)計(jì)結(jié)構(gòu)
Ruby on Rails是Ruby世界中Web開(kāi)發(fā)框架的代名詞,人氣相當(dāng)之高,本文就帶大家以MVC的思維方式來(lái)理解Ruby on Rails框架的設(shè)計(jì)結(jié)構(gòu),需要的朋友可以參考下2016-05-05
ruby實(shí)現(xiàn)github第三方認(rèn)證
GitHub在用戶認(rèn)證過(guò)程中采用了雙匙機(jī)制,在雙匙加密機(jī)制中,只有合法用戶才擁有私匙,只要GitHub在收到請(qǐng)求時(shí)可以證明提交請(qǐng)求的客戶端上擁有該私匙,即可以確認(rèn)該操作是由合法用戶發(fā)起的。我們通過(guò)ruby來(lái)簡(jiǎn)單模擬下吧。2015-06-06
Ruby遍歷文件夾同時(shí)計(jì)算文件的md5sum
這篇文章主要介紹了Ruby遍歷文件夾同時(shí)計(jì)算文件的md5sum,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-05-05
Windows下Ruby on Rails開(kāi)發(fā)環(huán)境安裝配置圖文教程
這篇文章主要介紹了Windows下Ruby on Rails開(kāi)發(fā)環(huán)境安裝配置圖文教程,ROR初學(xué)者必看,需要的朋友可以參考下2014-07-07
Ruby實(shí)現(xiàn)的刪除已經(jīng)合并的git分支腳本分享
這篇文章主要介紹了Ruby實(shí)現(xiàn)的刪除已經(jīng)合并的git分支腳本分享,本文給出腳本代碼、使用方法和執(zhí)行結(jié)果,需要的朋友可以參考下2015-01-01
Ruby中XML格式數(shù)據(jù)處理庫(kù)REXML的使用方法指南
這篇文章主要介紹了Ruby中XML格式數(shù)據(jù)處理庫(kù)REXML的使用方法指南,值得注意的REXML庫(kù)處理XML字符串時(shí)的編碼問(wèn)題,是需要的朋友可以參考下2016-04-04

