Ruby中的Proc類及Proc的類方法Proc.new的使用解析
Proc是對塊及其context(局部變量的作用域以及??蚣?進行對象化處理之后得到的過程對象。您可以像使用無名函數(shù)那樣來使用Proc,但它不會導(dǎo)入局部變量的作用域(可以把動態(tài)局部變量用作Proc局部變量)。
在下例中,正因為Proc一直保持著局部變量的作用域,所以才能調(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的話,會引發(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前面加上"&"并將其傳給一個帶塊的方法時,其運作情形類似于調(diào)用塊。但從嚴格意義上講,其間還存在以下不同。
# 沒問題 (1..5).each { break } # 在ruby 1.6.7, 1.8中沒問題。在1.6.8中則發(fā)生異常 proc = Proc.new { break } (1..5).each(&proc) # 在ruby 1.6 中是 LocalJumpError # 在ruby 1.8 中,再次運行each proc = Proc.new { retry } (1..5).each(&proc) #=> retry from proc-closure (LocalJumpError)
這正是Proc對象用作調(diào)用塊時的限制。
Proc.new Proc.new { ... }
對塊及其context進行對象化處理之后返回結(jié)果。
若沒有給出塊的話,就會把調(diào)用該方法的方法所帶的塊轉(zhuǎn)換為Proc對象并將其返回。
def foo pr = Proc.new pr.call(1,2,3) end foo {|args| p args } # => [1, 2, 3]
Proc.new方法深入
Proc.new對塊及其context進行對象化處理之后返回結(jié)果。
若沒有給出塊的話,就會把調(diào)用該方法的方法所帶的塊轉(zhuǎn)換為Proc對象并將其返回。
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)方法并沒有帶塊時,則引發(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時,若定義了Proc#initialize方法的話,就在對象初始化時調(diào)用該方法。除此以外,它和proc是相同的。
利用 Proc.new 方法,或者對 proc 方法指定塊,都可以創(chuàng)建代表塊的 Proc 對象。
通過調(diào)用 Proc#call 方法執(zhí)行塊。調(diào)用 Proc#call 方法時的參數(shù)會作為塊變量,塊中最后一個表達式的值則為 Proc#call 的返回值。Proc#call 還有一個名稱叫 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ù)、關(guān)鍵字參數(shù)等,幾乎都可以被用于塊變量的定義,并被指定給 Proc#call 方法。
相關(guān)文章
Ruby元編程之夢中情人method_missing方法詳解
這篇文章主要介紹了Ruby元編程之夢中情人method_missing方法詳解,本文講解了我該怎么用 method_missing 、方法代理、define_method、什么時候用 method_missing、元方法等內(nèi)容,需要的朋友可以參考下2015-05-05

windows下安裝ruby與rails時遇到的問題總結(jié)

Ruby創(chuàng)建“關(guān)鍵字”同名方法別名的方法

Ruby on Rails中的ActiveRecord編程指南

Linux下Redis數(shù)據(jù)庫的安裝方法與自動啟動腳本分享