我有一些Ruby代码不再起作用,因为它假定所有越界数组范围访问将返回空数组而不是零。数组范围从未返回nil的最后一个版本是什么?
a = []
a[1..-1] == [] # code assumes this from ancient Ruby
a[1..-1] == nil # but gets this on newer Ruby >= 1.8
什么是Ruby的最后一个版本,其中数组范围从来没有零?
我有一些Ruby代码不再起作用,因为它假定所有越界数组范围访问将返回空数组而不是零。数组范围从未返回nil的最后一个版本是什么?
a = []
a[1..-1] == [] # code assumes this from ancient Ruby
a[1..-1] == nil # but gets this on newer Ruby >= 1.8
什么是Ruby的最后一个版本,其中数组范围从来没有零?
我认为它是1.2.x.
我能找到的最古老的Ruby文档是。它说,这大约Array#[]
:
self[start..end]
返回从开始含有的对象的阵列,以端,包括两端。如果结束是laeger [原文如此]比数组的长度,它将被舍入到长度。如果开始大于结束,此方法返回空数组(
[]
)。
所以在1.2中,它总是返回一个数组。
我能找到的下一个最古老的文档was for Ruby 1.6。它说:
ARR [anInteger] - > anObject或零
ARR [开始,长度] - > aSubArray或零
ARR [人气指数] - > aSubArray或零元素参考 - 返回索引anInteger上的元素,或返回从索引开始的子阵列开始并继续为长度元素,或者返回由指定的子数组aRange。负数索引从数组末尾向后计数(-1是最后一个元素)。 如果任何指数超出范围,则返回
nil
。
因此,它缩小了很多。然后我决定直接找到源代码。在Ruby 1.2中,Array#[]
被称为ary_aref
in array.c。如果参数是一个范围,它会调用beg_len
来获取开始索引和子序列的长度,然后用这些参数调用ary_subseq
。长话短说,ary_subseq
总是返回一个数组,永远不会nil
。
接下来我尝试了Ruby 1.3,其中Array#[]
is now called rb_ary_aref
。你瞧,我们看到这个(406–414):
/* check if idx is Range */
switch (rb_range_beg_len(arg1, &beg, &len, RARRAY(ary)->len, 0)) {
case Qfalse:
break;
case Qnil:
return Qnil;
default:
return rb_ary_subary(ary, beg, len);
}
我认为,不言自明:如果参数超出范围,返回nil
。因为我在C上很糟糕,所以我去检查Ruby 1.6源代码(因为我们从文档中知道它有nil
行为),并且发现its implementation is the same。
然后,我相当确信Ruby 1.2.x是返回空数组的最后一个Ruby,1.3.x是第一个返回nil
的Ruby。
的Ruby 1.2,顺便说一句,发布于您正在使用什么版本的Ruby,我使用Ruby 2.0和第二行,b将零1998
我们需要一种方式来描述这个 - 代码古生物学? – zetetic 2014-09-26 22:05:34
@zetetic [软件](http://www.hpcf.upr.edu/~humberto/programmer-archaeologist.html)[考古学](http://en.wikipedia.org/wiki/Software_archaeology)。 ;) – 2014-09-26 22:12:30
。 – daremkd 2014-09-26 20:46:29
您可以使用或运算符来解决此问题,如下所示:'a [1..- 1] || [] == []'。如果返回值为null,则or子句执行。同时查看'|| ='的用法(类似,但是用于赋值)。 – ashes999 2014-09-29 13:32:23