要检查@some_var
是什么,我正在做
if @some_var.class.to_s == 'Hash'
我确信有更优雅的方法来检查@some_var
是Hash
还是Array
。
答案 0 :(得分:230)
你可以这样做:
@some_var.class == Hash
或类似的东西:
@some_var.is_a?(Hash)
值得注意的是“is_a?”如果类在对象祖先树中的任何位置,则方法为true。例如:
@some_var.is_a?(Object) # => true
如果@some_var是源自Object的散列或其他类的实例,则上述情况属实。那么,如果你想要类类型的严格匹配,使用==或instance_of?方法可能就是你要找的东西。
答案 1 :(得分:35)
首先,文字问题的最佳答案是
Hash === @some_var
但问题确实应该通过展示如何在这里进行鸭子打字来回答。 这取决于你需要什么样的鸭子。
@some_var.respond_to?(:each_pair)
或
@some_var.respond_to?(:has_key?)
甚至
@some_var.respond_to?(:to_hash)
可能是正确的,具体取决于申请。
答案 2 :(得分:25)
通常在红宝石中,当你在寻找“类型”时,你实际上想要的是“鸭型”或“像鸭子那样呱呱叫吗?”。你会看到它是否响应某种方法:
@some_var.respond_to?(:each)
你可以迭代@some_var,因为它响应:每个
如果您真的想知道类型,如果它是Hash或Array,那么您可以这样做:
["Hash", "Array"].include?(@some_var.class) #=> check both through instance class
@some_var.kind_of?(Hash) #=> to check each at once
@some_var.is_a?(Array) #=> same as kind_of
答案 3 :(得分:11)
Hash === @some_var #=> return Boolean
这也可以与案例陈述
一起使用case @some_var
when Hash
...
when Array
...
end
答案 4 :(得分:4)
我用这个:
@var.respond_to?(:keys)
适用于Hash和ActiveSupport :: HashWithIndifferentAccess。
答案 5 :(得分:4)
在实践中,您通常希望采取不同的行动,具体取决于变量是数组还是哈希,而不仅仅是告诉。在这种情况下,优雅的成语如下:
case item
when Array
#do something
when Hash
#do something else
end
请注意,您不要在.class
上调用item
方法。
答案 6 :(得分:2)
您可以使用instance_of?
e.g
@some_var.instance_of?(Hash)
答案 7 :(得分:0)
如果要测试对象是否严格或扩展了Hash
,请使用:
value = {}
value.is_a?(Hash) || value.is_a?(Array) #=> true
但是要使Ruby的鸭子打字更有价值,您可以执行以下操作:
value = {}
value.respond_to?(:[]) #=> true
当您只想使用value[:key]
语法访问某些值时,这很有用。
请注意,
Array.new["key"]
将引发TypeError
。
答案 8 :(得分:-1)
irb(main):005:0> {}.class
=> Hash
irb(main):006:0> [].class
=> Array