KyKy
KyKy

Reputation: 53

Ruby - NoMethodError, but why only sometimes?

I am working on a script to pull comments for a subreddit, break out the individual words, count them, and sort them. Roughly 70% of the time I get this error:

in `<main>': undefined method `map' for nil:NilClass (NoMethodError) Did you mean?  tap

About 30% of the time, the script works as intended. Why is this happening? And how would you resolve? I'm new to programming so won't be surprised if the issue is basic. Here is my code:

require 'net/http'
require 'rubygems'
require 'json'

# Pull json file, parse out comments
url = 'https://www.reddit.com/r/askreddit/comments.json?sort=top&t=all&limit=100'
uri = URI(url)
response = Net::HTTP.get(uri)
json = JSON.parse(response)

comments = json.dig("data", "children").map { |child| child.dig("data", "body") }

#Split words into array
words = comments.to_s.split(/[^'\w]+/)

words.delete_if { |a,_| a.length < 5}

#count and sort words
count = Hash.new(0)
words.each { |word| count.store(word, count[word]+1)}
count.delete_if { |_,b| b < 4}
sorted = count.sort_by { |word,count| count}.reverse
puts sorted

Upvotes: 1

Views: 87

Answers (2)

omikes
omikes

Reputation: 8523

There is basically an error on Reddit's side. I've written a work-around, but it sometimes has a small delay; it tries over and over until it succeeds. Edited to (mostly) match your original code.

require 'net/http'
require 'rubygems'
require 'json'

# Pull json file, parse out comments
url = 'https://www.reddit.com/r/askreddit/comments.json?sort=top&t=all&limit=100'
uri = URI(url)
error = true
while error
   response = Net::HTTP.get(uri)
   json = JSON.parse(response)
   error = json["error"]
end

comments = json.dig("data", "children").map { |child| child.dig("data", "body") }

#Split words into array
words = comments.to_s.split(/[^'\w]+/)

words.delete_if { |a,_| a.length < 5}

#count and sort words
count = Hash.new(0)
words.each { |word| count.store(word, count[word]+1)}
count.delete_if { |_,b| b < 4}
sorted = count.sort_by { |word,count| count}.reverse
puts sorted

Upvotes: 0

ragurney
ragurney

Reputation: 444

It looks like your json.dig("data", "children") is occasionally returning nil. One way to gracefully handle this is by using the safe navigation operator (&.):

comments = json.dig("data", "children")&.map { |child| child.dig("data", "body") }

if comments
  # your other logic with comments here
else
  {}
end

Upvotes: 1

Related Questions