2012-03-03 6 views
6

में इंस्टेंस वैरिएबल प्रारंभिकरण मुझे लगता है कि रूबी में इंस्टेंस चर को समझने की कोशिश करते समय मैं थोड़ा पागल हो रहा हूं। मेरा एकमात्र उद्देश्य यह सुनिश्चित करना है कि किसी दिए गए वर्ग के लिए बनाए गए प्रत्येक ऑब्जेक्ट में एक पूर्व निर्धारित मान के साथ बिना किसी वर्ग के initialize विधि लिखने के साथ एक चर है। की तरह कुछ:रूबी

class Test 

    @my = [] 

    attr_accessor :my 

end 
t = Test.new 
t.my # I want [] but this shows nil 

यह initialize बिना छुए इस लक्ष्य को हासिल करना संभव है? धन्यवाद।

संपादित करें: स्पष्ट करने के लिए, मैं कोड है जो अर्थ में attr_accessor के समान निष्पादित किया जाएगा कि यह वर्ग है जिसमें यह क्रियान्वित किया जाता है करने के लिए एक उदाहरण चर जोड़ देंगे से कुछ टुकड़ा लिख ​​रहा हूँ। अगर मैं अपना खुद का initialize लिखता हूं, तो मैं उपयोगकर्ता द्वारा लिखे गए एक को क्लॉबरिंग कर दूंगा।

उत्तर

11

आप जो कर रहे हैं वह वर्ग स्तर पर एक आवृत्ति चर परिभाषित कर रहा है (चूंकि वर्ग कक्षा वर्ग के उदाहरण हैं, यह ठीक काम करता है)।

और नहीं, प्रारंभ करने के आसपास कोई रास्ता नहीं है।

संपादित करें: आपके संपादन में आपको थोड़ा गलतफहमी है। attr_accessor कक्षा में एक आवृत्ति चर नहीं जोड़ता है। यह क्या करता है, सचमुच, (my के अपने उदाहरण का प्रयोग करके) यह है:

def my; @my; end 
def my=(value); @my = value; end 

यह सक्रिय रूप से/नहीं बना है किसी भी उदाहरण चर इनिशिएलाइज़, यह सिर्फ दो तरीकों को परिभाषित करता है। और define_method का उपयोग कर आप अपनी खुद की कक्षा विधि लिख सकते हैं जो समान चीजें करता है।

संपादित करें 2:

आगे कैसे एक ऐसी पद्धति लिखते थे उदाहरण देकर स्पष्ट करने के लिए:

class Module 
    def array_attr_accessor(name) 
    define_method(name) do 
     if instance_variable_defined?("@#{name}") 
     instance_variable_get("@#{name}") 
     else 
     instance_variable_set("@#{name}", []) 
     end 
    end 

    define_method("#{name}=") do |val| 
     instance_variable_set("@#{name}", val) 
    end 
    end 
end 


class Test 
    array_attr_accessor :my 
end 

t = Test.new 
t.my # => [] 
t.my = [1,2,3] 
t.my # => [1, 2, 3] 
+0

कृपया संपादित करें देखें। – sasuke

+0

मेरा बुरा, मैंने कहा "इसी तरह"। असल में, इस नई विधि, जिसे किसी भी वर्ग में जोड़ा गया है, जैसे 'attr_accessor', उस वर्ग के लिए बनाए गए सभी ऑब्जेक्ट्स में एक नया इंस्टेंस वैरिएबल जोड़ देगा। – sasuke

+1

आह, जैसा कि मैंने सोचा था, मैं इस तरह के गुणों के लिए डिफ़ॉल्ट 'attr_reader' पर भरोसा नहीं कर सकता। सिर्फ एक आखिरी सवाल: रुबी में जावा इत्यादि के तरीके के साथ इंस्टेंस वैरिएबल को शुरू करने का कोई तरीका नहीं है? – sasuke

0

मुझे नहीं लगता कि यह है, कि आपको ऐसा क्यों बस एक त्वरित इनिशियलाइज़ लिखने के लिए संकोच कर रहे हैं तरीका?

2
# as instance variable without initialize 
class Test1 
    def my; @my ||= [] end 

    attr_writer :my 
end 

t = Test1.new 
t.my 


# as class instance variable 
class Test2 
    @my = [] 

    class << self; attr_accessor :my end 
end 

Test2.my 
+1

+1, एएसपी। एक्सेसर्स के साथ कक्षा-स्तर चर के लिए। 'प्रारंभिक' के बिना चेतावनी पुनः आवृत्ति चर यह है कि यदि आप 't.my = nil' सेट करने का प्रयास करते हैं, तो' t.my' '~] '' = 'के कारण वापस लौटाएगा, जो अप्रत्याशित है और हो सकता है वांछित होना; मेथिंक बेहतर है कि 'प्रारंभिक' से बचें। – mklement0