Hyphens in serialized JSON OpenStruct - ruby

I have a JSON object such as:
"c": {
"10-20": 9.0,
"0-10": 8.5,
"30-end": 5.085714285714286,
"20-30": 10.3
}
When I convert that JSON to a serialized object using:
JSON.parse(response.body, object_class: OpenStruct)
It gives me:
<OpenStruct 10-20=0, 0-10=8.5, 30-end=5.085714285714286, 20-30=10.3>
Naturally that can't be accessed with c.10-20 as I don't believe hyphens are valid class variable names. So, how do you access these values?

You can use square brackets like you would with a hash:
obj["10-20"]
#=> 0
Of course, if most of the keys are not valid method names anyway, then you might as well just use a hash and not bother with an OpenStruct.
Related documentation: OpenStruct#[]

Related

Display multiple hash keys notation

Let's say i have a ruby hash in the style of savon soap xml response to hash
hash1= { node1­: {node­2:{node3:1­,node4:2}}­}
now to display this hash
hash1[:nod­e1][:node2­][:node3]
works and outputs => 1
hash1[:nod­e1][:node2­][:node4]
works and output => 2
hash1[:nod­e1][:node2­][:node3][:node4]
gives TypeError
although i have seen that type of code on savon scripts. What doesnt it work in my situation ?
hash1[:nod­e1][:node2­][:node3][:node4] is calling the method [] on
hash1[:nod­e1][:node2­][:node3].
Its the equivalent of trying 1[:node4]. The method on an integer takes a Fixnum and cannot implicitly convert a symbol (or a string etc) into an integer.
These multiply-nested hashes are difficult to read, aren't they? Let's spread your hash out a bit:
hash1= {
node1­: {
node­2: { node3:1­, node4:2 }
}­
}
So: The value of node1 is itself a hash. The only entry in that hash, node2, also has a hash for a value. This hash has two entries: node3 and node4, both of which have integers as values.
So hash1[:node1][:node2] returns {node3:1, node4:2}. And hash1[:node1][:node2][:node3] returns 1.
But hash1[:node1][:node2][:node3][:node4] doesn't make any sense, because 1 isn't a hash, and therefore doesn't have a key :node4. That key belongs to the :node2 hash.
It would make sense if you had hash1= { node1­: {node­2: {node3: {node4:2} }}­}. But you don't.
Like I said: these nested hashes are a pain to read...

How do I pass an array of strings to a ruby method that wants the strings but not in an array?

I have an array of strings (actually file names), something like
filenames = ['file1.jpg', 'file2.jpg', 'file3.jpg']
The method I am calling expects something like
images = Magick::ImageList.new("image1.png", "image2.png", "image3.png")
but if I call as below, I am actually passing an array.
images = Magick::ImageList.new(filenames)
How do I unwrap the contents of the array?
Do as below using splat opearator(*) :
images = Magick::ImageList.new(*filenames)
As #Stefan mentioned the documentation link for the same Array to Arguments Conversion

Mapping a JSON array of unnamed values with RESTKIT 0.20

