Caius Theory

Now with even more cowbell…

Abusing Ruby 1.9 & JSON for fun

Ever since I found out about the new hash syntax you can use in ruby 1.9, and how similar that syntax is to JSON, I've been waiting for someone to realise you can just abuse eval() for parsing (some) JSON now.

For example, lets say we have the following ruby hash, which could be generated by a RESTful api:

thing = {
    :person => {
        :name => "caius"
    }
}

If we pull in the JSON gem and dump that out as a string, we get the following:

jsonstr = thing.to_json
# => '{"person":{"name":"caius"}}'

That's… not quite what we wanted. It's not going to turn back into valid ruby as it is. Luckily javascript will parse objects without requiring the attributes to be wrapped in quotes, eg: {some: "attribute"}. We could build a JSON emitter that does it properly, or we could just run it through a regular expression instead. (Lets also add a space after the colon to aid readability.)

jsonstr.gsub!(/"([^"]+)": /, '\1: ')
# => '{person: {name: "caius"}}'

Okay, so now we've turned a ruby hash into a JSON hash, that can still be parsed by the browser. Here's a screenshot to prove that:

Valid JSON 'thing'

As you can see, it parses that into a valid JS object, complete with person and then (nested) name attributes. If we wanted to, thing["person"]["name"] or thing.person.name would access the nested value "caius" just fine.

Now then, we've proved that is successfully parsed into javascript objects by the browser, generated from a ruby hash. No great shakes there, that's fairly simple and has worked for ages. Now for my next trick, I'm going to turn that string of JSON back into a ruby hash, all without going anywhere near the JSON gem.

Some of you might have guessed what I'm about to do and have started hoping you've guessed wrongly — just for the record I don't condone doing this except for fun and games. The JSON gem is there for a reason ;) With that little disclaimer out the way, here we go!

thing2 = eval(jsonstr)
# => {:person=>{:name=>"caius"}}
thing2 == thing
# => true

Oh snap! We just turned javascript objects back into valid ruby objects, in one simple method call. And we'd be able to access the "caius" value by calling thing2[:person][:name], or creating OpenStructs from the hashes and calling thing2.person.name. Which is uncannily like the JS!

Updated 2011-02-07: Jens Ayton pointed out unquoted keys aren't strictly valid JSON, which is correct. Amended to say they're parsed as javascript objects instead, with no mention of it being valid JSON.

Bad Recruiters - Rhys Evans at Devonshire

This is a linked-in invitation I received from Rhys, and my reply.


Update 2011-02-10: As much as recruiters can be scummy twats, Rhys appears to at least care somewhat about his relationship with potential clients/contacts and has responded in the comments. Normally my policy with recruiters is a two strike one, first email gets a polite "No thanks, go away.", second gets a mini-rant to bugger off and stop contacting me. Rhys hadn't technically contacted me before, but the unsolicited xmas email showed up when I searched my mailbox (which had annoyed me back when I received it.) And asking amongst my peers around at the time showed he was fairly disliked. (As you can see in some of the comments left below as well.) Since then, including a comment left below, a few people I trust have noted he's really not that bad as recruiters go, and the fact he's left a comment acknowledging perhaps his approach is a little misguided is enough for me to see he does still care about trying to be better than the rest of the recruitment crowd.

I still stand by my initial reply to him, and all other recruiters who don't understand "No." however.


On 02/09/11 5:30 AM, Rhys Evans wrote:

Hi Caius,

Good afternoon, I hope all is well.

I've noticed we are connected to a number of the same people within the Rails space on LinkedIn. I've tried you on 07960 268100 to no avail so I'd like to add you to my network and make contact.

Hi Rhys,

I've already got you blocked on twitter, so we've obviously run across each other in the past. You also appear to have sent me a Merry Xmas email from Devonshire, with no previous contact initiated by me. (I seem to remember a lot of my friends got those emails as well and we eventually worked out you'd scraped Github for them.)

Now it would appear you're being more intrusive and hunting folk out on linked in, ignoring the fact that they are employed and have specifically set linked in to say they aren't looking for new jobs currently. From asking around you harass a few of my friends, to the point of ringing one up recently to tell them you knew they'd changed jobs and where they were now working. If you're going to spend time doing that much research then why not have the decency to not be a completely mannerless cunt and leave them alone when they request you to.

It would also appear you've just blanket-spammed me and a few people in my peer group through linked in with the same request, again a pretty dumb thing to do. It's as if you recruiters think we never talk to each other, and don't realise how much you lot being a bunch of pestering spammy bastards taints developers against ever dealing with a recruiter.

So no, I don't think I do want to accept your invitation to connect. And please never phone, email or contact me via any other means. I'm happily employed and if I ever need the services of a recruiter I'll find someone who actually possesses an ounce of politeness about approaching (potential) candidates.

Thanks,
Caius