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
end
và một chuỗi các chuỗi
arr = ["1", "2"]
Chúng tôi muốn map
danh 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_one
phươ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
Object#method
trả 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ó self
là gì , trong khi Module#instance_method
trả về một UnboundMethod
vì nó không thể biết nó sẽ được sử dụng với thể hiện nào.
.instance_method
vì 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 :function
làm đối số duy nhất.
:function
là một Symbol
nghĩa đen, tức là nó là ký hiệu theo nghĩa đen của a Symbol
. Symbol
là 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 Proc
thành một khối . Tức là nó cho phép bạn vượt qua Proc
nơ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_proc
tin 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.)
Proc
là 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 method
phương thức trên self
với :function
tư cách là đối số, gọi to_proc
giá 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 integrate
như thể bạn đã viết một cái gì đó như
res = integrate(0, 1, a) do
# something
end
Các method
phương pháp ở đây là có khả năng nhất, các Object#method
phươ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 .