Là một bài tập lập trình, tôi đã viết một đoạn mã Ruby tạo một lớp, khởi tạo hai đối tượng từ lớp đó, monkeypatches một đối tượng và dựa vào method_missing để monkeypatch một đối tượng khác.Ruby: define_method vs def
Đây là giao dịch. Điều này hoạt động như dự định:
class Monkey
def chatter
puts "I am a chattering monkey!"
end
def method_missing(m)
puts "No #{m}, so I'll make one..."
def screech
puts "This is the new screech."
end
end
end
m1 = Monkey.new
m2 = Monkey.new
m1.chatter
m2.chatter
def m1.screech
puts "Aaaaaargh!"
end
m1.screech
m2.screech
m2.screech
m1.screech
m2.screech
Bạn sẽ nhận thấy rằng tôi có tham số cho method_missing. Tôi đã làm điều này bởi vì tôi đã hy vọng sử dụng define_method để tự động tạo các phương thức còn thiếu với tên thích hợp. Tuy nhiên, nó không hoạt động. Trong thực tế, thậm chí sử dụng define_method với một tên tĩnh như vậy:
def method_missing(m)
puts "No #{m}, so I'll make one..."
define_method(:screech) do
puts "This is the new screech."
end
end
kết thúc với kết quả như sau:
ArgumentError: wrong number of arguments (2 for 1)
method method_missing in untitled document at line 9
method method_missing in untitled document at line 9
at top level in untitled document at line 26
Program exited.
Điều gì làm cho các thông báo lỗi bối rối hơn nữa là tôi chỉ có một đối số cho method_missing
. ..
Đó là một câu trả lời tuyệt vời, Avdi và nó giải thích một số câu hỏi khác mà tôi đã có. Cảm ơn bạn. – gauth
Theo nguyên tắc chung, điều này cho thấy lý do tại sao bạn nên sử dụng danh sách trắng trong 'method_missing', để bạn * chỉ * xử lý các phương thức mà bạn * thực sự * quan tâm và b) chuyển tiếp mọi thứ bạn làm * không * muốn để xử lý "lên chuỗi thức ăn", sử dụng 'super'. –
@ JörgWMittag có thể tôi có thêm một số từ trên dòng * b) chuyển tiếp mọi thứ bạn không muốn xử lý "lên chuỗi thức ăn", sử dụng siêu. ? * –