How can I pass JSON values ​​to a Struct Ruby object?

Given a JSON object

{"a": 1, "b":2}

      

and a value object derived from a struct:

class A < Stuct.new(:a, :b)
end

      

How can I make an instance of A that has values ​​from JSON?

I'm trying to:

 a = A.new(JSON.parse({a:1,b:2}.to_json).values)
 => #<struct A a=[1, 2], b=nil>

      

But I would expect a-> 1 and b-> 2

+3


source to share


3 answers


Try using:

a = A.new(*JSON[json].values)
a.class # => A < #<Class:0x00000102955828>

      

The problem is that it values

returns an array, but you need the individual elements of the array. By *

splats the array back into its components, this makes Struct happy when you pass values new

.


EDIT:



This will fail if the JSON and Struct orderings are not the same!

This forces the order of the values.

a = A.new(*JSON[json].values_at('a', 'b'))
{
    :a => 1,
    :b => 2
}
a.class # => A < #<Class:0x00000102955828>

      

JSON preserves hash insertion order, just like Ruby, so the JSON parsed and parsed by Ruby will be correct. JSON generated by not preserving order might be a problem, but it values_at

fixes the problem.

Note that JSON converts characters to strings, so the keys passed to values_at

must be strings, not characters.

+5


source


If it doesn't have to be a predefined structure this will work



a = Struct.new(*json.keys).new(*json.values)

      

+3


source


You can use an operator splat

to pass array values ​​as arguments to a new function.

a = A.new(*{a:1,b:2}.values)

      

+1


source







All Articles