How to check if an object is iterable in Ruby?

Because Range responds to each even when it isn't iterable you need to specifically check that the Range's elements respond to succ

def iterable?(object)
  return object.begin.respond_to? :succ if object.kind_of? Range
  object.respond_to? :each
end

For my purposes, let's say iterable is something you can do .each to.

You can just ask if this object has this method

def iterable?(object)
  object.respond_to?(:each)
end

You already got some answers, but here are two more ways, Object#is_a?/Object#kind_of? and Module#===:

  [].is_a? Enumerable #=> true
  "".is_a? Enumerable #=> false

  Enumerable === [] #=> true
  Enumerable === "" #=> false

There are a number of ways to do this, depending on your larger goals and what you need to do with the result.

  1. If you just want to use duck typing to see if the object responds to #each, then you can just ask the object if it has such a method.

    my_object.respond_to? :each
    
  2. If you want to find out if the object mixes in the Enumerable class, you can check the class for inclusion.

    my_object.class.include? Enumerable
    
  3. If you want a list of all the ancestors and mixins, you want the #ancestors method. For example, to see whether my_object inherits from the Enumerable class, you could invoke:

    my_object = []
    my_object.class.ancestors
    => [Array, Enumerable, Object, PP::ObjectMixin, Kernel, BasicObject]
    
    my_object.class.ancestors.include? Enumerable
    => true
    

Tags:

Ruby