Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

undefined method '[]' for nil:NilClass

Tags:

ruby

I'm writing a quick script to extract data from a device with a CLI via telnet. I could use a little help with an error that I'm not sure how to handle.

res = nil
res = t.cmd('actual command').match(/Calls:\s(\d{1,})/)[1].to_i

In some cases, the device is printing out all kinds of autonomous output at a rapid rate. Also, during this time, the device sometimes doesn't return all of the output which results in no match. Thus, I get the following error:

in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)

I've tried a few different things and can't seem to get past this issue. Thank you for any help with this.

like image 759
Rob Avatar asked Dec 08 '22 21:12

Rob


1 Answers

When you see undefined method '[]' for nil:NilClass it means:

Hey! You have a value that is nil followed by [...], but nil doesn't have this method.

In this case, your problem is that match(...) is sometimes failing to match the text you want, returning nil, and then you can't ask for [1] of that. Some direct approaches to avoid this are:

match = t.cmd('actual command').match(/Calls:\s(\d{1,})/)
res = match && match[1].to_i

# or
res = match[1].to_i if match

# or 
res = if (match=t.cmd('actual command').match(/Calls:\s(\d{1,})/))
  match[1].to_i
end

# or
res = (match=t.cmd('actual command').match(/Calls:\s(\d{1,})/)) && match[1].to_i

However, a simpler solution is to use the String#[] method to pull out the regex capture directly:

res = t.cmd('actual command')[/Calls:\s(\d+)/,1]
res = res.to_i if res

This form automatically returns nil for you if the regex fails, and you don't want to call to_i on nil.

I also cleaned up your regex a little, since \d{1,} is equivalent to \d+.

like image 196
Phrogz Avatar answered Dec 21 '22 23:12

Phrogz