Tôi có một vài module mở rộng phương pháp mất tích:Làm thế nào để soạn module chứa method_missing trong ruby
module SaysHello
def respond_to?(method)
super.respond_to?(method) || !!(method.to_s =~ /^hello/)
end
def method_missing(method, *args, &block)
if (method.to_s =~ /^hello/)
puts "Hello, #{method}"
else
super.method_missing(method, *args, &block)
end
end
end
module SaysGoodbye
def respond_to?(method)
super.respond_to?(method) || !!(method.to_s =~ /^goodbye/)
end
def method_missing(method, *args, &block)
if (method.to_s =~ /^goodbye/)
puts "Goodbye, #{method}"
else
super.method_missing(method, *args, &block)
end
end
end
class ObjectA
include SaysHello
end
class ObjectB
include SaysGoodbye
end
này tất cả hoạt động tốt, ví dụ như ObjectA.new.hello_there
đầu ra "Hello, hello_there"
. Tương tự, ObjectB.new.goodbye_xxx
kết quả đầu ra "Goodbye, xxx"
. respond_to?
cũng hoạt động, ví dụ: ObjectA.new.respond_to? :hello_there
trả về true.
Tuy nhiên, điều này không làm việc rất tốt khi bạn muốn sử dụng cả hai SaysHello
và SaysGoodbye
:
class ObjectC
include SaysHello
include SaysGoodbye
end
Trong khi ObjectC.new.goodbye_aaa
tác phẩm một cách chính xác, ObjectC.new.hello_a
hành động kỳ lạ:
> ObjectC.new.hello_aaa
Hello, hello_aaa
NoMethodError: private method `method_missing' called for nil:NilClass
from test.rb:22:in `method_missing' (line 22 was the super.method_missing line in the SaysGoodbye module)
Nó ra một cách chính xác, sau đó ném một lỗi. Ngoài ra respond_to?
không chính xác, ObjectC.new.respond_to? :hello_a
trả về false.
Cuối cùng, thêm lớp này:
class ObjectD
include SaysHello
include SaysGoodbye
def respond_to?(method)
super.respond_to?(method) || !!(method.to_s =~ /^lol/)
end
def method_missing(method, *args, &block)
if (method.to_s =~ /^lol/)
puts "Haha, #{method}"
else
super.method_missing(method, *args, &block)
end
end
end
Ngoài ra hoạt động kỳ lạ. ObjectD.new.lol_zzz
hoạt động, tuy nhiên ObjectD.new.hello_a and ObjectD.new.goodbye_t
đều ném ngoại lệ tên sau khi xuất chuỗi chính xác. respond_to?
cũng không thành công cho các phương thức chào và tạm biệt.
Có cách nào để điều này hoạt động chính xác không? Giải thích về cách method_missing
, Mô-đun và super
tương tác cũng sẽ thực sự hữu ích.
EDIT: coreyward đã giải quyết được sự cố, nếu tôi sử dụng siêu thay vì super.<method-name>(args...)
trong tất cả các phương pháp tôi xác định, chương trình hoạt động chính xác. Tôi không hiểu tại sao điều này là mặc dù, vì vậy tôi hỏi một câu hỏi về điều này tại What does super.<method-name> do in ruby?
module bao gồm được bổ sung vào chuỗi thừa kế; họ không ghi đè hoặc thay thế các phương pháp. Vì vậy, nếu mỗi method_missing gọi super, cuối cùng chúng sẽ được gọi. Xem câu trả lời của tôi dưới đây. – ChrisPhoenix