要检查@some_var
是什么,我正在做一个
if @some_var.class.to_s == 'Hash'
我确信有一种更优雅的方法来检查@some_var
是Hash
还是Array
。
您可以做:
@some_var.class == Hash
或也类似:
@some_var.is_a?(Hash)
值得注意的是,“ is_a?”如果该类在对象祖先树中的任何位置,则方法为true。例如:
@some_var.is_a?(Object) # => true
如果@some_var是源自Object的哈希或其他类的实例,则为true。因此,如果要对类类型进行严格匹配,请使用==或instance_of?方法可能是您要寻找的。
首先,对于字面问题的最佳答案是
Hash === @some_var
但是这个问题确实应该通过在此处显示如何进行鸭式打字来回答。这取决于您需要哪种鸭子。
@some_var.respond_to?(:each_pair)
或
@some_var.respond_to?(:has_key?)
甚至
@some_var.respond_to?(:to_hash)
可能取决于应用程序。
通常在红宝石中,当您寻找“类型”时,您实际上想要的是“鸭子类型”或“像鸭子一样嘎嘎吗?”。您将看到它是否响应某种方法:
@some_var.respond_to?(:each)
您可以遍历@some_var,因为它会响应:each
如果您真的想知道类型,并且它是哈希或数组,则可以:
["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
Hash === @some_var #=> return Boolean
也可以与case语句一起使用
case @some_var
when Hash
...
when Array
...
end
我使用这个:
@var.respond_to?(:keys)
它适用于Hash和ActiveSupport :: HashWithIndifferentAccess。
实际上,您经常希望根据变量是数组还是哈希而不是仅仅告诉变量来采取不同的行动。在这种情况下,elegant习惯用法如下:
case item
when Array
#do something
when Hash
#do something else
end
请注意,您不会在.class
上调用item
方法。
您可以使用instance_of?
例如
@some_var.instance_of?(Hash)
如果要测试对象是否严格或扩展了Hash
,请使用:
value = {}
value.is_a?(Hash) || value.is_a?(Array) #=> true
但是要让Ruby的鸭子打字更有价值,您可以做类似的事情:
value = {}
value.respond_to?(:[]) #=> true
仅在您只想使用value[:key]
语法访问某些值时很有用。
请注意,
Array.new["key"]
将引发TypeError
。
irb(main):005:0> {}.class
=> Hash
irb(main):006:0> [].class
=> Array