tags:

views:

53

answers:

1

I have a simple class that overrides to_json to list the attributes in an array -

class MyClass
  def initialize(a, b)
    @a = a
    @b = b
  end

  def to_json(*opt)
    [@a, @b].to_json(*opt)
  end
end

to_json works fine for an instance of the class -

irb> m = MyClass.new(10, "abc")
irb> m.to_json
=> "[10,\"abc\"]"

But if I put the object in an array, my custom to_json does NOT get called -

irb> [m].to_json
=> "[{\"a\":10,\"b\":\"abc\"}]"

I would expect to get the following output -

=> "[[10,\"abc\"]]"

Another example - if I create another instance that contains the first instance

irb> m2 = MyClass.new(20, m)
irb> m2.to_json
=> "[20,{\"a\":10,\"b\":\"abc\"}]"

What I expect is

=> "[20,[10,\"abc\"]]"

Looks like to_json does not get called recursively. How to solve this?

Thanks as always!!

Updates

This seems to work as expected on Ruby 1.9.1. Thanks Mladen!
I need to use 1.8.7.

A: 

Ugly hack to get it working on Ruby 1.8.7 till someone suggests a better method:

  • Override to_xml instead of to_json.
  • Call to_xml, export that back to a hash and then hash to json.

e.g. Hash.from_xml(m2.to_xml)["objects"].to_json

amolk