ruby-on-rails Rails3.1:Ruby习惯用法防止.each在nil时抛出异常?

piztneat  于 2023-01-22  发布在  Ruby
关注(0)|答案(7)|浏览(109)

有没有一种方法可以使用.each,使它在对象为nil或空时不会抛出错误(而不添加额外的nil/blank测试?)
看起来,如果我说phonelist.each do |phone|,如果phonelist是空的,那么这个块就不应该被执行。
但是在我的视图(haml)中,我有- @myvar.phonelist.each do |phone|,如果phonlist为空,它会抛出NoMethodError。
我经常遇到这种情况,并且总是通过为.blank添加一个显式的检查/分支来解决,但是似乎应该有一个更简单的方法来判断.每个空意味着什么都不做。

drnojrws

drnojrws1#

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

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

mwecs4sa2#

只需执行以下操作:

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

Array(my_variable)将确保在my_variable为nil时返回一个数组。
如果my_variable已经是一个数组,它不会创建一个新的Array,所以在任何地方使用它都是安全和轻便的!

xam8gpfp

xam8gpfp3#

你想用创可贴解决更大的问题。
Ruby有nil的概念;如果你在nil上调用一个方法,那么你就假设它是有效的,也就是说,你的 * 设计 * 假设它是有效的。你的设计中的漏洞在哪里?2为什么你的假设是不正确的?
这里的问题不是你不能在一个不支持任意方法的对象上调用它;问题是你的数据被假定为有效的,而事实显然并非总是如此。
但是在我看来(haml)我有- @myvar.phonelist.每个都有|电话|如果phonelist为空,则抛出NoMethodError。
不可以。如果phonelist * 不是一个实现.each * 的对象,它就会抛出一个错误。
如果为null,则可以将其初始化为空数组,即phonelist ||= [],但我更喜欢尽可能确保数据有效的设计。

zaq34kh6

zaq34kh64#

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

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

如果phonelistnil,则each将在空数组上循环,执行块零次。
但是,如果phonelist不是可枚举的(例如数组),这仍然会抛出异常。

afdcj2ne

afdcj2ne5#

如果您从散列(例如解析的JSON文件)中获得phonelist,您可能希望使用fetch,并将[]作为默认值。

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

68de4m5k6#

只需确保空的phonelist[],而不是nil值。
或者,nil值在Ruby中为falsey,因此可以使用nil-punning

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

u91tlkcl7#

我见过很多人做的是

@myvar.phonelist.each do |phone|
  # ...
end unless @myvar.phonelist.nil?

相关问题