2012-01-18 16 views
11

मैंने सोचा कि यह प्रश्न (How to do attr_accessor_with_default in ruby?) ने मेरे प्रश्न का उत्तर दिया, लेकिन मैं ActiveRecord का उपयोग नहीं कर रहा हूं और after_initialize इस पर निर्भर करता है।ActiveRecord के बिना किसी संपत्ति पर डिफ़ॉल्ट मान सेट करने का सबसे अच्छा तरीका है?

attr_accessor के लिए डिफ़ॉल्ट मान लागू करने के लिए रूबी सर्वोत्तम अभ्यास क्या है? this इसके बारे में दस्तावेज़ीकरण की सबसे नज़दीकी चीज है? क्या मुझे attr_accessor का उपयोग बंद करना चाहिए क्योंकि यह निजी है?

+0

आप तब तक नहीं चाहते हैं जब तक आप सुनिश्चित न हों कि आप क्यों करते हैं। कक्षा-स्तर के आवृत्ति चर (नीचे मेरा उत्तर देखें) बाल अधिक काम हैं, लेकिन उप-वर्गों के संबंध में कम आश्चर्य है। आप वास्तव में क्या करने की कोशिश कर रहे हैं? – Phrogz

+0

मुझे लगता है कि अब क्या हो रहा है, मैं संपादन को हटाने वाला हूं। मैं गलत धारणा के तहत था कि attr_accessor एक रेल चीज थी। – jcollum

उत्तर

20
class Foo 
    # class-level instance variable 

    # setting initial value (optional) 
    @class_var = 42 

    # making getter/setter methods on the class itself 
    class << self 
    attr_accessor :class_var 
    end 

    # instance-level variable getter/setter methods 
    attr_accessor :inst_var 
    def initialize 
    # setting initial value (optional) 
    @inst_var = 17 
    end 
end 

p Foo.class_var 
#=> 42 
Foo.class_var = 99 
p Foo.class_var 
#=> 99 

f1 = Foo.new 
f2 = Foo.new 
f2.inst_var = 1 
p [f1.inst_var, f2.inst_var] 
#=> [17,1] 
+2

उत्कृष्ट जवाब, धन्यवाद। 'Attr_accessor' निजी होने के बारे में क्या? यह सी # से अनोखा आ रहा है कि रूबी मुझे ऐसी चीजों का उपयोग करने देता है जो इस तरह निजी हैं। यह निजी की तरह है सिर्फ एक सुझाव है। अजीब। – jcollum

+0

यह निजी तरीके नहीं बनाता है, लेकिन यह निजी है: इसका उद्देश्य केवल तभी उपयोग किया जाना चाहिए जब आप कक्षा खोलें। आप बाद में कक्षा को फिर से खोल सकते हैं, या 'Foo.instance_eval {attar_accessor: bar}' कर सकते हैं या ['__send__'] का उपयोग कर सकते हैं (http://www.ruby-doc.org/core-1.9.3/BasicObject। एचटीएमएल # विधि-i -__ send__) जो प्रतिबंधों को छोड़ देता है। हां, रूबी आपको अगर चाहें तो खेलने के लिए तेज चाकू देता है। – Phrogz

+0

हम्म, बिल्कुल वही नहीं जो मुझे चाहिए। जब मैं '@debug = false कक्षा << स्वयं attr_accessor: अंत 'डीबग करें और उस वर्ग से प्राप्त कक्षा का एक उदाहरण बनाएं, डीबग संपत्ति शून्य है। मैं वहां 'झूठी' की उम्मीद कर रहा हूं, क्योंकि इसका डिफ़ॉल्ट मान है। खराब प्रारूपण के लिए खेद है। – jcollum

1

@Phrogz ने एक अच्छा समाधान दिया, लेकिन आपको इसके बारे में और जानना चाहिए।

यहां आप class-level instance variable बनाते हैं, जो वास्तव में एक वर्ग चर नहीं है, लेकिन कौन परवाह करता है, क्योंकि एक ही नाम के साथ एक वास्तविक वर्ग चर प्रारंभ करने के बाद, आप एक पुराना संदर्भ खो देते हैं।

fakeness का निरीक्षण करने के लिए, ऊपर दिए गए कोड का उपयोग करें, लेकिन एक सरणी के साथ:

class Foo 
    @class_var = [42] 
    class << self 
    attr_accessor :class_var 
    end 
end 
b = [Foo.class_var] 
Foo.class_var = 69 
p b # still [[42]] 

और आप एक समस्या पाने के लिए जा रहे हैं, जब @@ जो एक वास्तविक वर्ग के लिए चाहिए था के माध्यम से चर प्राप्त करने की कोशिश चर।

class Bar 
    @class_var = [42] 
    class << self 
    attr_accessor :class_var 
    end 
    def biz 
    self.class.class_var 
    end 
    def baz 
    @@class_var 
    end 
end 
p Bar.new.biz # self.class. is kinda a way to emulate the reference from outside 
p Bar.new.baz # and exception, because you don't really have a class variable defined yet! 
संबंधित मुद्दे