JChris
JChris

Reputation: 1678

Simple JSON not working in Ruby

Code:

#!/usr/bin/ruby
require 'rubygems'
require 'open-uri'
require 'json'

def getData
    file = open("http://goo.gl/BI6h7a")
    @json = JSON.parse(file.read)
end

getData

cveIds = @json['cve_id']
puts cveIds

You can see the JSON response here: http://goo.gl/BI6h7a

Console:

./cve.rb:13:in `[]': can't convert String into Integer (TypeError) from ./cve.rb:13:in `<main>'

I don't know why this is happening. "Convert String into Integer"? WHAT?

The @json gets the content fine, but the cveIds doesn't.

Upvotes: 0

Views: 177

Answers (3)

Tamer Shlash
Tamer Shlash

Reputation: 9523

The top element in the json that you're reading is actually an Array, each of its elements is actually a hash, it's like this:

[
    {
        "cve_id": "CVE-2014-3976"
        // other key/value pairs
    }
    {
        "cve_id": "CVE-2014-3975"
        // other key/value pairs
    }
    {
        "cve_id": "CVE-2014-3974"
        // other key/value pairs
    }
    // .... more hashes
]

so @json is an array. And if you want to access any of its elements you have to access it with a numeric integer index like, so:

@json[0] # => { "cve_id": "CVE-2014-3976", // other key/value pairs }

I think you are trying to collect the cve_id fields of all these hashes, this can be done as follows:

cveIds = @json.collect { |h| h["cve_id"] }

# The result:
=> ["CVE-2014-3976", "CVE-2014-3975", "CVE-2014-3974", "CVE-2014-3962", "CVE-2014-3961",
"CVE-2014-3878", "CVE-2014-3871", "CVE-2014-3842", "CVE-2014-3806", "CVE-2014-3792",
"CVE-2014-3791", "CVE-2014-3443", "CVE-2014-3247", "CVE-2014-3246", "CVE-2014-3225",
"CVE-2014-3216", "CVE-2014-3139", "CVE-2014-3138", "CVE-2014-3008", "CVE-2014-2996",
"CVE-2014-2994", "CVE-2014-2976", "CVE-2014-2850", "CVE-2014-2847", "CVE-2014-2671",
"CVE-2014-2668", "CVE-2014-2588", "CVE-2014-2587","CVE-2014-2586", "CVE-2014-2579"]

Upvotes: 2

Martin Konecny
Martin Konecny

Reputation: 59681

cveIds = @json['cve_id']

What are you doing here is equivalent to:

arr = [1, 2, 3, 4]
puts arr["hello"] # using a string here on an indexed based array!

Hence your error message about Ruby trying to convert a String to an int.

Try the following instead

cveIds = @json.first['cve_id'] # equivalent to @json[0]['cve_id']
puts cveIds

In the above code sample, we are getting the first element from the array, which is a hash we can then access cve_id from.

Upvotes: 1

Vor
Vor

Reputation: 35149

I'm not a ruby developer but what you have there is a list if dictionaries. My guess in order for you to read cve_id you need to create some kind of a for loop.

for example in python I would write it like this:

for line in my_data:
  print line['cve_id']

I guess in ruby it would look like this:

for i in @json do
    cveIds = i['cve_id']
    puts cveIds
end

Upvotes: 1

Related Questions