考虑存储在哈希中的"人".两个例子是:
fred = {:person => {:name => "Fred", :spouse => "Wilma", :children => {:child => {:name => "Pebbles"}}}}
slate = {:person => {:name => "Mr. Slate", :spouse => "Mrs. Slate"}}
Run Code Online (Sandbox Code Playgroud)
如果"人"没有任何子女,则"儿童"元素不存在.所以,对于Slate先生,我们可以检查他是否有父母:
slate_has_children = !slate[:person][:children].nil?
Run Code Online (Sandbox Code Playgroud)
那么,如果我们不知道"slate"是一个"人"哈希呢?考虑:
dino = {:pet => {:name => "Dino"}}
Run Code Online (Sandbox Code Playgroud)
我们不能再轻易检查孩子了:
dino_has_children = !dino[:person][:children].nil?
NoMethodError: undefined method `[]' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)
那么,你如何检查哈希的结构,特别是如果它被深深嵌套(甚至比这里提供的例子更深)?也许更好的问题是:这样做的"红宝石方式"是什么?
如果我尝试访问不存在的哈希元素,我会得到NoMethodError: undefined method '[]' for nil:NilClass.但是,我无法预测哪些元素会出现.
@param_info = {}
@param_info["drug"]["name"]
# => NoMethodError: undefined method `[]' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)
如果元素意外出现,如何避免引发此错误nil?
我在这里从这个答案中了解到这是可能的:
h = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
h['bar'] # => {}
h['tar']['star']['par'] # => {}
Run Code Online (Sandbox Code Playgroud)
有人能解释它是如何工作的吗?
所以我想根据是否给出输入有条件地分配变量.
例如
@name = params[:input]['name'] || "Name not yet given"
Run Code Online (Sandbox Code Playgroud)
但是,如果尚未传递参数,则会出错
method [] does not exist for nil class
Run Code Online (Sandbox Code Playgroud)
我有两个想法来解决这个问题.一个是将[]方法添加到nil类.就像是:
class NilClass
def []
self
end
end
Run Code Online (Sandbox Code Playgroud)
而我的另一个想法是使用if语句
if params[:input].nil?
@name = params[:input]['name']
else
@name = "Name not yet given"
end
Run Code Online (Sandbox Code Playgroud)
但是,这些解决方案都不是很正确.
什么是"红宝石方式"?
我最近在寻找一种在Ruby中正确创建和使用嵌套哈希的方法.我及时找到了Paul Morie的解决方案,他回答了自己的问题:
hash = Hash.new { |h,k| h[k] = {} }
我很快就使用了这个,很高兴报告它有效.但是,正如标题所说,我希望"辅助","内部"哈希默认返回0.
我知道你可以在构造函数(" Hash.new(0)")或使用.default(" hash.default(0)")中定义散列的默认返回值.
但是你如何用哈希中的哈希来做到这一点?