2012-03-16 19 views
6

क्या बीच का अंतर है:अंतर "वर्ग एक, वर्ग बी" और "वर्ग एक :: बी '

class A 
    class B 
    end 
end 

और

class A 
end 

class A::B 
end 

अद्यतन: इन 2 दृष्टिकोण नहीं हैं बिल्कुल वैसा ही।

दूसरे दृष्टिकोण में, B में A में परिभाषित स्थिरांक तक पहुंच नहीं है।

इसके अलावा, जैसा कि मैथ्यू मोरेरा ने सही तरीके से कहा है, A को परिभाषित किया जाना चाहिए A::B परिभाषित किया जा सकता है।

अन्य अंतर क्या हैं?

उत्तर

8

रूबी में, मॉड्यूल और वर्गों Module और Class वर्गों के उदाहरण क्रमश: कर रहे हैं। वे निरंतर से उनके नाम प्राप्त करते हैं जिन्हें वे असाइन किए जाते हैं। जब आप लिखें:

class A::B 
    # ... 
end 

आप को प्रभावी ढंग से लिख रहे हैं:

A::B ||= Class.new do 
    # ... 
end 

कौन सा वैध निरंतर काम वाक्य रचना है, और मान लिया गया कि A लगातार ठीक से प्रारंभ कर दिया गया है और है कि यह एक को संदर्भित करता है Module या Class

उदाहरण के लिए, पर विचार कैसे वर्गों आमतौर पर परिभाषित कर रहे हैं:

class A 
    # ... 
end 

क्या प्रभावी ढंग से हो रहा है यह है:

Object::A ||= Class.new do 
    # ... 
end 

अब, जब आप लिखते हैं:

class A 
    class B 
    # ... 
    end 
end 

क्या वास्तव में ऐसा लगता है:

(Object::A ||= Class.new).class_eval do 
    (A::B ||= Class.new).class_eval do 
    # ... 
    end 
end 

यहाँ क्या हो रहा है, क्रम में है:

  1. एक नया Class उदाहरण, Object की A लगातार करने के लिए asssigned है जब तक कि यह पहले से ही प्रारंभ किया गया था।
  2. एक नया Class उदाहरण BA के स्थिरांक के साथ गठबंधन किया गया है, जब तक कि यह पहले से प्रारंभ नहीं हुआ था।

यह सब बाहरी वर्गों किसी भी भीतरी वर्गों को परिभाषित करने के लिए प्रयास करने से पहले के अस्तित्व को सुनिश्चित करता है।

दायरे में भी बदलाव आया है, जो आपको सीधे A के स्थिरांक तक पहुंचने की अनुमति देता है। की तुलना करें:

class A 
    MESSAGE = "I'm here!" 
end 

# Scope of Object 
class A::B 
    # Scope of B 
    puts MESSAGE # NameError: uninitialized constant A::B::MESSAGE 
end 

# Scope of Object 
class A 
    # Scope of A 
    class B 
    # Scope of B 
    puts MESSAGE # I'm here! 
    end 
end 

this blog post के अनुसार, रूबी कोर टीम "वर्तमान वर्ग" cref कहता है। दुर्भाग्य से, लेखक विस्तृत नहीं करता है, लेकिन जैसा कि वह नोट करता है, यह self के संदर्भ से अलग है।


As explained here, cref एक लिंक्ड सूची उस समय में कुछ बिंदु पर मॉड्यूल के घोंसले का प्रतिनिधित्व करता है।

वर्तमान crefdef, undef और alias के लिए के लिए निरंतर और वर्ग चर देखने और प्रयोग किया जाता है।


के रूप में दूसरों ने कहा है, वे एक ही बात को व्यक्त करने के कई तरीके हैं।

हालांकि, एक सूक्ष्म अंतर है। जब आप class A::B लिखते हैं, तो आप मानते हैं कि A कक्षा पहले से ही परिभाषित कर दी गई है। यदि ऐसा नहीं है, तो आपको NameError और B बिल्कुल परिभाषित नहीं किया जाएगा।

लेखन ठीक से नेस्ट मॉड्यूल:

class A 
    class B 
    end 
end 

A वर्ग B परिभाषित करने के लिए प्रयास करने से पहले मौजूद है सुनिश्चित करता है।

+1

मैंने यह दिखाने के लिए प्रश्न अपडेट किया है कि ये 2 दृष्टिकोण समान नहीं हैं। – nickh

+0

@nickh, आपको उत्तर शामिल करने के लिए प्रश्न को संपादित करने की आवश्यकता नहीं है। आपको उन उत्तरों को ऊपर उठाना चाहिए जो मददगार थे और जिसने निश्चित रूप से आपके प्रश्न का उत्तर दिया था उसे स्वीकार करें] (http://stackoverflow.com/faq#howtoask)। –

+0

बात यह है कि उनमें से कोई भी सवाल का जवाब नहीं दिया। सभी उत्तरों का कहना है कि 2 दृष्टिकोण समान हैं, जो वे नहीं हैं। – nickh

1

वे वही हैं। वे एक ही चीज़ लिखने के विभिन्न तरीके हैं। पहला यह लिखने का बेवकूफ तरीका है, लेकिन अक्सर कक्षा/मॉड्यूल बड़ा होने के बाद घोंसले का ट्रैक रखना मुश्किल हो जाता है। दूसरे तरीके से, आप उपस्थिति में घोंसले से बच सकते हैं।

+1

मैंने यह प्रश्न दिखाने के लिए प्रश्न अपडेट किया है कि ये 2 दृष्टिकोण समान नहीं हैं। – nickh

+0

@nickh मैंने सोचा कि ये मतभेद तुच्छ और पूर्वनिर्धारित हैं, इसलिए मैंने उनका उल्लेख नहीं किया। उन्हें इंगित करने से यह कहने से बहुत अलग नहीं है "ठीक है, स्ट्रिंग 'कक्षा बी' वर्ग ए :: बी' से अलग दिखता है, लेकिन आपने इसका उल्लेख नहीं किया। – sawa

3

एक ही बात कहने के दो अलग-अलग तरीके। यह बात यह है कि कक्षा बी एक आंतरिक या घोंसला वाली कक्षा है और केवल ए इंटरफेस के माध्यम से पहुंचा जा सकता है।

> class A 
.. def say 
.... "In A" 
....end 
.. 
.. class B 
.... def say 
...... "In B" 
......end 
....end 
..end 
=> nil 

> A.new.say 
=> "In A" 
> B.new.say 
=> #<NameError: uninitialized constant B> 
> A::B.new.s­ay 
=> "In B" 

बनाम

> class A 
.. def say 
.... "In A" 
....end 
..end 
=> nil 

> class A::B 
.. def say 
.... "In B" 
....end 
..end 
=> nil 

> A.new.say 
=> "In A" 
> B.new.say 
=> #<NameError: uninitialized constant B> 
> A::B.new.s­ay 
=> "In B" 
> 
+1

मैंने यह दिखाने के लिए प्रश्न अपडेट किया है कि ये 2 दृष्टिकोण समान नहीं हैं। – nickh

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