我很好奇Ruby中的收集和阻止机制。我们可以定义一个这样的类:
class Foo
include Enumerable
def initialize
@data = []
end
def each
if block_given?
@data.each { |e| yield(e) }
else
Enumerator.new(self, :each)
end
end
end
我想知道@data.each
如何使用块{ |e| yield(e) }
作为参数。我搜索了Array#each:
rb_ary_each(VALUE array)
{
long i;
volatile VALUE ary = array;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AREF(ary, i));
}
return ary;
}
但这似乎并不像Ruby语言实现。如何在Ruby中实现Array#each
?
编辑:
看起来C代码遍历第一个到最后一个数组元素,并使用遍历数组元素的参数调用ruby yield函数。但是块传递到rb_ary_each
函数的哪个位置?
答案 0 :(得分:1)
这是一个简单的Ruby实现,类似each
的方法,它不依赖于任何Ruby的内置迭代器方法:
class List
def initialize(arr)
@arr = arr
end
def each
i = 0
while i < @arr.length
yield @arr[i]
i += 1
end
end
end
用法:
l = List.new(['a', 'b', 'c'])
l.each {|x| puts x}
输出:
a
b
c
答案 1 :(得分:0)
我可能会迟到这个主题,但我想VALUE数组是一个对象/结构而不是原始值,如int,char等。所以,rb_ary_each方法接收的是对象的指针/引用/ VALUE类型的结构。如果这是真的(我只是在这里猜测我对C的了解)那么块就会在带有retain参数的object / struct中传递。
我还猜测应该存在另一个对象/结构来保存块/ proc / lambda,因此VALUE对象/结构应该保存指向第一个的指针/引用。
如果我错了,请有人纠正我!你的问题与C的工作方式有关,而不是Ruby。