`& Phương thức (: function)` nghĩa là gì?


15

&method(:function)nghĩa là gì? Ví dụ: tôi có dòng này:

res = integrate(0, 1, a, &method(:function))

Hai câu trả lời xuất sắc (cho đến nay). Bạn thật may mắn!
Cary Swoveland

Câu trả lời:


13

Nói rằng chúng tôi có một phương pháp

def add_one(num)
  num + 1
end

và 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
end

Bạ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 successfully

Nitpick: Object#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.
Jörg W Mittag

@ JörgWMittag Ok cảm ơn vì đã sửa lỗi, bạn đã đúng Tôi phải trộn nó với .instance_methodvì tôi vừa mới đi qua (thiếu sót) bộ nhớ
max pleaner

10

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
end

Cá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)
end

Nhưng thể hiện trong những gì thường được gọi là phong cách pointfree .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.