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

jpw*_*ynn 25 ruby each ruby-on-rails

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

似乎如果我说phonelist.each do |phone|如果phonelist是空的,那么不应该执行该块.

但是在我看来(haml)我有- @myvar.phonelist.each do |phone|,如果phonelist是空的,它会抛出一个NoMethodError.

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

joh*_*x25 44

您可以使用try方法在nil上调用.each,以便在对象为nil或为空时不会抛出错误.

phonelist = nil
phonelist.try(:each){|i| puts i}
Run Code Online (Sandbox Code Playgroud)

  • 我同意最好确保你永远不会得到一个零,但我不明白为什么添加一个if语句是一个更好的解决方案然后使用try.任何一种方法都应该完成这项工作. (8认同)
  • 我想我不认为必须重复变量名称在每种情况下都更清晰或更简单(特别是如果使用长变量名称),但尝试的好处是你可以继续将方法链接在一起而不必分解它用if.这当然取决于具体情况. (6认同)
  • 我想我不明白为什么人们会诉诸这样的事情,因为最好简单地确保不应该为零的东西永远不会为零。如果无法做到这一点(无论出于何种原因),为什么要这样做而不是简单的 if 语句?我不明白。 (2认同)

Ark*_*kan 30

只需执行以下操作:

Array(phonelist).each do |phone|
  #deal with your phone
end
Run Code Online (Sandbox Code Playgroud)

如果my_variable为nil,Array(my_variable)将确保返回一个数组.

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


Ed *_* S. 16

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

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

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

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

不.如果phonelist 不是实现.each的对象则抛出错误.非常不一样.

如果为null,你总是可以将它初始化为一个空数组,即phonelist ||= [],但我更喜欢一种只要有可能就能确保有效数据的设计.


Gra*_*ier 6

不敢相信还没有人提出这个建议:

(@myvar.phonelist || []).each do |phone|
   ...
Run Code Online (Sandbox Code Playgroud)

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

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