Rails 3.1:Ruby成语,以防止.each抛出异常,如果为nil?

时间:2012-03-06 23:44:27

标签: ruby-on-rails ruby each

有没有办法使用.each所以如果对象为nil或为空(不添加额外的nil / blank测试,它不会抛出错误?

如果我说phonelist.each do |phone|,如果phonelist为空,那么该块就不应该被执行了。

但在我看来(haml)我有- @myvar.phonelist.each do |phone|,如果phonelist为空,则会抛出NoMethodError。

我遇到了很多,并且总是通过为.blank添加显式检查/分支来解决这个问题?但似乎应该有一种更简单的方法来告诉。每个空手段什么都不做。

6 个答案:

答案 0 :(得分:44)

您可以使用try方法在nil上调用.each,这样如果对象为nil或为空,则不会抛出错误。

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

答案 1 :(得分:29)

只需执行以下操作:

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

如果my_variable为nil,则数组(my_variable)将确保返回数组。

如果my_variable已经是一个数组,它不会创建一个新的数组,所以在任何你想要的地方使用它都是安全和轻松的!

答案 2 :(得分:15)

你正试图在一个更大的问题上打造一个创可贴。

Ruby有一个nil的概念;不能绕过它。如果您在nil上调用方法,那么您认为它是有效的,即您的设计认为它是有效的。所以问题确实是:你设计中的洞在哪里?为什么你的假设不正确?

这里的问题不是你不能在不支持它的对象上调用任意方法;问题是,当显然并非总是如此时,假设您的数据是有效的。

  

但在我看来(haml)我有 - @ myvar.phonelist.each做|电话|如果phonelist为空,则会抛出NoMethodError。

没有。如果phonelist 不是实现.each 的对象,则会引发错误。非常不同。

如果为null,您可以随时将其初始化为空数组,即phonelist ||= [],但我希望设计尽可能确保有效数据。

答案 3 :(得分:2)

如果您从散列中获取phonelist(例如已解析的JSON文件),则可能需要fetch使用[]作为默认值。

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

答案 4 :(得分:2)

不敢相信还没有人建议过

(@myvar.phonelist || []).each do |phone|
   ...

如果phonelistnil,则each将在空数组上循环,执行该块零次。

但是,如果phonelist不是可枚举的(例如数组),这仍然会引发异常。

答案 5 :(得分:1)

只需确保空phonelist[],而不是nil值。

或者,Ruby中的nil值为false,因此您可以使用nil-punning

if phonelist
   phonelist.each do |phone|
     ...