JSON for Red

I’ve been playing around more with Red.  I alternate between really liking it and totally pulling my hair out.  On a order form app that I’m building I made some very quick work of a dynamically updating billing summary div.  It came together very quickly until I added the AJAX piece.  AJAX support in Red is actually very good, but JSON support is non-existent.  This made Ryan a sad boy.  I dug around to see what other people have done and found that they haven’t done much.  There is some stub code for a Request::JSON that my be what I’m looking for at some point, but I need it now.  So here is what I did:

class Module
  def define_method(sym, &block)
    `this.prototype['m$'+sym.__value__]=block.__block__.__unbound__`
    `Red.updateChildren(this)`
    `Red.updateIncluders(this)`
    return `block`
  end
end

class Object
  def self.from_json(text)
    ret = Object.new
    meths = []
    `var v = eval("("+#{text}.__value__+")")`
    `for(var member in v){#{meths}.push(new Array($q(member), $q(v[member])))}`
    meths.each do |meth|
      ret.class.send(:define_method, meth[0]) do
        meth[1]
      end
    end
    return ret
  end
end

Now doing a simple AJAX call that returns JSON becomes really easy:

@req = Request.new(:url => '/orders')
@req.upon(:response) do |response|
  new_data = Object.from_json(response.text)
  @summary = new_data.summary
  @subtotal = new_data.subtotal
  @total = new_data.total
end
@req.execute(:data => {'plan_id' => @plan, 'promo' => @promo})

A few things to note here.  The section that defines `define_method` on `Module` is actually back ported from the current master branch of Red.  This works pretty well, though I haven’t tried it with a JSON string that describes a living object.  But I don’t think it’s too far from being able to handle that.