2011-09-23 15 views
18

उत्पन्न करें मैं एक हैश (नेस्टेड हैश के साथ) से attr_reader उत्पन्न करने की कोशिश कर रहा हूं ताकि यह example_variable सृजन को स्वचालित रूप से दर्पण कर सके।रूबी: गतिशील रूप से attribute_accessor

data = {:@datetime => '2011-11-23', :@duration => '90', :@class => {:@price => '£7', :@level => 'all'}} 


class Event 
#attr_reader :datetime, :duration, :class, :price, :level 
    def init(data, recursion) 
    data.each do |name, value| 
    if value.is_a? Hash 
     init(value, recursion+1) 
    else 
     instance_variable_set(name, value) 
     #bit missing: attr_accessor name.to_sym 
    end 
    end 
end 

लेकिन मैं बाहर कि :(

उत्तर

33

आप पर (निजी) वर्ग विधि attr_accessor कॉल करने की आवश्यकता करने के लिए एक रास्ता नहीं मिल रहा है:

यहाँ मैं अब तक किया है Event वर्ग:

:

self.class.send(:attr_accessor, name) 

मैं तुम्हें इस लाइन पर @ जोड़ने की सलाह देते

instance_variable_set("@#{name}", value) 

और हैश में उनका उपयोग न करें।

data = {:datetime => '2011-11-23', :duration => '90', :class => {:price => '£7', :level => 'all'}} 
+0

आप मेरे नए सबसे अच्छे दोस्त हैं !!!! यह सिर्फ काम करता है और इतना आसान है ... रूबी जादू है :) और आप एक स्टार हैं :) (मुझे खुशी है क्योंकि मैंने थोड़ी देर की तलाश की थी) –

+0

बस एक त्वरित सवाल है, क्या नाम का प्रीपेड करने का कोई तरीका है एक्सेसर नाम के लिए हैश है, ताकि मैं my_class.class.price, या ऐसा कुछ कह सकूं? –

+0

सबसे पहले, 'कक्षा' एक आरक्षित कीवर्ड है, इसका उपयोग न करें। आपकी टिप्पणी में आपका दूसरा प्रश्न इस विशेष प्रश्न के दायरे से बाहर चला गया है। हो सकता है कि आप एक नया प्रश्न शुरू करना चाहें, क्योंकि यह रिकर्सन से संबंधित है और ऐसे में, विशेषता एक्सेसर्स के साथ नहीं। (पीएस, सबसे अच्छा जवाब स्वीकार करना न भूलें) – rdvdijk

1

attr_accessor एक वर्ग विधि है और इस तरह की जरूरत के रूप में वर्ग पर लागू किया जाना है। यह एक निजी विधि भी है, इसलिए आपको इसे उस संदर्भ में आमंत्रित करने की आवश्यकता है जिसमें कक्षा वस्तु self है।

एक उदाहरण के रूप:

class C 
    def foo 
    self.class.instance_eval do 
     attr_accessor :baz 
    end 
    end 
end 

C का उदाहरण बनाकर और, कि उदाहरण है कि उदाहरण पर foo कॉल करने के बाद - और सभी भावी अवसरों - तरीकों baz और baz= शामिल होंगे।

3

आप इस को हल करने के मेटा-जादू का एक सा कर सकता है, method_missing का उपयोग कर:

class Event 
    def method_missing(method_name, *args, &block) 
    if instance_variable_names.include? "@#{method_name}" 
     instance_variable_get "@#{method_name}" 
    else 
     super 
    end 
    end 
end 

क्या ऐसा करेंगे, तो वस्तु उन वेरिएबल नहीं है, पहुँच object.variable वाक्य रचना के माध्यम से उदाहरण चर आपत्ति करने की अनुमति है परिभाषित किया गया है, पूरे वर्ग को attr_accessor के माध्यम से संशोधित करने के बिना।

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