我有很多模型和关联。因此,在视图/控制器中有很多调用,看起来像这样:
@object.something.with_something.value
某些链的部分可能最终变成nil,这是完全可以接受的。检查终端对象的存在的正确/清洁/快速方法是什么?
像这样调用是否正确:
@object.something.with_something.value if defined? @object.something.with_something.value
考虑是否可行?
我有很多模型和关联。因此,在视图/控制器中有很多调用,看起来像这样:
@object.something.with_something.value
某些链的部分可能最终变成nil,这是完全可以接受的。检查终端对象的存在的正确/清洁/快速方法是什么?
像这样调用是否正确:
@object.something.with_something.value if defined? @object.something.with_something.value
考虑是否可行?
&&
运算符(而不是defined?
),但这样很快就会变得非常冗长。(@object && @object.something && @object.something.with_something &&
@object.something.with_something.value)
@object.try(:something).try(:with_something).try(:value)
或者安装调用构建工具包并使用其守护式评估工具:
Ick::Maybe.belongs_to YourClass
maybe(@object) { |obj| obj.something.with_something.value }
@object.something.with_something.value if @object.something.with_something
我可能会利用以下事实:
nil.to_a => []
nil.to_s => ''
nil.to_f => 0.0
nil.to_i => 0
因此,如果您知道某个东西是nil
或一个Array
,通常可以通过编写以下内容来编写更好的代码而无需任何条件语句:
something.to_a.each do |e|
. . .
nil
有专门的Object
的to_x函数时,我想:Matz真是个天才。例如,**(something.somethingelse || []).each do**相比之下真的有点笨拙。 - DigitalRosswhat.you.are.doing
有时被称为“火车失事”,也被描述为违反Demeter法则。
话虽如此,我认为有一种叫做“andand”的东西可以帮助你解决目前的问题。
Object#andand
是一种解决方案,但我尽量避免使用它——引入一个本质上只提供了一个方法的依赖关系有点奇怪。此外,默认情况下它会对 Object
类进行猴子补丁,这是很糟糕的。 - Bob Aman另一个选择是使用空对象模式来确保这些对象中没有一个是nil。可以说,如果您的代码要以这种方式链接访问,那么某些东西应该始终被定义。
maybe
的方式。它提供了一个IdentityWrapper
和一个GuardWrapper
。GuardWrapper
的目的与该模式中的空对象基本相同,只不过当块评估完成时,包装器可以自动剥离。 - Bob Aman
@object.something.with_something.value
是否为nil
,还是担心链中的任何内容都是nil
时引发的NoMethodError
?我猜想是后者? - Bob Aman