Theo dõi tới How can I reverse ruby's include function, được trả lời tốt nhưng hóa ra sự đơn giản hóa vấn đề thực sự của tôi không phải là giải pháp không áp dụng được.Làm thế nào tôi có thể "thay thế" một mô-đun được bao gồm thông qua ruby bao gồm chức năng
Tôi bây giờ phải đối mặt với điều này (tên đã thay đổi để bảo vệ bản sắc!):
module OldFormHelpers
def foo
puts "foo"
end
def bar
puts "bar"
end
end
module Helpers
include OldFormHelpers
end
này mang lại cho tôi:
Helpers.instance_methods
=> ["bar", "foo"]
Helpers.ancestors
=> [Helpers, OldFormHelpers]
Đây là mã mà tôi không thực sự có quyền truy cập vào sửa đổi, mà không forking.
Điều tôi muốn làm là tạo mô-đun mới;
module BetterFormHelpers
def foo
puts "better foo"
end
end
này cần phải loại bỏ các hành vi từ OldFormHelpers
, và sau đó thêm vào những thứ mới từ BetterFormHelpers
Các giải pháp trước đây là sử dụng undef_method
như vậy:
Helpers.module_eval do
OldFormHelpers.instance_methods do |m|
undef_method(m)
end
end
Tuy nhiên, sau đó BetterFormHelpers
, Helpers.instance_methods không chứa "foo". Lý do cho điều này được giải thích tại http://ruby-doc.org/core/classes/Module.src/M001652.html
Sử dụng remove_method
nói với tôi rằng Helpers
không có phương pháp "foo", vì vậy tôi đoán tôi cần một số cách loại bỏ sự bao gồm đầu tiên kể từ chuỗi tổ tiên ...
Điều này đã nhận được một chút lâu vì vậy tôi đã ngừng đặt quá nhiều đoạn mã vào cuối, nhưng tôi thêm một phiên irb cho thấy hành vi của undef/remove và sau đó là một bao gồm.
"Đây là mã mà tôi không thực sự có quyền truy cập để sửa đổi": Bản vá khỉ không phải là một tùy chọn? –
Khỉ vá là một lựa chọn, loại - nhưng cách mô-đun chúng tôi đang thay thế công trình, Nó xác định các mô-đun và sau đó bao gồm chúng - nó khá phức tạp để tiêm mã một nơi nào đó vào chuỗi này để ngăn chặn bao gồm xảy ra. Mặc dù sau khi theo đuổi dòng này trong một thời gian, tôi bắt đầu nghiêng nhiều hơn theo hướng đó. – Glenjamin