说我有一个User
对象,它有一个email
财产,我需要他们的大写最后一个字母email
:
u = User.find(1)
letter = u.email.upcase.last
If u
or email
is nil
在这个链中,然后我得到一个NoMethodError: undefined method 'blah' for nil:Nilclass
。在大多数情况下我应该能够解决这个问题,但有时,nil
到达不该到达的地方或难以控制的地方。一种方法会很冗长:
u = User.find(1)
letter = nil
if u && u.email
letter = u.email.upcase.last
end
但从某种角度来看,或者从一长串的角度来看,这会变得烦人且危险。a.bunch.of.properties.down.a.hierarchy
。我读到try
Rails 中的方法:
u = User.find(1)
letter = u.try(:email).try(:upcase).try(:last)
这不太冗长,但我觉得写所有这些尝试很恶心。一旦我把try
在链条中,我必须一直使用它们。有没有更好的办法?
我喜欢用空对象模式 https://en.wikipedia.org/wiki/Null_Object_pattern. Avdi 有一篇很棒的文章解释了这一点 http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/,但基本思想是你有一个小类可以代表一个对象并合理地响应你可能传递给原始对象的消息。我发现这些不仅有助于避免NoMethodError
还可以用于设置默认值/友好消息。
例如,你可以这样做:
class NilUser
def email
"(no email address)"
end
end
u = User.find(1) || NilUser.new
u.email.upcase.last # => No errors!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)