如何检查对象是否可以在Ruby中迭代?

var*_*tis 34 ruby

如何检查对象是否可以在Ruby中迭代?

也就是说,我想要一个干净地检查对象是否可迭代的方法,如下所示:

def is_iterable(my_object)
  ..
end
Run Code Online (Sandbox Code Playgroud)

我真的不知道从这个方法中明确命名类的这个简短的开始.

编辑: 为了我的目的,让我们说可迭代是你可以做的事情.

Ser*_*sev 44

为了我的目的,让我们说可迭代是你可以做的事情.each.

您可以询问此对象是否具有此方法

def iterable?(object)
  object.respond_to? :each
end
Run Code Online (Sandbox Code Playgroud)

  • 这在所有情况下都不起作用.`nil..nil`是一个Range对象并响应`each`,但是不可迭代并抛出`TypeError:在尝试迭代时不能从NilClass`迭代.我刚刚在一个带有日期范围输入的项目中遇到这个问题,该项目针对虚假用户条目(如无任何内容或随机字符串等)进行测试. (9认同)

Mic*_*ohl 44

你已经得到了一些答案,但是还有两种方法,Object#is_a?/ Object#kind_of?模块#===:

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

  Enumerable === [] #=> true
  Enumerable === "" #=> false
Run Code Online (Sandbox Code Playgroud)


Tod*_*obs 9

有很多方法可以做到这一点,具体取决于您的更大目标以及您需要对结果做些什么.

  1. 如果你只想使用duck typing来查看对象是否响应#each,那么你可以问对象是否有这样的方法.

    my_object.respond_to? :each
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果要查看对象是否在Enumerable类中混合,可以检查该类是否包含在内.

    my_object.class.include? Enumerable
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如果你想要一个所有祖先和mixin的列表,你需要#ancestors方法.例如,要查看my_object是否继承自Enumerable类,您可以调用:

    my_object = []
    my_object.class.ancestors
    => [Array, Enumerable, Object, PP::ObjectMixin, Kernel, BasicObject]
    
    my_object.class.ancestors.include? Enumerable
    => true
    
    Run Code Online (Sandbox Code Playgroud)