Подтвердить что ты не робот

Как проверить, является ли объект итерируемым в Ruby?

Как проверить, является ли объект итерируемым в Ruby?

То есть, мне нужен метод, который проверяет, является ли объект итерируемым, например:

def is_iterable(my_object)
  ..
end

Я действительно не уверен, с чего начать, если явно не назвать классы из этого метода.

Edit: Для моих целей, допустим, iterable - это то, что вы можете сделать. To to.

4b9b3361

Ответ 1

В моих целях, допустим, iterable - это то, что вы можете сделать .each to.

Вы можете просто спросить, имеет ли этот объект этот метод

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

Ответ 2

У вас уже есть ответы, но вот еще два способа: Object # is_a?/Object # kind_of? и Модуль # ===:

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

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

Ответ 3

Существует несколько способов сделать это, в зависимости от ваших больших целей и того, что вам нужно сделать с результатом.

  • Если вы просто хотите использовать утиную печать, чтобы увидеть, отвечает ли объект на #each, тогда вы можете просто спросить объект, есть ли у него такой метод.

    my_object.respond_to? :each
    
  • Если вы хотите узнать, смешивается ли объект в классе Enumerable, вы можете проверить класс для включения.

    my_object.class.include? Enumerable
    
  • Если вам нужен список всех предков и миксинов, вы хотите метод # ancestors. Например, чтобы узнать, наследует ли my_object класс Enumerable, вы можете вызвать:

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

Ответ 4

В общем случае вы можете проверить, установлен ли метод each, или если модуль Enumerable включен в класс объекта:

my_object.class.include? Enumerable

Ответ 5

Поскольку Range отвечает на each, даже если он не является итерируемым, вам нужно специально проверить, реагируют ли элементы Range на succ

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