2014-09-26 41 views
2

我有一些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的最后一个版本,其中数组范围从来没有零?

+0

。 – daremkd 2014-09-26 20:46:29

+0

您可以使用或运算符来解决此问题,如下所示:'a [1..- 1] || [] == []'。如果返回值为null,则or子句执行。同时查看'|| ='的用法(类似,但是用于赋值)。 – ashes999 2014-09-29 13:32:23

回答

4

我认为它是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

+1

我们需要一种方式来描述这个 - 代码古生物学? – zetetic 2014-09-26 22:05:34

+1

@zetetic [软件](http://www.hpcf.upr.edu/~humberto/programmer-archaeologist.html)[考古学](http://en.wikipedia.org/wiki/Software_archaeology)。 ;) – 2014-09-26 22:12:30

相关问题