2010-03-09 11 views
5

How can I reverse ruby's include function का पालन करने के रूप में, जिसका उत्तर दिया गया था लेकिन असली समस्या का मेरा सरलीकरण यह नहीं हुआ कि समाधान लागू नहीं था।रूबी के माध्यम से शामिल मॉड्यूल को "प्रतिस्थापित" कैसे किया जा सकता है फ़ंक्शन

मैं अब इस के साथ सामना कर रहा हूँ (नाम पहचान की रक्षा करने के लिए बदल गया है!):

module OldFormHelpers 
    def foo 
    puts "foo" 
    end 
    def bar 
    puts "bar" 
    end 
end 

module Helpers 
    include OldFormHelpers 
end 

यह मैं देता है:

Helpers.instance_methods 
=> ["bar", "foo"] 
Helpers.ancestors 
=> [Helpers, OldFormHelpers] 

इस कोड है कि मैं वास्तव में करने के लिए पहुँच नहीं है है फोर्किंग के बिना संशोधित करें।

मैं क्या करना चाहता हूं एक नया मॉड्यूल बनाना है;

module BetterFormHelpers 
    def foo 
    puts "better foo" 
    end 
end 

यह OldFormHelpers से व्यवहार को दूर करने, और फिर BetterFormHelpers

पिछले समाधान से नई सामग्री में जोड़ने की जरूरत है ताकि तरह undef_method उपयोग करने के लिए किया गया था:

Helpers.module_eval do 
    OldFormHelpers.instance_methods do |m| 
    undef_method(m) 
    end 
end 

हालांकि, सहित के बाद BetterFormHelpers, Helpers.instance_methods में "foo" नहीं है। इस का कारण यह मुझसे कहता है Helpers "foo" विधि नहीं है कि कम से http://ruby-doc.org/core/classes/Module.src/M001652.html

remove_method का उपयोग करते हुए समझाया गया है, इसलिए मुझे लगता है मैं पूर्वजों श्रृंखला से पहले शामिल किए जाने को हटाने की किसी तरह की जरूरत है ...

यह थोड़ा लंबा हो रहा था इसलिए मैंने अंत में इतने सारे स्निपेट डालने से रोक दिया, लेकिन मैं एक इरब सत्र जोड़ता हूं जो अनावृत/निकालने का व्यवहार दिखाता है और फिर एक शामिल करता है।

+0

"यह कोड है कि मुझे वास्तव में संशोधित करने की पहुंच नहीं है": क्या बंदर-पैचिंग एक विकल्प नहीं है? –

+0

बंदर पैचिंग एक विकल्प है, लेकिन जिस तरह से मॉड्यूल हम काम बदल रहे हैं, यह मॉड्यूल को परिभाषित करता है और फिर उन्हें शामिल करता है - इसमें शामिल होने से रोकने के लिए इस श्रृंखला में कोड को इंजेक्ट करना काफी मुश्किल है। हालांकि थोड़ी देर के लिए इस लाइन का पीछा करने के बाद, मैं उस दिशा में अधिक दुबला होना शुरू कर रहा हूं। – Glenjamin

उत्तर

2

क्या आप केवल उन्हीं विधियों को परिभाषित नहीं कर सकते हैं जिन्हें ओवरराइट नहीं किया जाएगा?

Helpers.module_eval do 
    (OldFormHelpers.instance_methods - BetterFormHelpers.instance_methods).each do |m| 
    undef_method(m) 
    end 
end 

(उत्तरार्द्ध शामिल मॉड्यूल पहले की खोज की जाएगी ताकि कोई OldFormHelpers विधि BetterFormHelpers भी यह परिभाषित करता है, तो निष्पादित किया जाएगा।)

आप गतिशील OldFormHelpers मॉड्यूल के आगे तरीकों अधिलेखित करना चाहते हैं अगर, हालांकि, समस्या वही बना है।

संबंधित मुद्दे

 संबंधित मुद्दे