是否有Ruby文档可以验证Enumerable.to_a是否在内部调用?

时间:2011-09-12 07:59:52

标签: ruby enumerable

我可以写一个简短的示例来验证内部to_a Enumerableeach调用class MyFooClass include Enumerable def initialize @members = [1, 2, 3] end def each puts "each is now called" @members.each{ |m| yield(m) } end end a = MyFooClass.new puts "let us convert to array" g = a.to_a 。这是:

let us convert to array
each is now called

输出结果为:

each

请注意,Enumerable不是to_a的成员,而是each。另外,如果我从我的类中删除in `to_a': undefined method `each' for #<MyFooClass:0x997c1ac @members=[1, 2, 3]> (NoMethodError) 的定义,则代码会崩溃,并显示以下消息:

to_a

我想知道是否有关于此的Ruby官方文档,这将记录Enumerableeach的成员)在您的班级中通过to_a方法的事实。请不要指导我{{1}}的源代码。我不认为这是一个答案。

3 个答案:

答案 0 :(得分:5)

来自fine manual

  

Enumerable mixin为集合类提供了多种遍历和搜索方法,并具有排序功能。 该类必须提供方法each ,这会产生集合的连续成员。

强调我的。所以Enumerable的所有迭代行为都基于类的each方法; Enumerable接口(minmaxsort)的排序部分使用<=>,但这里并不重要。

提供的each方法是Enumerable与混合它的类进行交互的唯一定义方式.Enumerable提供to_a方法,因此必须使用each来实现它

顺便说一下,Enumerable最好不要调用to_a,除非必须这样做,它会尝试将所有内容保存为Enumerable,以避免耗尽枚举来构建一个在两个时间都很昂贵的数组和空间。 Yossi指出的答案更多地是关于 Enumerable调用to_a而非如何时(但答案仍然是有趣的读取)。< / p>

答案 1 :(得分:1)

请注意#to_a代码中的id_each

static VALUE
enum_to_a(int argc, VALUE *argv, VALUE obj)
{
    VALUE ary = rb_ary_new();

    rb_block_call(obj, id_each, argc, argv, collect_all, ary);
    OBJ_INFECT(ary, obj);

    return ary;
}

有关更深入的说明,请参阅this问题。

答案 2 :(得分:0)

除了mu指出的手册中的禁欲主义解释之外,在Pickaxe书中还有following passage,这是Ruby介绍性书籍的真实之王:

  

好吧,你的课程可以支持所有这些整洁的功能,多亏了   mixins和模块的魔力Enumerable。你所要做的就是写作   一个名为each的迭代器,它返回集合的元素   反过来。混入Enumerable,突然你的课程支持   例如map,include?和find_all?。