Come follow-up a How can I reverse ruby's include function, a cui è stata data una risposta soddisfacente ma la mia semplificazione del problema reale ha significato che la soluzione non era applicabile.Come "sostituire" un modulo incluso tramite ruby include la funzione
Ora sto di fronte a questo (i nomi cambiati per proteggere le identità!):
module OldFormHelpers
def foo
puts "foo"
end
def bar
puts "bar"
end
end
module Helpers
include OldFormHelpers
end
Questo mi dà:
Helpers.instance_methods
=> ["bar", "foo"]
Helpers.ancestors
=> [Helpers, OldFormHelpers]
Questo è il codice che in realtà non hanno accesso alle modificare, senza biforcazione.
Quello che voglio fare è creare un nuovo modulo;
module BetterFormHelpers
def foo
puts "better foo"
end
end
Questo deve per rimuovere i comportamenti da OldFormHelpers
, e quindi aggiungere il nuovo roba da BetterFormHelpers
La soluzione precedente era di utilizzare undef_method
in questo modo:
Helpers.module_eval do
OldFormHelpers.instance_methods do |m|
undef_method(m)
end
end
Tuttavia, dopo aver incluso BetterFormHelpers
, Helpers.instance_methods non contiene "pippo". La ragione di questo è spiegato in http://ruby-doc.org/core/classes/Module.src/M001652.html
Utilizzando remove_method
mi dice che Helpers
non si ha il metodo di "foo", quindi credo che ho bisogno di un modo per rimuovere il primo inserimento dalla catena antenati ...
Questo è stato un po 'lungo, quindi ho smesso di inserire così tanti frammenti verso la fine, ma aggiungo una sessione irb che mostra il comportamento di undef/remove e quindi un include.
"Questo è un codice che non ho realmente accesso alla modifica": la patch delle scimmie non è un'opzione? –
Le patch per le scimmie sono un'opzione, una specie di - ma il modo in cui il modulo che stiamo sostituendo funziona, definisce i moduli e quindi li include - è piuttosto difficile inserire il codice da qualche parte in questa catena per fermare l'evento. Anche se dopo aver seguito questa linea per un po ', sto iniziando ad orientarmi di più in quella direzione. – Glenjamin