我一直在学习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
这是否由于数组类实现不完整而发生(即'元素'未定义或是因为其他原因?我还想知道'每个'和其他基本功能是如何实现的。正确的文档/答案会有所帮助。让我知道这是否重复(我没有看到任何类似的问题)。谢谢
答案 0 :(得分:12)
你可以这样做(不要错过in
):
class Array
def each
for element in self
yield element
end
end
end
但事实是:
for element in array
是array.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
有效!