Preface
在 程式區塊與 Proc 中談過,Proc 物件像是個程式流程片段,有時候,你希望的是程式區塊更像是個方法呼叫,這時可以使用 lambda 方法。例如:
上例就像是:
- def some
- def lda
- puts "執行 lambda"
- return 1
- end
- puts "some 1"
- lda
- puts "some 2"
- end
然而你仔細觀察,使用 lambda 方法傳回的物件,其實也是 Proc 實例:
lambda 與直接使用 Proc.new 建立的物件不同的地方在於,Proc.new 直接建立的物件像個程式流程,而 lambda方法建立的 Proc 物件像是個方法,因此 lambda 建立時的程式區塊 return,就像是個方法 return,另外,lambda 建立的 Proc 物件,有哪些區塊參數,call 就只能傳入幾 個引數。例如:
因此 lambda 建立的 Proc 物件,在概念上就類似其它程式語言的一級函式物件,因此在 Ruby 1.9 之後,直接使用語法支援 lambda 方法建立的 Proc 物件。例如:
圓括號中可以指定參數,若不需要參數,則圓括號可以省略。由於 lambda 建立的也是 Proc 物件,所以適用程式區塊的方法,也可以使用 lambda 建立的 Proc 物件。例如:
不過這並不是 lambda 最主要的用途,由於 lambda 建立的 Proc 物件更像是個方法,所以你可以將之自由傳遞,也可以從方法中返回,而不用擔心 return 的問題。一個例子像是 因 式分解,可以先準備好一定長度的質數表,之後利用該質數表來進行因式分解。例如:
- class Range
- def comprehend(&block)
- return self if block.nil?
- self.collect(&block).compact
- end
- end
- def prepare_factor(max)
- prime = Array.new(max, 1)
- 2.upto(Math.sqrt(max).to_i - 1) do |i|
- if prime[i] == 1
- (2 * i).upto(max - 1) do |j|
- if j % i == 0
- prime[j] = 0
- end
- end
- end
- end
- primes = (2..max - 1).comprehend { |i| i if prime[i] == 1} # 質數表
- ->(num) {
- list = []
- i = 0
- while primes[i] ** 2 <= num
- if num % primes[i] == 0
- list << primes[i]
- num /= primes[i]
- else
- i += 1
- end
- end
- list << num
- f = Array.new(list.length, 0)
- f.length.times { |i|
- f[i] = list[i]
- }
- return f # 在這邊return是可以不寫的,只是為了強調
- }
- end
- factor = prepare_factor(1000)
- p factor.call(100) # 顯示 [2, 2, 5, 5]
- p factor.call(500) # 顯示 [2, 2, 5, 5, 5]
- p factor.call(800) # 顯示 [2, 2, 2, 2, 2, 5, 5]
- def prepare_factor(max)
- ...
- Proc.new { |num|
- list = []
- i = 0
- while primes[i] ** 2 <= num
- if num % primes[i] == 0
- list << primes[i]
- num /= primes[i]
- else
- i += 1
- end
- end
- list << num
- f = Array.new(list.length, 0)
- f.length.times { |i|
- f[i] = list[i]
- }
- f
- }
- end
沒有留言:
張貼留言