मेरे पास एक धारावाहिक JSON स्ट्रिंग (वास्तव में शेफ भूमिका परिभाषा) है और इसमें एक json_class कुंजी है, जिससे रूबी JSON पार्सर इसे शेफ :: रोल ऑब्जेक्ट के रूप में मजबूर करने का प्रयास करता है। मैं पार्सर को इस कुंजी को अनदेखा कैसे कर सकता हूं और बस एक सामान्य हैश में बस deserialize कर सकते हैं?रूबी JSON पार्सर को json_class को अनदेखा कैसे करें?
उत्तर
मैं सिर्फ एक ही समस्या थी, और JSON मणि के स्रोत को पढ़ कर जवाब मिला - पार्स करने के लिए प्रयास करने से पहले बस को सेट किए बिना JSON.create_id:
JSON.create_id = nil
JSON.parse('{ "json_class": "Chef::Role" }').class => Hash
संपादित करें: ध्यान दें कि जब से मणि के संस्करण 1.7 (1.8.0 वर्तमान है क्योंकि मैं इस अद्यतन को टाइप करता हूं), उपर्युक्त हैक अब आवश्यक नहीं है। JSON#parse
अब json_class
को अनदेखा करता है, और JSON#load
का उपयोग अनमर्शलिंग डंप किए गए ऑब्जेक्ट्स के बजाय किया जाना चाहिए।
आप पार्सिंग से पहले स्ट्रिंग पर gsub
कर सकते हैं, और उस विशेष कुंजी को किसी और चीज़ में बदल सकते हैं।
JSON का नमूना पहले और बाद में दिखाने के बारे में कैसे?
"json_class" कुंजी यह इंगित करने के लिए है कि ऑब्जेक्ट जेसन को किस तरह से मार्शल किया जाना चाहिए। यह JSON.dump द्वारा जोड़ा गया है। JSON के नवीनतम संस्करणों में, JSON.parse
"json_class" को अनदेखा कर देगा, एक हैश के लिए गैर-मार्शलिंग। जबकि JSON.load
संकेतित वस्तु के लिए अन-मार्शल होगा (आपके मामले में, एक शेफ :: भूमिका)।
JSON.parse('{ "json_class": "Chef::Role" }').class => Hash
JSON.load('{ "json_class": "Chef::Role" }').class => Chef::Role
धन्यवाद अद्यतन के लिए, मैट। मैंने भविष्य में passersby के लिए प्रतिबिंबित करने के लिए अपना जवाब संपादित कर दिया है। –
डॉक्स के अनुसार, मार्क रीड की समाधान निश्चित रूप से काम करना चाहिए। लेकिन जब मैं एक Vagrantfile में यह करने की कोशिश की:
JSON.create_id = nil
vagrant_json = JSON.parse(Pathname(__FILE__).dirname.join('nodes', "#{node_name}.json").read)
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = "roles"
chef.data_bags_path = "data_bags"
chef.node_name = node_name
chef.run_list = vagrant_json.delete('run_list')
chef.json = vagrant_json
end
vagrant_json.class एक हैश किया गया था, लेकिन यह अभी भी json_class मूल्य आंतरिक रूप से बनाए रखा जब भी node.json फ़ाइल "json_class" निहित: "बावर्ची :: नोड " प्रविष्टि। फिर आखिरी पंक्ति में chef.json मान को सेट करने के लिए हैश का उपयोग करते समय, इसे फिर से जेसन क्लास (और परिणाम, अजीब, एक खाली रन सूची का उपयोग करके व्याख्या किया गया था।)
यहां क्या काम किया गया है। एक ही विचार है, लेकिन थोड़ा कम चालाकी:
vagrant_json = JSON.parse(Pathname(__FILE__).dirname.join('nodes', "#{node_name}.json").read)
vagrant_json['json_class'] = nil # <== This worked
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = "roles"
chef.data_bags_path = "data_bags"
chef.node_name = node_name
chef.run_list = vagrant_json.delete('run_list')
chef.json = vagrant_json
end
इस कोड, दोनों json गुण और एक बावर्ची नोड फ़ाइल से रन सूची सेट करने के लिए काम के साथ या "json_class" बिना: "बावर्ची :: नोड" प्रवेश।
संक्षेप में, पिछले उत्तर JSON.parse से हैश प्राप्त करने के संबंध में पूरी तरह से सही प्रतीत होता है, लेकिन यदि आप उस हैश से json_class जोड़ी को नहीं हटाते हैं, तो इस मामले में अभी भी समस्या हो सकती है ।
वाह, यह एक हैक जैसा दिखता है, लेकिन यह वास्तव में प्रलेखित एपीआई है: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html#create_id – jes5199