Có &method(:function)nghĩa là gì? Ví dụ: tôi có dòng này:
res = integrate(0, 1, a, &method(:function))Có &method(:function)nghĩa là gì? Ví dụ: tôi có dòng này:
res = integrate(0, 1, a, &method(:function))Câu trả lời:
Nói rằng chúng tôi có một phương pháp
def add_one(num)
  num + 1
endvà một chuỗi các chuỗi
arr = ["1", "2"]Chúng tôi muốn mapdanh sách các chuỗi đến đầu ra tương ứng của chúng từ add_one.
Để bắt đầu, chúng tôi có thể gọi
nums = arr.map(&:to_i)Đây là điều tương tự như
nums = arr.map do |str|
  str.to_i
endBạn có thể thấy Bản đồ (&: name) có nghĩa là gì trong Ruby? để biết thêm thông tin về điều này.
Tuy nhiên, nó không hoạt động để gọi:
nums.map(&:add_one)Tại sao? Bởi vì số không có phương thức xây dựng add_one. Vì vậy, bạn sẽ nhận được một NoMethodError.
Vì vậy, thay vì chỉ cung cấp một tên phương thức, :add_one bạn có thể truyền một phương thức bị ràng buộc method(:add_one) :
nums.map(&method(:add_one))Bây giờ, thay vì mỗi num được sử dụng làm máy thu cho add_onephương thức, chúng sẽ được sử dụng làm đối số . Vì vậy, về cơ bản nó giống như:
nums.map do |num|
  add_one(num)
endĐể đưa ra một ví dụ khác, so sánh như sau:
[1].map(&:puts)
# this is the same as [1].map { |num| num.puts }
# it raises NoMethodError
[1].map(&method(:puts))
# this is the same as [1].map { |num| puts num }
# it prints 1 successfullyObject#methodtrả về một ràng buộc Method , không phải là một UnboundMethod. Phương thức này được liên kết với một người nhận bởi vì bạn đang gọi nó trên một cá thể và do đó nó biết nó selflà gì , trong khi Module#instance_methodtrả về một UnboundMethodvì nó không thể biết nó sẽ được sử dụng với thể hiện nào.
                    .instance_methodvì tôi vừa mới đi qua (thiếu sót) bộ nhớ
                    method(:function)là một tin nhắn gửi (đôi khi được gọi là một cuộc gọi phương thức ) đến người nhận ẩn (tức là self). Nó đang gửi tin nhắn methodđến người nhận ẩn (tức là self), chuyển :functionlàm đối số duy nhất.
:functionlà một Symbolnghĩa đen, tức là nó là ký hiệu theo nghĩa đen của a Symbol. Symbollà một kiểu dữ liệu đại diện cho "tên của một cái gì đó".
&Toán tử tiền tố đơn và toán tử "unrolls" a Procthành một khối . Tức là nó cho phép bạn vượt qua Procnơi mà một khối được mong đợi. Nếu đối tượng chưa là a Proc, nó sẽ được gửi to_proctin nhắn cho phép nó tự chuyển đổi thành a Proc. (Toán tử chỉ hợp pháp trong một danh sách đối số và chỉ cho đối số cuối cùng. Đây là đối số của &sigil trong danh sách tham số, "cuộn" một khối vào một Procđối tượng.)
Proclà một kiểu dữ liệu đại diện cho mã thực thi. Đây là lớp thư viện cốt lõi của Ruby cho các chương trình con hạng nhất.
Vì vậy, những gì nó làm, là gọi methodphương thức trên selfvới :functiontư cách là đối số, gọi to_procgiá trị trả về, "hủy đăng ký" Procđối tượng kết quả thành một khối và chuyển khối đó sang lệnh gọi integratenhư thể bạn đã viết một cái gì đó như
res = integrate(0, 1, a) do
  # something
endCác methodphương pháp ở đây là có khả năng nhất, các Object#methodphương pháp, mà trả về một ràng buộc Method đối tượng.
Vì vậy, tất cả trong tất cả, điều này là phần nào tương đương với
res = integrate(0, 1, a) do |*args, &block|
  function(*args, &block)
endNhưng thể hiện trong những gì thường được gọi là phong cách pointfree .