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) # 14Lambda 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.
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:
- Kết quả khi gọi
tripler.call(10) - 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, 9Tự 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 ", "
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ý
1Tìm hiểu sâu về chuỗi
Tổng quan về phương thức chuỗiNội suy chuỗiDuyệt qua chuỗiTách và nối chuỗiÔn tập: Đan chuỗi4Khối lệnh, Proc và lambda
Khối lệnh là gì?do..end và dấu ngoặc nhọnTừ khóa yieldTham số của khối lệnhProc và lambdaÔn tập: bộ lặp tùy chỉnh7Hash, phần 2
Hash.new với giá trị mặc địnhLặp qua HashHash lồng nhauGộp và chuyển đổiÔn tập: Bộ đếm tần suất10Dự án: Hồ sơ học sinh
Tổng quan dự ánThêm học sinh2Phạm vi
Phạm vi là gì?Các phương thức của phạm viPhạm vi trong case / whenÔn tập: luyện tập với phạm vi5Sức mạnh của Enumerable
select và rejectNối chuỗi mapreduce / injectcount, all?, any?, none?group_by và partitionsort_by, min_by, max_byÔn tập: quy trình dữ liệuTự luyện tập: Trình biên dịch Ruby online