Ai đó có thể vui lòng cho tôi biết điều gì không
send("#{Model.find...}")
là và không?
Ai đó có thể vui lòng cho tôi biết điều gì không
send("#{Model.find...}")
là và không?
Câu trả lời:
send
gửi một thông báo đến một cá thể đối tượng và tổ tiên của nó trong phân cấp lớp cho đến khi một số phương thức phản ứng (vì tên của nó khớp với đối số đầu tiên).
Thực tế mà nói, những dòng đó tương đương:
1.send '+', 2
1.+(2)
1 + 2
Lưu ý rằng send
bỏ qua kiểm tra khả năng hiển thị, để bạn cũng có thể gọi các phương thức riêng tư (hữu ích cho kiểm tra đơn vị).
Nếu thực sự không có biến nào trước khi gửi, điều đó có nghĩa là Đối tượng chung được sử dụng:
send :to_s # "main"
send :class # Object
send là một phương thức ruby (không có đường ray) cho phép gọi một phương thức khác theo tên.
Từ tài liệu
class Klass
def hello(*args)
"Hello " + args.join(' ')
end
end
k = Klass.new
k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
Một trong những tính năng hữu ích nhất mà tôi nghĩ với phương thức .send là nó có thể tự động gọi phương thức. Điều này có thể giúp bạn tiết kiệm rất nhiều công việc đánh máy. Một trong những cách sử dụng phổ biến nhất của phương thức .send là gán các thuộc tính động. Ví dụ:
class Car
attr_accessor :make, :model, :year
end
Để chỉ định các thuộc tính thường xuyên, người ta cần
c = Car.new
c.make="Honda"
c.model="CRV"
c.year="2014"
Hoặc sử dụng phương thức .send:
c.send("make=", "Honda")
c.send("model=", "CRV")
c.send("year=","2014")
Nhưng tất cả có thể được thay thế bằng những thứ sau:
Giả sử ứng dụng Rails của bạn cần gán các thuộc tính cho loại xe của bạn từ thông tin người dùng nhập, bạn có thể làm
c = Car.new()
params.each do |key, value|
c.send("#{key}=", value)
end
Một ví dụ khác, tương tự như https://stackoverflow.com/a/26193804/1897857 của Antonio Jha
là nếu bạn cần đọc các thuộc tính trên một đối tượng.
Ví dụ: nếu bạn có một mảng chuỗi, nếu bạn cố gắng lặp lại chúng và gọi chúng trên đối tượng của mình, nó sẽ không hoạt động.
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.a
end
# => NoMethodError: undefined method `a'
Tuy nhiên, bạn có thể send
xâu chuỗi đối tượng:
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.send(a)
end
# => Vandalay Project
# => A very important project
define_method
: apidock.com/ruby/Module/define_method .
send
là một cách gọi khác của một phương thức.
Điều này được minh họa tốt nhất bằng ví dụ:
o = Object.new
o.send(:to_s) # => "#<Object:0x00005614d7a24fa3>"
# is equivalent to:
o.to_s # => "#<Object:0x00005614d7a24fa3>"
Gửi các cuộc sống trong lớp Đối tượng .
Lợi ích của phương pháp này là bạn có thể chuyển vào phương thức bạn muốn gọi dưới dạng tham số. Đây là một ví dụ đơn giản:
def dynamically_call_a_method(name)
o = Object.new
o.send name
end
dynamically_call_a_method(:to_s) # => "#<Object:0x00005614d7a24fa3>"
Bạn có thể chuyển vào phương thức bạn muốn được gọi. Trong trường hợp này, chúng tôi đã vượt qua :to_s
. Điều này có thể rất hữu ích khi thực hiện lập trình siêu ứng dụng ruby, bởi vì điều này cho phép chúng ta gọi các phương thức khác nhau theo các yêu cầu khác nhau của chúng ta.
Một trường hợp sử dụng khác cho các khung nhìn:
<%= link_to
send("first_part_of_path_#{some_dynamic_parameters}_end_path",
attr1, attr2), ....
%>
Cho phép. bạn viết chế độ xem có thể mở rộng làm việc với tất cả các loại đối tượng với:
render 'your_view_path', object: "my_object"