2010-12-16 13 views
64

मैं रूबी में जेएसओएन क्रमबद्धता परिदृश्य को समझने की कोशिश कर रहा हूं। मैं रूबी के लिए नया हूँ।रूबी ऑब्जेक्ट्स और जेएसओएन सीरियलाइजेशन (रेल के बिना)

क्या आप रेल के साथ काम नहीं कर रहे हैं तो कोई अच्छा JSON क्रमबद्धता विकल्प है? जहां इस उत्तर (रेल के लिए) हो जाता है

लगता है कि होने के लिए How to convert a Ruby object to JSON

json मणि यह देखो की तरह आप अपने खुद के to_json विधि लिखने के लिए कर रहा है। मैं arrays और हैश के साथ काम करने के लिए to_json प्राप्त करने में सक्षम नहीं हूं (प्रलेखन कहता है कि यह इनके साथ काम करता है) क्या कोई कारण है कि जेसन मणि ऑब्जेक्ट पर प्रतिबिंबित नहीं होता है और डिफ़ॉल्ट क्रमबद्धता रणनीति का उपयोग करता है? यह कैसे काम करता है to_yaml (यहाँ अनुमान लगा)

+2

शायद ध्वनि बेवकूफ हो, लेकिन क्या आपको वास्तव में 'जसन' की आवश्यकता थी? मैंने जेएसओएन रत्नों के साथ काम किया और उन्होंने एक आकर्षण की तरह काम किया। – DarkDust

उत्तर

8

तो प्रतिपादन प्रदर्शन के लिए महत्वपूर्ण है, तो आप भी yajl-ruby को देखने के लिए है, जो एक सी yajl पुस्तकालय के लिए बाध्य किया जाता है चाहते हो सकता है नहीं है।

require 'yajl' 
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}" 
+0

जैसा कि मुझे अपनी अगली परियोजना में बहुत सारे JSON डेटा के साथ काम करना होगा, यह मेरा जीवन बचतकर्ता हो सकता है। +1 – Ernest

96

लिए JSON पुस्तकालय उपलब्ध होने के लिए आपको अपने पैकेज प्रबंधक से libjson-ruby स्थापित करने के लिए हो सकता है: यह है कि एक के लिए क्रमांकन एपीआई तरह दिखता है।

'json' पुस्तकालय का उपयोग करें:

require 'json' 

JSON करने के लिए एक वस्तु को बदलने के लिए (इन 3 तरीके बराबर हैं):

JSON.dump object #returns a JSON string 
JSON.generate object #returns a JSON string 
object.to_json #returns a JSON string 

किसी ऑब्जेक्ट को JSON टेक्स्ट बदलने के लिए (इन 2 तरीके बराबर हैं):

JSON.load string #returns an object 
JSON.parse string #returns an object 

यह आपके स्वयं के वर्गों से वस्तुओं के लिए थोड़ा और कठिन होगा। निम्न वर्ग के लिए, to_json "\"#<A:0xb76e5728>\"" जैसे कुछ उत्पन्न करेगा।

class A 
    def initialize a=[1,2,3], b='hello' 
     @a = a 
     @b = b 
    end 
end 

यह संभवतः वांछनीय नहीं है। जेएसओएन के रूप में अपनी ऑब्जेक्ट को प्रभावी ढंग से क्रमबद्ध करने के लिए, आपको अपनी खुद की to_json विधि बनाना चाहिए। इसके साथ जाने के लिए, एक_json क्लास विधि उपयोगी होगी। तुम इतनी तरह अपने वर्ग का विस्तार कर सकते हैं: object.from_json! string

class JSONable 
    def to_json 
     hash = {} 
     self.instance_variables.each do |var| 
      hash[var] = self.instance_variable_get var 
     end 
     hash.to_json 
    end 
    def from_json! string 
     JSON.load(string).each do |var, val| 
      self.instance_variable_set var, val 
     end 
    end 
end 

