昨天有提到 Block 不是物件,但我們可以透過 Proc 將 Block 物件化,也可以避免重複撰寫功能類似的 Block。
我們可以使用 Proc.new {block} 將block 存為物件。
# 創建一個 Proc
my_proc = Proc.new { |x| x * 2 }
# 使用 Proc 呼叫它並傳入參數
result = my_proc.call(3)
# 輸出結果
puts "呼叫 Proc 後的結果:#{result}"
當我們要將 Proc 帶入到函式時,需要使用 & 符號來將 Proce 轉換為 Block。
# 定義一個接受 block 的函式
def process_data(data, &block)
puts "Start processing data..."
result = block.call(data)
puts "Finish processing data. Result: #{result}"
end
# 創建一個 Proc,該 Proc 用於對數據進行轉換
multiply_by_2 = Proc.new { |x| x * 2 }
# 呼叫函式並代入 Proc
data_to_process = [1, 2, 3, 4, 5]
process_data(data_to_process, &multiply_by_2)
除了 Proc 我們也可以使用 Lamda 將 Block 物件化。
使用方式和 Proc 相同。
使用關鍵字 'lambda' or '->'。
# 使用 lambda 關鍵字創建 Lambda
my_lambda = lambda { |x, y| x + y }
# 使用 -> 符號創建 Lambda
my_lambda = ->(x, y) { x + y }
Lambda 對於參數的數量是嚴格的,必須要傳遞正確數量的參數,否則會引發 'ArgumentError'
Proc 不要求參數數量嚴格匹配,當參數數量不足時,會補充為 'nil',不引發錯誤。
# Lambda 的例子
my_lambda = lambda { |x, y| x + y }
my_lambda.call(1, 2) # 正確,返回 3
my_lambda.call(1) # 錯誤,引發 ArgumentError
# Proc 的例子
my_proc = Proc.new { |x, y| x + y }
my_proc.call(1, 2) # 正確,返回 3
my_proc.call(1) # 正確,返回 nil
Lambda 使用 'return' 會將控制權交回呼叫他的方法,並繼續執行該方法後續的片段。
Proc 使用 'return' 會立即跳出該方法。
# Lambda 的例子
def lambda_example
my_lambda = lambda { return "Hello from Lambda!" }
my_lambda.call
return "This will be reached."
end
# Proc 的例子
def proc_example
my_proc = Proc.new { return "Hello from Proc!" }
my_proc.call
return "This won't be reached."
end
puts lambda_example # 輸出 "This will be reached."
puts proc_example # 輸出 "Hello from Proc!"
簡單來說, Lambda 較嚴格,需要精確參數控制、不中斷方法執行,Proc 更靈活,可以彈性處理參數,並在需要時中斷方法。