Tôi muốn chuyển một đối số cho một phương thức được xác định bằng cách sử dụng define_method, tôi sẽ làm như thế nào?Làm thế nào để bạn vượt qua đối số để define_method?
Trả lời
Khối bạn vượt qua để define_method có thể bao gồm một số thông số. Đó là cách phương thức được định nghĩa của bạn chấp nhận các đối số. Khi bạn xác định một phương thức, bạn thực sự chỉ cần đặt tên cho khối đó và giữ một tham chiếu đến nó trong lớp. Các tham số đi kèm với khối. Vì vậy:
define_method(:say_hi) { |other| puts "Hi, " + other }
Ngoài câu trả lời của Kevin Conner: đối số khối không hỗ trợ cùng ngữ nghĩa làm đối số phương pháp. Bạn không thể xác định đối số mặc định hoặc chặn đối số.
Điều này chỉ được sửa trong Ruby 1.9 với cú pháp thay thế mới "stabby lambda" hỗ trợ ngữ nghĩa đối số đầy đủ.
Ví dụ:
# Works
def meth(default = :foo, *splat, &block) puts 'Bar'; end
# Doesn't work
define_method :meth { |default = :foo, *splat, &block| puts 'Bar' }
# This works in Ruby 1.9 (modulo typos, I don't actually have it installed)
define_method :meth, ->(default = :foo, *splat, &block) { puts 'Bar' }
Trên thực tế, tôi tin rằng các đối số khối trên define_method làm hỗ trợ splat, mà có thể cung cấp một cách vòng-a-bout để xác định đối số mặc định quá. – Chinasaur
Chinasaur là chính xác về các đối số khối cho phép các biểu tượng. Tôi đã xác nhận điều này trong cả Ruby 1.8.7 và 1.9.1. –
Cảm ơn, tôi đã quên mất điều này. Đã sửa lỗi. –
... và nếu bạn muốn thông số tùy chọn
class Bar
define_method(:foo) do |arg=nil|
arg
end
end
a = Bar.new
a.foo
#=> nil
a.foo 1
# => 1
... như nhiều lập luận như bạn muốn
class Bar
define_method(:foo) do |*arg|
arg
end
end
a = Bar.new
a.foo
#=> []
a.foo 1
# => [1]
a.foo 1, 2 , 'AAA'
# => [1, 2, 'AAA']
... kết hợp của
class Bar
define_method(:foo) do |bubla,*arg|
p bubla
p arg
end
end
a = Bar.new
a.foo
#=> wrong number of arguments (0 for 1)
a.foo 1
# 1
# []
a.foo 1, 2 ,3 ,4
# 1
# [2,3,4]
... tất cả trong số họ
class Bar
define_method(:foo) do |variable1, variable2,*arg, &block|
p variable1
p variable2
p arg
p block.inspect
end
end
a = Bar.new
a.foo :one, 'two', :three, 4, 5 do
'six'
end
Cập nhật
của Ruby 2.0 giới thiệu đôi splat **
(hai ngôi sao) mà (I quote) thực hiện: đối số từ khóa
của Ruby 2.0 giới thiệu và ** hoạt động như *, nhưng đối với đối số từ khóa. Nó trả về một Hash với các cặp khóa/giá trị.
... và tất nhiên bạn có thể sử dụng nó trong xác định phương pháp quá :)
class Bar
define_method(:foo) do |variable1, variable2,*arg,**options, &block|
p variable1
p variable2
p arg
p options
p block.inspect
end
end
a = Bar.new
a.foo :one, 'two', :three, 4, 5, ruby: 'is awesome', foo: :bar do
'six'
end
# :one
# "two"
# [:three, 4, 5]
# {:ruby=>"is awesome", :foo=>:bar}
Đặt tên thuộc tính ví dụ:
class Bar
define_method(:foo) do |variable1, color: 'blue', **other_options, &block|
p variable1
p color
p other_options
p block.inspect
end
end
a = Bar.new
a.foo :one, color: 'red', ruby: 'is awesome', foo: :bar do
'six'
end
# :one
# "red"
# {:ruby=>"is awesome", :foo=>:bar}
Tôi đã cố gắng để tạo ra ví dụ với lập luận từ khóa, splat và double splat tất cả trong một:
define_method(:foo) do |variable1, variable2,*arg, i_will_not: 'work', **options, &block|
# ...
hoặc
define_method(:foo) do |variable1, variable2, i_will_not: 'work', *arg, **options, &block|
# ...
... nhưng điều này sẽ không hoạt động, có vẻ như có giới hạn. Khi bạn nghĩ về nó có ý nghĩa như toán tử splat là "nắm bắt tất cả các đối số còn lại" và splat kép là "nắm bắt tất cả các đối số từ khóa còn lại" do đó trộn chúng sẽ phá vỡ logic dự kiến. (Tôi không có bất kỳ tham chiếu nào để chứng minh điểm này!)
Thú vị - đặc biệt khối thứ tư: nó đã hoạt động trên 1.8.7! Khối đầu tiên không hoạt động trong 1.8.7 và khối thứ hai có lỗi đánh máy (phải là 'a.foo 1' thay vì' foo 1'). Cảm ơn! –
cảm ơn phản hồi, lỗi đánh máy đã được sửa, ... Trên ruby 1.9.3 và 1.9.2 tất cả các ví dụ hoạt động và tôi tích cực là trên 1.9.1 quá (nhưng không thử) – equivalent8
Tôi kết hợp câu trả lời này với chấp nhận câu trả lời tại http://stackoverflow.com/questions/4470108/when-monkey-patching-a-method-can-you-call-the-overridden-method-from-the-new-i để tìm cách ghi đè (không ghi đè lên) một phương thức trong thời gian chạy có các tham số tùy chọn và một khối và vẫn có thể gọi phương thức gốc với các tham số và khối. Ah, ruby. Cụ thể, tôi cần ghi đè Savon :: Client.request trong env dev của tôi cho một cuộc gọi API đến một máy chủ mà tôi có thể truy cập chỉ trong sản xuất. Chúc mừng! – pduey
Với 2.2 bây giờ bạn có thể sử dụng đối số từ khóa: https://robots.thoughtbot.com/ruby-2-keyword-arguments
define_method(:method) do |refresh: false|
..........
end
- 1. Bạn có thể vượt qua một đối số để sigaction?
- 2. Làm thế nào để bạn vượt qua một mảng :: ::?
- 3. Làm thế nào để bạn vượt qua một Container.DataItem như một tham số?
- 4. Làm thế nào để bạn vượt qua tăng :: ràng buộc đối tượng với một chức năng?
- 5. Làm thế nào để vượt qua nhiều giá trị thông qua đối số lệnh trong Asp.net?
- 6. Làm thế nào để vượt qua đối số cho PowerShell qua C#
- 7. Làm thế nào để vượt qua một đối số để xử lý sự kiện trong tkinter?
- 8. python theading.Timer: làm thế nào để vượt qua đối số để gọi lại?
- 9. Làm thế nào để vượt qua đối số argparse để hoạt động như kwargs?
- 10. Làm thế nào để vượt qua mảng đối số để Powershell dòng lệnh
- 11. Làm thế nào để bạn vượt qua một hàm như một tham số trong C?
- 12. Làm thế nào để vượt qua ENUM làm đối số hàm trong C
- 13. PHP: Làm thế nào để vượt qua lớp con __construct() đối số cho cha mẹ :: __ construct()?
- 14. Làm thế nào để bạn vượt qua các đối số từ một hàm này sang hàm khác?
- 15. Làm thế nào để vượt qua một đối tượng duy nhất [] để một đối tượng params []
- 16. Làm thế nào để vượt qua các đối số dòng lệnh khi sử dụng ideone?
- 17. Làm thế nào để vượt qua đối số với dấu chấm than trên linux?
- 18. Làm thế nào để vượt qua các đối số thêm vào trang trí python?
- 19. Làm thế nào để vượt qua các đối số bằng cách sử dụng std :: mem_fun
- 20. Làm thế nào để vượt qua một tập tin văn bản như một đối số?
- 21. Làm thế nào để vượt qua đối số trong @selector trong UITapGestureRecognizer?
- 22. Làm thế nào để vượt qua một đối số khi gọi một tập tin xem?
- 23. Làm thế nào để bạn vượt qua kwargs để tăng cường chức năng bọc python?
- 24. Làm cách nào để vượt qua các đối số bội số trong processStartInfo?
- 25. Làm thế nào để sử dụng va_args để vượt qua các đối số trên (tham số variadic, dấu ba chấm)
- 26. làm thế nào để vượt qua constinity make_shared
- 27. OAuth2.0 làm thế nào để vượt qua access token
- 28. Làm thế nào để vượt qua Drawable sử dụng Parcelable
- 29. làm thế nào để vượt qua một đối số cho một bài kiểm tra junit android (thử nghiệm tham số)
- 30. Làm thế nào để vượt qua đối số trong hy vọng thông qua dòng lệnh trong shell script
Đó chỉ là một điều tuyệt đối không được pha trộn. Làm tốt lắm, Kevin Costner. – Fuser97381