Khác nhau giữa block, proc và lambda trong ruby
Bài đăng này đã không được cập nhật trong 6 năm
Block, Proc, Lambdas là gì
Định nghĩa đơn giản là cách chúng ta nhóm những đoạn code vào 1 chỗ và gọi ra để chạy khi cần
# Block Examples
[1,2,3].each { |x| puts x*2 } # block được giới hạn bởi dấu {}
[1,2,3].each do |x|
puts x*2 # block được giới hạn bởi do và end
end
# Proc Examples
p = Proc.new { |x| puts x*2 }
[1,2,3].each(&p) # Ký tự '&' bảo ruby đưa các proc (các giá trị của array) vào trong block mà proc đấy định nghĩa
proc = Proc.new { puts "Hello World" }
proc.call # block mà proc đấy định nghĩa đc thực thi khi gọi hàm call từ proc
# Lambda Examples
lam = lambda { |x| puts x*2 }
[1,2,3].each(&lam)
lam = lambda { puts "Hello World" }
lam.call
Nhìn qua thấy chúng rất giống nhau, đều là định nghĩa các block rồi đưa biêns vào thực thi block đấy sau đây là sự khác nhau
Block và proc
- Proc là 1 object, block không phải, block chỉ đơn giản là 1 khối lệnh
p = Proc.new { puts "Hello World" }
tạo 1 instance của proc
p.call # prints 'Hello World'
p.class # returns 'Proc'
a = p # a now equals p, a Proc instance
p # returns a proc object '#<Proc:0x007f96b1a60eb0@(irb):46>'
Trong khi đó, block chỉ là 1 khối lệnh và ko có ý nghĩa gì hết, cũng ko gán qua gán lại được
{ puts "Hello World"} # syntax error
a = { puts "Hello World"} # syntax error
[1,2,3].each {|x| puts x*2} # only works as part of the syntax of a method call
Proc và lambdas
Cả proc và lambdas đều là proc object
proc = Proc.new { puts "Hello world" }
lam = lambda { puts "Hello World" }
proc.class # returns 'Proc'
lam.class # returns 'Proc'
Tuy nhiên lambdas khác đôi chút
proc # returns '#<Proc:0x007f96b1032d30@(irb):75>'
lam # returns '<Proc:0x007f96b1b41938@(irb):76 (lambda)>'
- Lambdas check số lượng tham số truyên vào còn proc thì không
lam = lambda { |x| puts x } # creates a lambda that takes 1 argument
lam.call(2) # prints out 2
lam.call # ArgumentError: wrong number of arguments (0 for 1)
lam.call(1,2,3) # ArgumentError: wrong number of arguments (3 for 1)
proc = Proc.new { |x| puts x } # creates a proc that takes 1 argument
proc.call(2) # prints out 2
proc.call # returns nil
proc.call(1,2,3) # prints out 1 and forgets about the extra arguments
- Lambas và proc luận giải 'return' khác nhau
def lambda_test
lam = lambda { return }
lam.call
puts "Hello world"
end
lambda_test # calling lambda_test prints 'Hello World'
return của lambda đựoc kích hoạt code ngay bên ngoài lambda code
def proc_test
proc = Proc.new { return }
proc.call
puts "Hello world"
end
proc_test # calling proc_test prints nothing
return của proc kích hoạt code bên ngoài cái method mà proc đấy đc thực thi
All rights reserved