Ruby 1.9.1 built-in JSON troubles

I’m puzzled. On a box running Ruby 1.9.1 I try this:

[email protected]:/path$ irb
irb(main):001:0> require ‘json’
=> true
irb(main):002:0> JSON.parse(JSON.generate(’\’))
JSON::ParserError: 598: unexpected token at ‘"\"’
from /usr/local/lib/ruby/1.9/json/common.rb:122:in parse' from /usr/local/lib/ruby/1.9/json/common.rb:122:inparse’
from (irb):2
from /usr/local/bin/irb:12:in `’
irb(main):003:0> RUBY_VERSION
=> “1.9.1”
irb(main):004:0> ^D

This is the JSON module that came with 1.9–I don’t have a JSON gem
installed.

Any ideas where to go looking? A little web searching showed me
various similar problems, but most were under 1.8.

Looking for a clue,
Aaron out.

Aaron D. Gifford wrote:

irb(main):002:0> JSON.parse(JSON.generate(’\’))
JSON::ParserError: 598: unexpected token at ‘"\"’

This is simply because JSON.parse only parses JSON objects and
arrays, not strings or numbers.

JSON.parse(’{“foo”:“bar”}’)
=> {“foo”=>“bar”}

JSON.parse(’[“foo”,“bar”]’)
=> [“foo”, “bar”]

JSON.parse(’“bar”’)
JSON::ParserError: 574: unexpected token at ‘“bar”’

I use the following workaround:

json = JSON.generate(’\’)
=> “”\\""

JSON.parse("[" + json + “]”).first
=> “\”

HTH,

Brian.

On Mon, Mar 8, 2010 at 5:39 AM, Brian C. [email protected]
wrote:

=> [“foo”, “bar”]
HTH,

Brian.

Thanks for the note, Brian.

The JSON documentation does NOT make that clear.

And that limitation is a terrible limitation. Ugly!

I ended up rolling my own pure Ruby JSON parser that doesn’t have that
work-around requirement. It looks like I could have avoided that with
your work-around (even though it’s sad that the JSON library requires
such an ugly kludge).

Aaron out.

As per Brian’s suggestion, I used his workaround this way:
(IMHO, JSON ought to handle this automagically.)

require ‘json’
def json_parse_kludge(data)
return JSON.parse(’[’ + data + ‘]’)[0] if data.is_a?(String) &&
data[0,1] == ‘"’
JSON.parse(data)
end

Fixes my issue: json_parse_kludge(JSON.generate(’\’))

irb(main):001:0> require ‘json’
=> true
irb(main):002:0> def json_parse_kludge(data)
irb(main):003:1> return JSON.parse(’[’ + data + ‘]’)[0] if
data.is_a?(String) && data[0,1] == ‘"’
irb(main):004:1> JSON.parse(data)
irb(main):005:1> end
=> nil
irb(main):006:0> json_parse_kludge(JSON.generate(’//’))
=> “//”
irb(main):007:0>

Thanks again, Brian!

Aaron out.

Aaron D. Gifford wrote:

Thanks for the note, Brian.

The JSON documentation does NOT make that clear.

I could understand if it only allowed an object at the top level (which
is what CouchDB requires), but I agree it doesn’t make sense to allow
two types of values but not the other types.

Your kludge is a bit messy, it won’t parse ’ “foo”’ for example (with a
leading space). If you are afraid of building an extra string, then how
about:

def jparse(str)
return JSON.parse(str) if str =~ /\A\s*[{[]/
JSON.parse("[#{str}]")[0]
end

On Mon, Mar 8, 2010 at 12:19 PM, Brian C. removed_email_[email protected]
wrote:

… If you are afraid of building an extra string, then how
about:

def jparse(str)
return JSON.parse(str) if str =~ /\A\s*[{[]/
JSON.parse("[#{str}]")[0]
end

Definitely more robust, since that will handle numbers too. Thanks

Aaron out.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs