2013-02-14 54 views
0

怎么可能变量的简单和直接的方式在这种情况下分配的:分配变量与可选呈现阵列

interface = reply[:user][:interface][:data][0][:value].presence || 'simple' 

如果数组键reply[:user][:interface]存在 - 我把整个数据链(以这种情况下),但如果它不 - 我得到undefined method '[]' for nil:NilClass。一般来说,我想要一个方法来分配默认值,如果任何一个路径中的键不存在。现在我这样做:

a = b[:asd][:qwe] rescue 5 

它的工作,但看起来不正确的方式。

+0

嗯..所以处理这个最好的办法就是不要有可变的结构从API,如果可能的。谢谢。 – lifecoder 2013-02-14 19:32:54

回答

0

像这样调用rescue的问题是,它会捕获比您想要的更多的错误,因此可以隐藏问题。因此,“有道”是抢救上只有你所期望的错误:

begin 
    reply[:user][:interface][:data][0][:value].presence || 'simple' 
rescue NoMethodError 
    'simple' 
end 
+0

即使这可能会产生意想不到的结果,如果“存在”或“答复”本身是不确定的。这里很难简洁和正确。 – 2013-02-14 17:17:04

0
interface = [:user, :interface, :data, 0, :value] 
.inject(reply){|h, k| h = h.fetch(k, {})} 
.presence || 
'simple' 
+0

不错的解决方案,但只有当方法具有相同类型的返回值(散列)时才有效,可以改进为.inject(reply){| h,k | h.nil? ? h:h [k]}。 – 2013-02-14 16:02:04

0

我认为你的代码有一个误解。

你不应该直接对reply[:user][:interface][:data][0][:value]如果[:interface]可能会错过,但更多的像

reply[:user].has_key?(:interface) && reply[:user][:interface][:data][0][:value] 

如果最重要的是工作,[:data][:data][0][:data][0][:value]可以丢失,那么你应该做一些验证之前使用所有这些数据。

+1

谢谢,我纠正了。 – ByScripts 2013-02-14 16:06:45

+0

一般而言,我有一些结构,我无法预测哪个键会被遗漏。我有很多。 – lifecoder 2013-02-15 07:56:22

0

一个通用的模式为“守卫方法链”是使用是https://github.com/raganwald/andand 这样,你可以写(信用泽):

interface = [:user, :interface, :data, 0, :value] 
.inject(reply){|h, k| h.andand[k] } || 'simple' 

不过说实话往往更好的风格是明确