तो फिर तुम object.to_json उपयोग कर सकते हैं JSON के serialise करने के लिए और बचाया कॉपी करने के लिए:

class A 
    def to_json 
     {'a' => @a, 'b' => @b}.to_json 
    end 
    def self.from_json string 
     data = JSON.load string 
     self.new data['a'], data['b'] 
    end 
end 

आप एक 'JSONable' वर्ग से इनहेरिट द्वारा इस को स्वचालित कर सकता है वह स्थिति जिसे ऑब्जेक्ट में JSON स्ट्रिंग के रूप में सहेजा गया था।

+3

ऐसी लाइब्रेरी की तलाश में थी जिसके लिए आपको कक्षाओं में to_json विधि लिखने की आवश्यकता नहीं थी। क्या कोई वर्ग है जिसे आप प्राप्त कर सकते हैं जो आपको प्रतिबिंब के माध्यम से देता है? और जटिल वस्तुओं पर काम करता है? – BuddyJoe

+0

मैं stdlib कामों में वाईएएमएल कोड जिस तरह से देख रहा हूं, लेकिन इस बिंदु पर मुझे ग्रोक करने के लिए यह थोड़ा सा है। – BuddyJoe

+0

क्या अद्यतन उत्तर आपको इस सम्मान से मदद करता है? – david4dev

6

रूबी का आप किस संस्करण का उपयोग कर रहे हैं? ruby -v आपको बताएगा।

यदि यह 1.9.2, JSON is included in the standard library है।

यदि आप 1.8.something पर हैं तो gem install json करें और यह इंस्टॉल हो जाएगा।फिर, अपने कोड में कार्य करें:

require 'rubygems' 
require 'json' 

तब किसी ऑब्जेक्ट को to_json संलग्न करें और आप के लिए तैयार हैं:

asdf = {'a' => 'b'} #=> {"a"=>"b"} 
asdf.to_json #=> "{"a":"b"}" 
+0

क्या यह यजल से तेज होगा? – Ernest

+0

