在ruby中使用'for each'的“each”函数实现

时间:2011-12-14 07:54:51

标签: ruby irb

我一直在学习ruby,并且有兴趣知道数组类中的'each'是如何实现的。我看到一个documentation here,看起来这就是'每个'的写法;

# within class Array...
def each
  for each element
    yield(element)
  end
end

我确实在ruby控制台中编写了上面的代码(没有注释#)(我使用的是1.9.2)并且出现了这种语法错误

:SyntaxError: (irb):2: syntax error, unexpected tIDENTIFIER, expecting keyword_do or '{' or '('
(irb):5: syntax error, unexpected keyword_end, expecting $end

这是否由于数组类实现不完整而发生(即'元素'未定义或是因为其他原因?我还想知道'每个'和其他基本功能是如何实现的。正确的文档/答案会有所帮助。让我知道这是否重复(我没有看到任何类似的问题)。谢谢

4 个答案:

答案 0 :(得分:12)

你可以这样做(不要错过in):

class Array
  def each
    for element in self
      yield element
    end
  end
end

但事实是:

for element in arrayarray.each

的语法糖

所以上面的代码转换成了这个:

class Array
  def each
    each do |element|
      yield element
    end
  end
end

你堆栈溢出。

答案 1 :(得分:7)

首先,您的for语句的语法已关闭,它应该类似for element in elements,几乎等同于elements.each { |element| ... },但它不会引入新范围。事实上for是使用each实现的,当您尝试在没有定义each方法的方法上调用它时可以看到:

>> for element in nil
..   end
NoMethodError: undefined method `each' for nil:NilClass
    from (irb):1

关于语法错误:由于您要重新打开一个类,当Ruby解析器看到独立的each它使用self作为接收者时,它会将您的语句转换为for self.each element,其中element是提到的tIDENTIFIER,而self.each do |element| ... end之类的内容是预期的。

至于Array#each的实现,它在C中实现,看起来像这样

VALUE
rb_ary_each(VALUE array)
{
    long i;
    volatile VALUE ary = array;

    RETURN_ENUMERATOR(ary, 0, 0);
    for (i=0; i<RARRAY_LEN(ary); i++) {
        rb_yield(RARRAY_PTR(ary)[i]);
    }
    return ary;
}

这基本上就是你在C中用Ruby编写的。

答案 2 :(得分:0)

Array#each是用Ruby构建的方法。任何宝石都没有打补丁。请参阅文档here

答案 3 :(得分:0)

可以通过循环范围从0到数组大小(排除)

class Array
  def each
    for i in 0...self.size
      yield self[i]
    end
  end
end

示例:

[1,2,3].each {|i| puts i}
1
2
3

有效!