When I configure mapping from a REST service returning JSON to a object, I normally do this:
RKObjectMapping *myMapping = [RKObjectMapping mappingForClass:[MyClass class]];
[myMapping addAttributeMappingsFromDictionary:#{#"Address" : #"address", #"City" : #"city"}];
and this works great for JSON with named attributes, but how do I map the following JSON to a object with the property "name"?
["My Value","Some other value","More stuff","Hello World"]
This JSON is just a array of values and has not name/key only values. How do I map this to a object with RESTKIT 0.20?
Thank you
Søren
This expression in square brackets is a json array: http://www.json.org. If you look on the syntax tree on the home page, you can consider, every json array is a value of a "variable" with a name. It means your expression has to look like this, to be a valid json:
{ "myArray": ["My Value","Some other value","More stuff","Hello World"] }
and you map it like you always do:
[myMapping addAttributeMappingsFromDictionary:#{#"myArray" : #"myArray"}];
Your parameter MyArray in mapping target class has then a type of NSArray.

Passing a hash where the keys are objects to JSON?

I am trying to pass a hash into Javascript via JSON where the keys are ruby objects, and the values are arrays of objects. The arrays of objects are transmitted just fine, but the key is being converted into a string of the class.
Here is an example:
[4] pry(#<User>)> x = find_all_sections.collect { |s| { s => s.find_all_events_id_and_title } }
=> [{#<Section id: 58, course_id: 12, section_number: 3, semester_id: 1>} =>
[{:id=>37, :title=>"Event 37"},
{:id=>40, :title=>"Event 40"},
{:id=>9, :title=>"Event 9"},
{:id=>10, :title=>"Event 10"},
{:id=>16, :title=>"Event 16"},
{:id=>38, :title=>"Event 38"}, etc...
The result of converting this to json is (you just have to look at the first few characters of the string to see that it's not the object, but the to_s of the object:
[11] pry(#<User>)> x.to_json
=> "[{\"#<Section:0x007fa475b52f68>\":[{\"id\":37,\"title\":\"Event 37\"},{\"id\":40,\"title\":\"Event 40\"},{\"id\":9,\"title\":\"Event 9\"},{\"id\":10,\"title\":\"Event 10\"},{\"id\":16,\"title\":\"Event 16\"},{\"id\":38,\"title\":\"Event 38\"},{\"id\":49,\"title\":\"Event 49\"},{\"id\":39,\"title\":\"Event 39\"},{\"id\":15,\"title\":\"Event 15\"},{\"id\":25,\"title\":\"Event 25\"},{\"id\":11,\"title\":\"Event 11\"},{\"id\":4,\"title\":\"Event 4\"},{\"id\":22,\"title\":\"Event 22\"},{\"id\":1,\"title\":\"Event 1\"},{\"id\":23,\"title\":\"Event 23\"},{\"id\":8,\"title\":\"Event 8\"},{\"id\":13,\"title\":\"Event 13\"},{\"id\":26,\"title\":\"Event 26\"},{\"id\":46,\"title\":\"Event 46\"},{\"id\":20,\"title\":\"Event 20\"},{\"id\":31,\"title\":\"Event 31\"},{\"id\":6,\"title\":\"Event 6\"},{\"id\":18,\"title\":\"Event 18\"},{\"id\":41,\"title\":\"Event 41\"},{\"id\":7,\"title\":\"Event 7\"},{\"id\":43,\"title\":\"Event 43\"},{\"id\":45,\"title\":\"Event 45\"},{\"id\":24,\"title\":\"Event 24\"},{\"id\":2,\"title\":\"Event 2\"},{\"id\":44,\"title\":\"Event 44\"},{\"id\":29,\"title\":\"Event 29\"},{\"id\":28,\"title\":\"Event 28\"},{\"id\":5,\"title\":\"Event 5\"},{\"id\":3,\"title\":\"Event 3\"},{\"id\":27,\"title\":\"Event 27\"}]},
How can I achieve the JSON data keeping the key's object intact?
You can't. Keys are always strings in JavaScript. Furthermore, the JSON spec says that keys must always have the form of a single, double-quoted string literal.

Hash from String in Ruby: Marshal.load? (re-create the params hash from a Rails production.log)

I want to parse Rails production.log files and recreate the params Hash. I am stuck with the Marshal.load method, which actually expects the data to be marshalled. Well, the data is well-formed but it is a String and not in a Marshal expected format.
here is the String that i regexed out of the request from the logfile:
{
"location"=>{"city"=>"München \"foo \" bar", "id"=>"462", "youtube_tags"=>""},
"authenticity_token"=>"UHi0GCNDBPN/Ms+0bqEOl4HGvUjDRw8tNvtqVl3v0dY=",
"utf8"=>"\342\234\223", "textinput"=>""
}
I tried my way around this issue with
o=JSON.parse.gsub("=>",":"))
in which case i get problems with umlauts.
Is there no way to parse or load a Hash representation from a String to actual Ruby Hash structures with Ruby 1.8.7?
This probably isn't the best way to do it, but ...
h = eval '{
"location"=>{"city"=>"München", "id"=>"462", "youtube_tags"=>""},
"authenticity_token"=>"UHi0GCNDBPN/Ms+0bqEOl4HGvUjDRw8tNvtqVl3v0dY=",
"utf8"=>"\342\234\223", "textinput"=>""
}'

Resources