Khác nhau giữa block, proc và lambda trong ruby
Đị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 ...
Đị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
- 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
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