Hacklog: Blogamundo — poking holes in the language barrier since approximately 1 month from now

b
l
o
g
a
m
u
n
d
o

New Ruby JSON serializer

Written by Jonas Galvez, 2 years, 7 months ago.
Tags: , , , , .

I wrote a new Ruby JSON serializer using Jamis Buck’s Ruby Tokenizer. It’s an order of magnitude safer than my previous attempt. I still use inspect() to create a string representation of the object, but now I’m using the tokenizer to safely replace => by : (properly ignoring => inside strings, that is) instead of that heinous regular expression.

require 'rubygems'
require_gem 'syntax'
	
class RubyJSONSerializer
	
    @@tokenizer = Syntax.load \"ruby\"
	
    def ruby_to_json(obj)
        res = \"\"
        symbol = false
        @@tokenizer.tokenize(obj.inspect) do |token|
            if token.group == :punct
                if symbol
                    res += token.gsub(/>/, '')
                    symbol = false
                else
                    res += token.gsub(/=>/, ': ')
                end
            elsif token.group == :symbol
                res += \"\\"#{token.match(/:(.+)=/)[1]}\\": \"
                symbol = true
            else
                res += token
            end
        end
        res
    end
	
end
	
s = RubyJSONSerializer.new
o = {\"foo\"=>\"foo => bar\", :bar=>\"bar => foo\", \"meh\"=>[1,2,3], :n=>123}
puts s.ruby_to_json(o)

Let me know if you spot anything wrong. Update: since a couple friends asked me about this, I thought I’d clarify it here: I’m using Ruby’s built-in YAML parser (syck, I believe, which is also available for Python) to parse JSON. It’s been flawless so far.

Update 2: I should also point out that this only works for primitive datatypes. If you have an object whose to_s method is not JSON-enabled, beware that the serializer will silently produce invalid JSON. To avoid this, make sure you’re creating a Ruby object from scratch:

# good
obj = ruby_to_json({\"foo\"=>MyActiveRecordInstance.foo, \"bar\"=>MyActiveRecordInstance.bar})
# bad
obj = ruby_to_json(MyActiveRecordInstance)

2 Comments for 'New Ruby JSON serializer'

  1. Comment received 2 years, 7 months ago from Suzana

    Oi guri! Estou gostando de ver que o projeto vai à mil. Uma hora destas me conta as novidades.
    abraço,
    Su

  2. Comment received 10 months, 3 weeks ago from Alex Egg

    What’s the point if you can’t just serialize a whole object?

Leave a comment

(required)

(required)

Comment moderation may delay the posting of your comment. XHTML: You can use the following tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <img src="" alt=""> <strike> <strong> . Don't forget to close them after use.