Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a elegant way in Ruby to tell if a variable is a Hash or an Array?

Tags:

arrays

ruby

hash

People also ask

How do you check if something is a hash in Ruby?

Overview. A particular value can be checked to see if it exists in a certain hash by using the has_value?() method. This method returns true if such a value exists, otherwise false .

What is the difference between a hash and an array in Ruby?

Ruby's arrays and hashes are indexed collections. Both store collections of objects, accessible using a key. With arrays, the key is an integer, whereas hashes support any object as a key.

How do you define a hash in Ruby?

In Ruby you can create a Hash by assigning a key to a value with => , separate these key/value pairs with commas, and enclose the whole thing with curly braces.

What does .first mean in Ruby?

The first() is an inbuilt method in Ruby returns an array of first X elements. If X is not mentioned, it returns the first element only. Syntax: range1.first(X) Parameters: The function accepts X which is the number of elements from the beginning. Return Value: It returns an array of first X elements.


You can just do:

@some_var.class == Hash

or also something like:

@some_var.is_a?(Hash)

It's worth noting that the "is_a?" method is true if the class is anywhere in the objects ancestry tree. for instance:

@some_var.is_a?(Object)  # => true

the above is true if @some_var is an instance of a hash or other class that stems from Object. So, if you want a strict match on the class type, using the == or instance_of? method is probably what you're looking for.


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.


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

Hash === @some_var #=> return Boolean

this can also be used with case statement

case @some_var
when Hash
   ...
when Array
   ...
end

I use this:

@var.respond_to?(:keys)

It works for Hash and ActiveSupport::HashWithIndifferentAccess.


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.


You can use instance_of?

e.g

@some_var.instance_of?(Hash)