Rails 3.1: Ruby idiom to prevent .each from throwing exception if nil?

SOLVED: AS SOME COMMENTORS NOTED, AN EMPTY PHONELIST WAS NIL WHEN SHOULD HAVE BEEN [].

Is there a way to use .each so it does not throw an error if the object is nil or empty (without adding an additional nil/blank test?

It seems that if I say phonelist.each do |phone| that if phonelist is empty, then the block should not be executed.

But in my view (haml) I have – @myvar.phonelist.each do |phone| and if phonelist is empty, it throws a NoMethodError.

I run into this a lot, and always workaround by adding an explicit check/branch for .blank? but it seems there should be an easier way to tell .each that empty means do nothing.

Ruby idiom for “foo.nil? ? nil : foo.to_i”?

def bar(foo) foo.nil? ? nil : foo.to_i end Any concise Ruby idiom for foo.nil? ? nil : foo.to_i ?

Prevent JSON serialization from throwing an exception in Python

What is a good way to prevent the python’s json library from throwing an exception when it encounters objects that it does not know how to serialize? We are using json to serialize dict objects, somet

Ruby “return unless nil” idiom

I’ve got a smelly method like: def search_record(*args) record = expensive_operation_1(foo) return record unless record.nil? record = expensive_operation_2(foo, bar) return record unless record.nil? r

Ruby string initialized with nil causes exception

Why does a Ruby String initialized with nil cause this exception? irb(main):001:0> String.new(nil) TypeError: no implicit conversion of nil into String from (irb):1:in `initialize’ from (irb):1:in

Prevent code from throwing XML exception

In the following piece of code : try{ …. } catch(Exception e) { logger.error(Exception caught in method: /n); logger.error(e.getMessage()); String fault = <Fault><FaultCode> + e.getC

Best ruby idiom for “nil or zero”

I am looking for a concise way to check a value to see if it is nil or zero. Currently I am doing something like: if (!val || val == 0) # Is nil or zero end But this seems very clumsy.

ArangoDB Transactions – How prevent from throwing exceptions

How to prevent ArangoDB from throwing an exception during the Transaction when looking for a specific document which perhaps does not exist at that moment? Nodejs sends the transaction in one block to

Ruby on Rails Error: The error occurred while evaluating nil.each

I’m trying to learn Ruby but I geep getting this error: The error occurred while evaluating nil.each I was reading here the Getting started guide http://guides.rubyonrails.org/getting_started.html H

Rails idiom for .present? and .any?

Is there a Rails/Ruby idiom for checking if an enumerable is both present and has non-nil values? I get errors if I ever try to do nil.any? so I always have to do if foo && foo.any?.

how to not iterate nil array ruby?

i want prevent iteration of nil array. How its should be done in ruby? My bad solution: if nil!=myArr myArr.each { |item| p item; } end

Answers

You’re attempting to smack a band-aid on a larger problem.

Ruby has a concept of nil; can’t get around it. If you are calling a method on nil, then you are assuming it is valid, i.e., your design assumes it to be valid. So the question really is: where is the hole in your design? Why is your assumption incorrect?

The problem here is not that you cannot call arbitrary methods on an object which does not support it; the problem is that your data is assumed to be valid when obviously that is not always the case.

But in my view (haml) I have – @myvar.phonelist.each do |phone| and if phonelist is empty, it throws a NoMethodError.

No. If phonelist is not an object which implements .each it throws an error. Very different.

You can always initialize it to an empty array if null, i.e., phonelist ||= [], but I would prefer a design which ensures valid data whenever possible.

You can use the try method to call .each on a nil so it does not throw an error if the object is nil or empty.

phonelist = nil
phonelist.try(:each){|i| puts i}

Simply do the following:

Array(phonelist).each do |phone|
  #deal with your phone
end

Array(my_variable) will ensure to return an array if my_variable is nil.

It doesn’t create a new Array if my_variable is already an array, so it is safe and light to use it wherever you want !

If you get phonelist from a hash (e.g. parsed JSON file), you may want to use fetch with [] as the default.

phonelist = my_data.fetch('phonelist', [])