यह आपके लिए ['बेंचमार्क'] (http://ruby-doc.org/core/classes/Benchmark.html) का उपयोग निर्धारित करने के लिए है? है ना? –

+1

मुझे लगा कि आपको शायद यह पता चलेगा। बेंचमार्क किया गया और यह धीमा है: पी विशेष रूप से एन्कोडिंग करते समय। – Ernest

1

आप 1.9.2 उपयोग कर रहे हैं या इसके बाद, आप हैश परिवर्तित कर सकते हैं और JS_ ऑब्जेक्ट्स को नेस्टेड करने के लिए सरणी सिर्फ to_json का उपयोग कर।

{a: [1,2,3], b: 4}.to_json 

रेल में, आप सक्रिय रिकॉर्ड ऑब्जेक्ट्स पर to_json पर कॉल कर सकते हैं। आप पास कर सकते हैं: शामिल हैं और: केवल मानकों उत्पादन को नियंत्रित करने के:

@user.to_json only: [:name, :email] 

तुम भी to_json एआर संबंधों पर, कॉल कर सकते हैं तो जैसे:

User.order("id DESC").limit(10).to_json 

तुम कुछ भी आयात करने की आवश्यकता नहीं है और यह जैसा कि आप उम्मीद करेंगे बिल्कुल सभी काम करता है।

9

Oj देखें। जब किसी भी पुराने ऑब्जेक्ट को जेएसओएन में परिवर्तित करने की बात आती है तो गॉथचा जाता है, लेकिन ओज इसे कर सकता है।

require 'oj' 

class A 
    def initialize a=[1,2,3], b='hello' 
     @a = a 
     @b = b 
    end 
end 

a = A.new 
puts Oj::dump a, :indent => 2 

यह आउटपुट:

{ 
    "^o":"A", 
    "a":[ 
    1, 
    2, 
    3 
    ], 
"b":"hello" 
} 

ध्यान दें कि ^o वस्तु की कक्षा नामित करने के लिए प्रयोग किया जाता है, और अक्रमांकन सहायता करने के लिए नहीं है। ^o छोड़ करने के लिए, :compat मोड का उपयोग करें:

puts Oj::dump a, :indent => 2, :mode => :compat 

आउटपुट:

{ 
    "a":[ 
    1, 
    2, 
    3 
    ], 
    "b":"hello" 
} 
+0

'ओज' में कक्षाओं को बदलने और अतिरिक्त त्रुटियों के बिना उन्हें deserializing के लिए महान संगतता है। +1 – ashes999

+1

इस "^ oj" मान को कैसे निकालें? – neustart47

+1

@ neustart47: मैंने यह जवाब दिखाने के लिए संपादित किया है कि यह 'compat' मोड का उपयोग करके कैसे किया जा सकता है। – Jimothy

0

वास्तव में, वहाँ एक मणि Jsonable, https://github.com/treeder/jsonable कहा जाता है। यह बहुत प्यारा है।

+0

जेसनबल अक्षम दिखता है: आखिरी बार 2012 में अपडेट किया गया था, और उदाहरण कोड विफल रहता है - 'JSON.parse' एक ऑब्जेक्ट नहीं, जेसन लौटाता है। – ashes999

+0

उदाहरणों के बारे में नहीं जानते, लेकिन मैंने अपने उपयोग के मामले में जेसन योग्य पाया: https://feedjira.herokuapp.com/ https://github.com/dentarg/feedjira.herokuapp.com/blob/464c27af9179dcb73898ca029883a648bccd67c2/feedjira । आरबी # एल 17 https://github.com/dentarg/feedjira.herokuapp.com/blob/464c27af9179dcb73898ca029883a648bccd67c2/monkey.rb – dentarg

+0

शायद यह रेल या कुछ और पर निर्भर है। मैं सीधे रूबी का उपयोग कर रहा हूँ। – ashes999

1

वर्गों (सरणी और हैश की तरह) में निर्माण as_json और to_json समर्थन करने के लिए पाने के लिए आपको (विवरण के लिए readme देखें)

0

मैं virtus के लिए इस्तेमाल किया require 'json/add/core' की जरूरत है। वास्तव में शक्तिशाली उपकरण, आपके निर्दिष्ट कक्षाओं के आधार पर एक गतिशील रूबी संरचना संरचना बनाने की अनुमति देता है। आसान डीएसएल, रूबी हैश से वस्तुओं को बनाने के लिए संभव है, सख्त मोड है। it देखें।

4

जब से मैं एक बहुत अपने आप json करने के लिए एक रूबी वस्तु क्रमानुसार करने की खोज:

require 'json' 

class User 
    attr_accessor :name, :age 

    def initialize(name, age) 
    @name = name 
    @age = age 
    end 

    def as_json(options={}) 
    { 
     name: @name, 
     age: @age 
    } 
    end 

    def to_json(*options) 
    as_json(*options).to_json(*options) 
    end 
end 

user = User.new("Foo Bar", 42) 
puts user.to_json #=> {"name":"Foo Bar","age":42} 
+1

मैंने इसे एक रूबी फ़ाइल में कॉपी/चिपकाया, और इसे किसी समस्या के बिना निष्पादित किया गया। आउटपुट शामिल करने के लिए अपने उत्तर को अपडेट करना सहायक हो सकता है: {"name": "फू बार", "आयु": 42} –

1

Jbuilder एक मणि रेल समुदाय द्वारा बनाया गया है। लेकिन यह गैर-रेल वातावरण में अच्छी तरह से काम करता है और सुविधाओं का एक अच्छा सेट है।

# suppose we have a sample object as below 
sampleObj.name #=> foo 
sampleObj.last_name #=> bar 

# using jbuilder we can convert it to json: 
Jbuilder.encode do |json| 
    json.name sampleObj.name 
    json.last_name sampleObj.last_name 
end #=> "{:\"name\" => \"foo\", :\"last_name\" => \"bar\"}" 
संबंधित मुद्दे