ruby中每个迭代器的行为
为什么这段代码输出的是ruby中每个迭代器的行为,ruby,Ruby,为什么这段代码输出的是[1,2,3,4,5],而不是[2,3,4,5,6] x = [1, 2, 3, 4, 5] x.each do |a| a + 1 end 我在上查看了每个的源代码。上面写着这样的东西 VALUE rb_ary_each(VALUE array) { long i; volatile VALUE ary = array; RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_le
[1,2,3,4,5]
,而不是[2,3,4,5,6]
x = [1, 2, 3, 4, 5]
x.each do |a|
a + 1
end
我在上查看了每个的源代码。上面写着这样的东西
VALUE
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;
}
值
rb_ary_每个(值数组)
{
龙我;
易变值=数组;
返回大小为的枚举数(ary,0,0,ary,enum,length);
对于(i=0;i它输出对象,您正在调用each
on,因为这是each
的返回值
x.map { |a| a + 1 }
#=> [2, 3, 4, 5, 6]
如果您只想打印a+1
,您应该实际将其输出:
x.each do |a|
puts a + 1
end
或者,如果您想要的结果是[2,3,4,5,6]
-您想要的,而不是每个
x.map { |a| a + 1 }
#=> [2, 3, 4, 5, 6]
让我看一下要点
从这一行可以看出,‘ary’在逻辑上等于array。注意,Ruby的新版本(如2.4.0)中没有这一行
volatile VALUE ary = array;
由于给定了一个块,我跳过了返回大小的枚举数。请参阅include/ruby/intern.h中的源代码
接下来,我们为“ary”数组的每个元素输入一个“for”
我相信接下来的一行会让你感到困惑。首先,它通过RARRAY_AREF宏从'ary'数组中获取第I个元素。其次,它通过rb_yield将元素的值传递给给定的块(即'a+1')。因此,它不存储任何内容
rb_yield(RARRAY_AREF(ary, i));
由于rb_yield没有写入任何内容,因此函数返回的“ary”数组[见上文]是输入“array”
将其与“地图”进行比较可能有助于您进一步:
static VALUE rb_ary_collect_bang(VALUE ary)
{
long i;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
}
return ary;
}
静态值rb\u ary\u collect\u bang(值ary)
{
龙我;
返回大小为的枚举数(ary,0,0,ary,enum,length);
rb_ary_modify(ary);
对于(i=0;i
注意“for”循环中的“rb_ary_store”函数调用。这就是问题所在!它的rb_产量与“each”变量中的一样,但它不会丢弃返回的结果。结果存储在我们的[心爱的]“ary”数组的第i个元素。我尝试了puts a+1…但这同时打印了[2,3,4,5,6]和[1,2,3,4,5]@AmitAuddy您发布的Ruby代码没有打印任何内容。它是交互式解释器(irb
)打印每个计算表达式的值的一个。当使用ruby
执行代码时,它不会产生任何输出。@axiac是的。我说的是irb的输出。我个人觉得比YARV的更容易阅读。