5

I have a javascript object of this form

 obj = "[
   {
     title: "Sean Kingston1",
     duration: parseInt("71", 10),
   },
   {
     title: "Sean Kingston2",
     duration: parseInt("71", 10),
   },
 ]"

is there a way to convert this to a ruby hash ?

I tried using JSON.parse and JSON.load
both of them throw

 JSON::ParserError: lexical error: invalid string in json text.
                               {   title: "Sean Kingston1
                 (right here) ------^

Is there a generic solution or should I use regex and then construct the hash in ruby ?

vireshas
  • 806
  • 6
  • 19
  • 1
    Deleting [your old question](http://stackoverflow.com/questions/9579673/convert-javascript-json-like-object-to-a-ruby-hash) and creating a new one doesn't change the fact that what you have is **not** valid JSON. – Andrew Marshall Mar 06 '12 at 08:43
  • 2
    @andrew i did change the question its a javascript object and that is what i get from the server... do u know an answer to the question ?? – vireshas Mar 06 '12 at 09:10
  • @andrew i never used the word JSON! – vireshas Mar 06 '12 at 09:13
  • 1
    You did when you tagged it as JSON. – Andrew Marshall Mar 06 '12 at 09:14
  • my bad,i didnt notice! what do u think i shld do here ? i will probably use reqex and convert all the title and duration to "title" and "duration".. is there a generic solution ? – vireshas Mar 06 '12 at 09:19
  • eval !!! thats it :) ( remove parseInt thingy and use eval ) – vireshas Mar 06 '12 at 10:17
  • I think this is a perfectly fine question, worded correctly. It is a Javascript object, and not JSON. – gerard Jun 03 '13 at 15:18

2 Answers2

4

ruby 1.9 supports hash of this kind which resembles a javascript object

 obj = "[
  {
   title: "Sean Kingston1",
   duration: "71",
  },
  {
   title: "Sean Kingston2",
   duration: "71",
  },
 ]"

to convert this into a ruby hash

 eval(obj)
vireshas
  • 806
  • 6
  • 19
  • Actually you may need to have numbers **not** quoted. At least this is allowed even in JSON (which has even more strictly syntax) – kirilloid Mar 06 '12 at 10:27
  • @kirilloid yup i will do it right away, thank u :) actually i get this Js object by scraping a site and my scraper is written in ruby! – vireshas Mar 06 '12 at 10:31
  • 6
    Be careful when `eval`ing code from random websites! – Benjamin Manns Jul 24 '15 at 22:20
  • I found my own answer when I was trying to build a Ruby Map out of this data http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js :-) – vireshas Nov 24 '16 at 10:34
  • eval RestClient.get("http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js").match(/regions\:(\[.*\])/)[1] – vireshas Nov 24 '16 at 10:38
2

This is not a JSON. Actually, JSON is not the same as code, could be interpreted by javascript and evaluated to object.

JSON itself allows only static values (no parseInt) and any keys should be quoted as well.

[{
    "title": "Sean Kingston1",
    "duration": 71
 },
 {
    "title": "Sean Kingston2",
    "duration": 71
 }]

Using regexes and such things ain't good. You'd better just format JSON properly.

Ok, if you're not able to modify that input, you may solve a problem for this particular input with following regexpes:

/^\s*(\w+)\s*:/, '"\1":';
/:\s*parseInt\("(\d+)"\,\s*10)/, ': \1';

but for any variation in input you'll need to add more and more regexpes.

Generally, in order to interpret javascript you need to ... interpret javascript.

This is possible via installing some js Engine, like Rhino or V8 and binding it to Ruby.

kirilloid
  • 14,011
  • 6
  • 38
  • 52
  • the javascript code what i have is not under my control :( i am scraping a site.. – vireshas Mar 06 '12 at 09:11
  • i was very careful to not to use the word JSON , i have a javascript object of that kind.. now how do i convert it to hash ? is their a solution or shld i use regex ?? – vireshas Mar 06 '12 at 09:13
  • Ideally, in order to parse such code, you need to have full javascript interpreter in order to evaluate any input into objects, hashes or somewhat (I'm not familiar with Ruby). – kirilloid Mar 06 '12 at 10:12
  • i did something like this replaced parseInt("","") by the number and called eval(obj) it worked :) – vireshas Mar 06 '12 at 10:16
  • Hmm. You may call eval for js code? Eval isn't good thing, but will work here. – kirilloid Mar 06 '12 at 10:21
  • i used eval of ruby ! this link has more information http://stackoverflow.com/questions/1667630/how-do-i-convert-a-string-object-into-a-hash-object – vireshas Mar 06 '12 at 10:22
  • Those Regexps worked great for me! Normalizing to JSON is much wiser than `eval`. – sondra.kinsey Jun 10 '19 at 13:32