2010-08-15 14 views
5

मान लीजिए कि हमें पेड़ के लिए एक सामान्य वर्ग को परिभाषित करने की आवश्यकता है (या किसी समस्या को हल करने के लिए हमें कुछ अन्य वस्तुओं की आवश्यकता है)। चूंकि हमारी कक्षा संरचना काफी जटिल हो सकती है, इसलिए मैं इसकी परिभाषा के बाद कक्षा विधियों को परिभाषित करना पसंद करता हूं। हमारे सामान्य वर्ग BaseTree और हमारे विशिष्ट वर्गों Tree में से एकरूबी वर्ग विरासत और वृद्धिशील परिभाषा

class BaseTree 
    class BaseNode; end 
    class NodeA < BaseNode; end 
end 

class Container 
    class Tree < BaseTree; end 
end 

हैं वर्ग संरचना को परिभाषित करने के बाद, हम सभी नोड्स के लिए #initialize निर्धारित किया है।

class BaseTree::BaseNode 
    def initialize x 
    p x 
    end 
end 

हम इसे परीक्षण है, तो सब कुछ ठीक है,

Container::Tree::NodeA.new(1) 
# => 1 

लेकिन अगर उसके बाद हम निम्नलिखित तरीके से एक विधि जोड़ने

class Container::Tree::NodeA 
    def some_method; end 
end 

तो यह NodeA के बीच विरासत टूट जाता है और BaseNode !!

Container::Tree::NodeA.new(2) 
# ~> -:30:in `initialize': wrong number of arguments(1 for 0) (ArgumentError) 

आदेश इसे ठीक करने के लिए, हम यह स्पष्ट रूप से परिभाषित करने के लिए है

class Container 
    class Tree < BaseTree 
    class NodeA < BaseNode; end # explicit inheritance 
    end 
end 

class Container::Tree::NodeA 
    def some_method; end 
end 

या निम्नलिखित तरीके

class Container::Tree::NodeA < Container::Tree::BaseNode 
    def some_method; end 
end 

class Container::Tree::NodeA < BaseTree::BaseNode 
    def some_method; end 
end 

पिछले रास्ता केवल एक बार इस्तेमाल किए जाने की आवश्यकता द्वारा - पहले समय हम एक विधि जोड़ते हैं, और हम बाद की परिभाषाओं के लिए अभिभावक वर्ग को छोड़ सकते हैं

class Container::Tree::NodeA 
    def another_method; end 
end 

उसके बाद यह ठीक काम करता है, लेकिन मुझे यह काफी बोझिल लगता है, खासकर यदि बहुत सारे पेड़ के प्रकार और कई अलग-अलग नोड्स हैं।

क्या ऐसी परिभाषाओं को करने का एक और शानदार तरीका है?

+0

शायद यह देखने के लिए कि पिंग कोर – rogerdpack

+0

मुझे समझ में नहीं आता कि आप नेमस्पेस के लिए कक्षाओं का उपयोग क्यों करते हैं, तो मुझे वहां मॉड्यूल होने की उम्मीद होगी। ऐसा लगता है कि बाइंडिंग का एक मेल नहीं है, लेकिन मुझे समस्या को समझ में नहीं आता है। वैसे, आप वर्ग विधियों को परिभाषित नहीं करते हैं, आप उदाहरण विधियों को परिभाषित करते हैं। – mliebelt

उत्तर

2

जिस तरह से आपको रूबी में कोड व्यवस्थित करना चाहिए, वह नामस्थान के रूप में मॉड्यूल का उपयोग करके, और उप-वर्गों और विरासत व्यवहार के लिए वर्ग विरासत का उपयोग कर रहा है। मुझे नहीं लगता कि रूबी नेमस्पेस विरासत का समर्थन करता है (जो मूल रूप से आप बेस ट्री से ट्री विरासत कहकर कर रहे हैं और नोडा को ट्री :: नोडे के रूप में संदर्भित करते हुए) कर रहे हैं, और इसलिए यह अजीब किनारा मामला है जहां बाइंडिंग सही नहीं हैं।

किसी भी मामले में, मुझे नहीं लगता कि एक वैध परिदृश्य है जिसमें आपको कोड को व्यवस्थित करने की आवश्यकता है। 'उचित' तरीका नामस्थान को परिभाषित मॉड्यूल के माध्यम से और वर्ग परिभाषित व्यवहार के माध्यम से आयोजित किया जाएगा।

तो, जिस तरह से एक के रूप में एक पेड़ को परिभाषित या तो बस नामस्थान के बिना, केवल कक्षाओं की घोषणा कर रहा है, या एक नाम स्थान है कि उन्हें कक्षाओं से अलग करता है कि एक नाम टकराव मेरे साथ से जाना होगा:

module UserInterface 
    class Container; end 

    class Tree; end 

    class BaseTree < Tree; end 

    class BaseNode; end 

    class NodeA < BaseNode; end 
end 


module DataStructures 
    class Tree; end 

    class RedBlackTree < Tree; end 
end 
संबंधित मुद्दे