2013-02-06 56 views
6

मैं शेफ विशेषताओं में मेरी सेवा के लिए एक कॉन्फ़िगरेशन उत्पन्न कर रहा हूं। हालांकि, किसी बिंदु पर, मुझे विशेषता मैश को एक साधारण रूबी हैश में बदलना होगा। यह शेफ 10:शेफ 11: रूबी हैश में गुणों को बदलने का कोई तरीका?

node.myapp.config.to_hash 

हालांकि, शेफ 11 से शुरू होने पर यह ठीक काम नहीं करता है, यह काम नहीं करता है। केवल विशेषता का शीर्ष-स्तर एक हैश में परिवर्तित हो जाता है, उसके बाद घोंसला वाले मान अपरिवर्तनीय मैश ऑब्जेक्ट्स शेष होते हैं। उन्हें संशोधित करना इस तरह त्रुटियों की ओर जाता है:

बावर्ची :: अपवाद :: ImmutableAttributeModification ---------------------------- -------------------- नोड विशेषताएँ केवल पढ़ने के लिए होती हैं जब आप निर्दिष्ट नहीं करते कि कौन सा प्राथमिकता स्तर सेट करना है। करने के लिए ' `node.default [" कुंजी "] =" मूल्य "की तरह

एक विशेषता उपयोग कोड सेट मैं तरीकों से काम नहीं करते इस समस्या के समाधान प्राप्त करने के लिए के एक झुंड की कोशिश की है:

node.myapp.config.dup.to_hash 
JSON.parse(node.myapp.config.to_json) 

जो यह बहुत अच्छा काम करना चाहिए की तरह है, में परिणाम लगता है json पार्स करने हैक,:

JSON::ParserError 
unexpected token at '"#<Chef::Node::Attribute:0x000000020eee88>"' 

कोई वास्तविक विश्वसनीय तरीका प्रत्येक रसोई की किताब में एक नेस्टेड पार्स समारोह सहित, एक सरल करने के लिए गुण परिवर्तित करने के लिए की कमी है, सामान्य, जाओ ओड पुरानी रूबी हैश?

+1

आप हैश आवश्यकता क्यों है? –

+0

मुझे इसकी आवश्यकता नहीं है - मैं किसी भी समय मुझे छोड़ सकता हूं! लेकिन गंभीरता से, मैं कई अलग-अलग विशेषताओं में से एक कॉन्फ़िगरेशन फ़ाइल बना रहा हूं, और मुझे उन्हें कॉन्फ़िगरेशन फ़ाइल में लिखने से पहले उन्हें संशोधित करने की आवश्यकता है। गुणों को हैश में परिवर्तित करना, उन्हें उत्परिवर्तित करना और फिर हैश का उपयोग करना वास्तव में सहायक है। –

उत्तर

7

दोनों यहाँ और opscode महाराज मेलिंग सूची पर जवाब में से एक शानदार कमी के बाद, मैं निम्नलिखित हैक का उपयोग कर समाप्त हो गया:

class Chef 
    class Node 
    class ImmutableMash 
     def to_hash 
     h = {} 
     self.each do |k,v| 
      if v.respond_to?('to_hash') 
      h[k] = v.to_hash 
      else 
      h[k] = v 
      end 
     end 
     return h 
     end 
    end 
    end 
end 

मैं पुस्तकालयों मेरी रसोई की किताब में निर्देशिका में डाल; अब मैं दोनों chef 10 में attribute.to_hash का उपयोग कर सकता हूं (जो पहले से ही ठीक से काम करता है और जो इस बंदर-पैच द्वारा अप्रभावित है) और शेफ 11. मैंने इसे ओपस्कोड के लिए एक बग के रूप में भी बताया है:

यदि आप ' टी अपने शेफ को बंदर-पैच करना चाहते हैं, इस मुद्दे पर बात करें: http://tickets.opscode.com/browse/CHEF-3857

+0

बीटीडब्लू यह काम नहीं करता है अगर आपके हैश में एरे – David

+1

एरे के साथ काम करने वाले संस्करण के साथ अपडेट किया गया है। – David

+0

मैं डेविड के सुझाए गए संपादन को स्वीकार नहीं कर सका, इसलिए मैंने इसमें से एक गलती की: https: //gist.github।कॉम/igor47/59 9 7028; मुझे नेस्टेड सरणी के मुद्दे को दूर नहीं करना पड़ा, लेकिन यह निश्चित रूप से एक समस्या होगी। –

-1

उपर्युक्त उत्तर थोड़ा अनावश्यक है। तुम बस ऐसा कर सकते हैं:

json = node[:whatever][:whatever].to_hash.to_json 
JSON.parse(json) 
+0

यह सच नहीं है; क्योंकि 'to_hash' उथला है, आप 'इमटेबल मैश' ऑब्जेक्ट्स के मानों के रूप में समाप्त हो जाएंगे। 'to_json' फ़ंक्शन नहीं जानता कि इस तरह की ऑब्जेक्ट को कैसे संभालना है और बार्फ़ होगा। यह इस सवाल का पूरा बिंदु है। –

2

मैं एक ही समस्या थी और बहुत चारों ओर हैकिंग के बाद इस के साथ आया था:

json_string = node[:attr_tree].inspect.gsub(/\=\>/,':') 
my_hash = JSON.parse(json_string, {:symbolize_names => true}) 

निरीक्षण गहरी पार्स कि अन्य तरीकों से याद आ रही है प्रस्तावित करता है और मैं एक हैश के साथ समाप्त होता है जिसे मैं आवश्यकतानुसार संशोधित और पास कर सकता हूं।

+0

एक 1-लाइनर के लिए, '' 'JSON.parse (हैश.to_json, symbolize_names: true)' ''। काफी बुराई, लेकिन अधिक जटिल समाधानों से बनाए रखने के लिए बहुत आसान है। – Afforess

1

मुझे आशा है कि मैं पार्टी के लिए भी देर नहीं हुई हूँ, लेकिन एक खाली हैश के साथ नोड वस्तु विलय मेरे लिए यह किया:

chef (12.6.0)> {}.merge(node).class 
=> Hash