'What is an elegant way in Ruby to tell if a variable is a Hash or an Array?
To check what @some_var is, I am doing a
if @some_var.class.to_s == 'Hash'
I am sure that there is a more elegant way to check if @some_var is a Hash or an Array.
Solution 1:[1]
First of all, the best answer for the literal question is
Hash === @some_var
But the question really should have been answered by showing how to do duck-typing here. That depends a bit on what kind of duck you need.
@some_var.respond_to?(:each_pair)
or
@some_var.respond_to?(:has_key?)
or even
@some_var.respond_to?(:to_hash)
may be right depending on the application.
Solution 2:[2]
Usually in ruby when you are looking for "type" you are actually wanting the "duck-type" or "does is quack like a duck?". You would see if it responds to a certain method:
@some_var.respond_to?(:each)
You can iterate over @some_var because it responds to :each
If you really want to know the type and if it is Hash or Array then you can do:
["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
Solution 3:[3]
Hash === @some_var #=> return Boolean
this can also be used with case statement
case @some_var
when Hash
...
when Array
...
end
Solution 4:[4]
I use this:
@var.respond_to?(:keys)
It works for Hash and ActiveSupport::HashWithIndifferentAccess.
Solution 5:[5]
In practice, you will often want to act differently depending on whether a variable is an Array or a Hash, not just mere tell. In this situation, an elegant idiom is the following:
case item
when Array
#do something
when Hash
#do something else
end
Note that you don't call the .class method on item.
Solution 6:[6]
You can use instance_of?
e.g
@some_var.instance_of?(Hash)
Solution 7:[7]
If you want to test if an object is strictly or extends a Hash, use:
value = {}
value.is_a?(Hash) || value.is_a?(Array) #=> true
But to make value of Ruby's duck typing, you could do something like:
value = {}
value.respond_to?(:[]) #=> true
It is useful when you only want to access some value using the value[:key] syntax.
Please note that
Array.new["key"]will raise aTypeError.
Solution 8:[8]
irb(main):005:0> {}.class
=> Hash
irb(main):006:0> [].class
=> Array
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Brandon |
| Solution 3 | GutenYe |
| Solution 4 | drinor |
| Solution 5 | Daniel Szmulewicz |
| Solution 6 | Shiv |
| Solution 7 | Vinicius Brasil |
| Solution 8 | Spyros |
