Menu
CoddyTech

Proc và lambda

Thuộc phần Logic và luồng xử lý trong hành trình Ruby của Coddy. Bài học 19 trên 56.

Khối lệnh không phải là một đối tượng, bạn không thể lưu nó vào một biến. Khi muốn có một đoạn code mà bạn có thể truyền đi, lưu lại và gọi sau này, bạn đặt nó trong một Proc hoặc một lambda.

Một Proc được tạo bằng Proc.new hoặc từ khóa proc. Gọi Proc bằng .call:

double = proc { |n| n * 2 }
puts double.call(5)   # 10
puts double.call(7)   # 14

Lambda cũng tương tự nhưng nghiêm ngặt hơn, nó kiểm tra xem bạn có truyền đúng số lượng đối số không. Dạng mũi tên -> là cách viết phổ biến:

square = ->(n) { n * n }
puts square.call(4)   # 16
puts square.(4)       # 16  (cách viết tắt của .call)

Cả hai đều có thể được truyền vào một phương thức mong đợi khối lệnh bằng cách thêm tiền tố &:

[1, 2, 3].map(&double)   # [2, 4, 6]
[1, 2, 3].map(&square)   # [1, 4, 9]

Dùng lambda khi bạn muốn kiểm tra đối số chặt chẽ hơn; dùng Proc khi bạn muốn hành vi linh hoạt và dễ chấp nhận hơn.

challenge icon

Thử thách

Dễ

Tạo một lambda có tên tripler, nhận vào một số và trả về số đó nhân với 3.

Sau đó đọc một danh sách số nguyên được phân tách bằng dấu phẩy và in ra, mỗi kết quả trên một dòng riêng:

  1. Kết quả khi gọi tripler.call(10)
  2. Các số đầu vào sau khi nhân ba, dùng map(&tripler), rồi nối lại bằng ,

Với đầu vào 1,2,3, đầu ra là:

30
3, 6, 9

Tự làm thử

# TODO: định nghĩa `tripler` là một hàm lambda

numbers = gets.chomp.split(",").map(&:to_i)

# TODO: dòng 1, in ra tripler.call(10)
# TODO: dòng 2, dùng &tripler để ánh xạ numbers, rồi nối các giá trị bằng ", "
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Logic và luồng xử lý

Tự luyện tập: Trình biên dịch Ruby online