为了检查 @some_var是什么,我正在做一个
@some_var
if @some_var.class.to_s == 'Hash'
我确信有一个更优雅的方法来检查 @some_var是 Hash还是 Array。
Hash
Array
你可以使用 instance_of?
instance_of?
例如:
@some_var.instance_of?(Hash)
你可以这样做:
@some_var.class == Hash
或者类似这样的东西:
@some_var.is_a?(Hash)
值得注意的是“ is _ a?”如果该类位于对象祖先树中的任何位置,则。例如:
@some_var.is_a?(Object) # => true
如果@some _ var 是散列或其他源自 Object 的类的实例,则上述条件为真。那么,如果您希望对类类型进行严格匹配,使用 = = 或 instance _ of?方法可能就是你要找的。
irb(main):005:0> {}.class => Hash irb(main):006:0> [].class => Array
通常在红宝石中,当你在寻找“类型”时,你实际上想要的是“鸭子类型”或“像鸭子一样嘎嘎叫吗?”.你会看到它是否对某种方法有反应:
@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
首先,字面上的问题的最佳答案是
Hash === @some_var
但是这个问题真的应该通过在这里展示如何使用 Duck 键入来回答。 这取决于你需要什么样的鸭子。
@some_var.respond_to?(:each_pair)
或者
@some_var.respond_to?(:has_key?)
甚至
@some_var.respond_to?(:to_hash)
可能是正确的,这取决于申请。
我用这个:
@var.respond_to?(:keys)
它适用于 Hash 和 ActiveSupport: : HashWithIndifferent entAccess。
在实践中,您通常希望根据变量是 Array 还是 Hash 而采取不同的行为,而不仅仅是告诉。在这种情况下,优雅惯用语如下:
case item when Array #do something when Hash #do something else end
请注意,不要在 item上调用 .class方法。
item
.class
如果您想测试一个对象是严格的还是扩展了 Hash,请使用:
value = {} value.is_a?(Hash) || value.is_a?(Array) #=> true
但是为了让 Ruby 的 Duck 键入变得有价值,你可以这样做:
value = {} value.respond_to?(:[]) #=> true
当您只想使用 value[:key]语法访问某些值时,它非常有用。
value[:key]
请注意,Array.new["key"]将提高一个 TypeError。
Array.new["key"]
TypeError