2016-01-14 7 views
6

मेरे पास एक साधारण वर्ग है, प्रारंभ में, एक और आठ पैरामीटर के बीच होता है। यह बाद में उपयोग करने के लिए इन तक पहुंचकर्ता सेट करता है। रूबोकॉप मुझे एबीसी के लिए बहुत अधिक गिरफ्तार करने की कोशिश कर रहा है, लेकिन मुझे यकीन नहीं है कि मेरे द्वारा किए गए कार्यों में वास्तव में कुछ गलत है या नहीं। क्या यह एक ऐसा मामला है जहां मैं अपने प्रारंभिक पर निरीक्षण को अक्षम करता हूं?असाइनमेंट शाखा की स्थिति बहुत अधिक

class Foo 
    attr_accessor :one, :two, :three, :four 
    attr_accessor :five, :six, :seven, :eight 

    def initialize(p={}) 
    @one = p[:one] if p[:one].present? 
    # ... 
    @eight = p[:eight] if p[:eight].present? 
    end 
end 

मेरे आकार को कम करने इनिशियलाइज़ पर मेरे सभी attr_accessors के माध्यम से पुनरावृत्ति की तरह कुछ करने के लिए हो सकता है, अगर वहाँ एक इसी प्रतीक होता है में के माध्यम से पारित है, देखने और यदि ऐसा है तो यह सौंपने के बारे में केवल सोचा।

class Foo 
    attr_accessor :one, :two, :three, :four 
    attr_accessor :five, :six, :seven, :eight 

    def initialize(p={}) 
    instance_variables.each do |variable| 
     send("@#{variable}") = p["#{send(variable)}".to_sym] if p["#{send(variable)}".to_sym].present? 
    end 
    end 
end 

लेकिन यह कमजोर लगता है। Hash#fetch विधि के लिए

class Foo 
    %i(one two three four five six seven eight).each { |attribute| attr_accessor attribute } 

    def initialize(p = {}) 
    p.keys.each { |k| instance_variable_set("@#{k}", p.fetch(k, nil)) } 
    end 
end 

चेक आउट:

उत्तर

4

यहां कुछ ऐसे तरीके प्राप्त करने के लिए आपको बस इतना करना कोशिश कर रहे हैं में से एक है।

आप भी इसका इस्तेमाल सिर्फ p चर का मुख्य-मान जोड़ों का उपयोग करने के कर सकते हैं यदि आप के बजाय 8 चर एक (@p)


संपादित

बस से बाहर के साथ जाने का निर्णय जिज्ञासा इस संस्करण में लिखा था (कुछ मेटा प्रोग्रामिंग प्रयोग किया जाता) - यह गतिशील रूप से जोड़ा उदाहरण चर के लिए attr_accessor जोड़ देगा:

class Foo 
    def initialize(p = {}) 
    p.keys.each do |k| 
     instance_variable_set("@#{k}", p.fetch(k, nil)) 
     self.class.__send__(:attr_accessor, k) 
    end 
    end 
end 

क्या हो रहा है, क्या हम initialize विधि तर्क (हैश p) प्रदान करते हैं, इसकी चाबियां प्राप्त करें और उनमें से आवृत्ति चर बनाएं, प्रत्येक चर को कुंजी के अनुरूप मान के साथ असाइन करें। फिर हम प्रत्येक कुंजी के लिए attr_accessor परिभाषित कर रहे हैं।

a = Foo.new(a: 2, b: 3) 
#=> #<Foo:0x00000002d63ad8 @a=2, @b=3> 
+0

ऐसा लगता है कि मैं जो सोच रहा था उसके समान एक पुलिस हो सकता है। जानबूझ का मजाक। जबकि मैं मानता हूं कि यह समस्या को हल करने का एक तरीका है, क्या कोई संदर्भ है जो आप मुझे इंगित कर सकते हैं ताकि मैं और अधिक पढ़ सकूं कि यह 'सही' तरीका क्यों है? प्रतिउत्तर हेतु समय लेने के लिए धन्यवाद! – CarlyL

+0

@ करलीएल सही तरीके से - रूबी बहुत लचीली भाषा है, इसलिए विभिन्न तरीकों से चीजें की जा सकती हैं। और अक्सर "सही तरीका" व्यक्तिगत वरीयताओं का मामला है। मुझे लगता है कि आप रूबी स्टाइल गाइड के माध्यम से पढ़ सकते हैं कि ** ** ** क्या करना है, लेकिन मुझे संदेह है कि कोई 100% सही होने का दावा करेगा :) –

+0

आप गुणों के नाम को जमे हुए सरणी में भी डाल सकते हैं, जैसे '' 'ATTR_NAMES =% i (एक दो तीन चार पांच छः सात आठ)। फ्रीज' '' निरंतर और कॉल '' 'attr_accessor (* ATTR_NAMES)' ' –

2

आपको उनमें से प्रत्येक को अलग-अलग चर के रूप में असाइन नहीं करना चाहिए। आपको इसे एक हैश के रूप में एक चर के रूप में सहेजना चाहिए, और जब आपको मूल्यों की आवश्यकता हो तो हैश तक पहुंचें। वास्तव में, आपके पास पहले से एक चर p प्रतीत होता है। तो इसे @p = p के रूप में रखें।

+0

जवाब देने के लिए समय निकालने के लिए धन्यवाद। दोनों प्रतिक्रियाएं कहती हैं कि मेरे पास सिर्फ एक attr_accessor पी हो सकता है जो हैश है, लेकिन यह मेरे लिए अजीब लगता है। क्या आपके पास कोई संदर्भ है जिसे मैं पढ़ सकता हूं कि यह सबसे अच्छा तरीका क्यों होगा? – CarlyL

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