ठीक है, इसलिए मैं डुप्लिकेशंस को हटाने के प्रयास में अपने छोटे रेल ऐप में अपना कोड दोबारा कर रहा हूं, और सामान्य रूप से मेरे जीवन को आसान बना देता हूं (जैसा कि मुझे एक आसान जीवन पसंद है)। इस रिफैक्टरिंग का एक हिस्सा, कोड को स्थानांतरित करना है जो मेरे दो मॉडलों के लिए एक मॉड्यूल में आम है जिसमें मैं इसे शामिल कर सकता हूं।रूबी मिश्रक और सुपर विधियों को बुलाएं
अब तक तो अच्छा। ऐसा लगता है कि यह काम करने जा रहा है, लेकिन मैंने अभी एक समस्या को मारा है कि मुझे यकीन नहीं है कि कैसे घूमना है। मॉड्यूल (जिसे मैंने भेजने योग्य कहा है), सिर्फ वह कोड होगा जो फ़ैक्सिंग, ई-मेलिंग या दस्तावेज़ के पीडीएफ को प्रिंट करता है। इसलिए, उदाहरण के लिए, मेरे पास एक खरीद आदेश है, और मेरे पास आंतरिक बिक्री आदेश हैं (कल्पनात्मक रूप से आईएसओ को संक्षेप में)।
समस्या मैं मारा गया है, कि मैं चाहता हूँ कुछ चर initialised (जो लोग सही लिखें नहीं है के लिए प्रारंभ: पी), के बाद वस्तु भरी हुई है तो मैं after_initialize हुक का उपयोग कर रहा है। कोई समस्या नहीं ... जब तक मैं कुछ और मिश्रण जोड़ने शुरू नहीं करता।
समस्या मेरे पास है, मैं एक after_initialize
मेरी mixins में से किसी एक में हो सकता है है, इसलिए मुझे यकीन है कि अन्य mixin after_initialize
कॉल कहा जाता हो बनाने के लिए शुरू में एक सुपर कॉल शामिल करने की ज़रूरत । जो महान है, जब तक कि मैं सुपर कॉलिंग समाप्त नहीं करता और मुझे कोई त्रुटि मिलती है क्योंकि कॉल करने के लिए कोई सुपर नहीं है।
यहाँ मामले में एक छोटे से उदाहरण दिया गया है, मैं काफी भ्रमित नहीं किए गए हैं:
class Iso < ActiveRecord::Base
include Shared::TracksSerialNumberExtension
include Shared::OrderLines
extend Shared::Filtered
include Sendable::Model
validates_presence_of :customer
validates_associated :lines
owned_by :customer
order_lines :despatched # Mixin
tracks_serial_numbers :items # Mixin
sendable :customer # Mixin
attr_accessor :address
def initialize(params = nil)
super
self.created_at ||= Time.now.to_date
end
end
तो, अगर mixins में से हर एक एक after_initialize फोन है, एक सुपर कॉल के साथ, मैं कैसे रोक सकता कि अंतिम सुपर त्रुटि उठाने से कॉल करें? मैं यह कैसे जांच सकता हूं कि इसे कॉल करने से पहले सुपर विधि मौजूद है?
downvoted क्योंकि यह एक सामान्य समाधान नहीं है:
यहाँ एक उदाहरण है। मुद्दा यह है कि आप नहीं जानते कि सुपर मौजूद है या नहीं, इसलिए ActiveRecord :: बेस # को बंद करने के बाद ActiveRecord :: बेस # अस्तित्व में प्रारंभ करने के बाद, आप एक बिंदु बनाते हैं जहां आपका कोड टूट जाएगा यदि ActiveRecord आधार # after_initialize जोड़ता है, या इसकी धैर्य बदल जाती है ; यदि यह परिभाषित किया गया है तो सशर्त रूप से इसे कॉल करने के लिए यह बहुत ही कठिन है। – yaauie
@yaauie - निश्चित रूप से, अगर मैं monkeypatch से पहले विधियों को शामिल कर सकता हूं, तो मैं 'raise' ओह नहीं कर सकता था? (: बाद में शुरूआत करें), लेकिन यह उदाहरण को समझने में कठिन होगा ... पकड़ा जाना इतना आसान है सभी किनारे के मामलों का विवरण देने में कि वास्तविक पाठ यहां (केवल मूल विधि पैच करें) शोर में खो जाएगा। –
बंदरगाह एक सामान्य समाधान नहीं है और सामान्य रूप से - प्रोत्साहित किया जाना चाहिए। एक उत्तर जिसमें एक-ऑफ मोनीकीपैच शामिल है जो * काम * हो सकता है, अनावश्यक रूप से जटिल और नाजुक कोड की ओर जाता है, खासकर यदि आपके पास विरासत श्रृंखला तक सभी तरह का नियंत्रण नहीं है। – yaauie