为什么s [n ..- 1]在红宝石中起作用?

时间:2012-03-01 17:34:54

标签: ruby

我对红宝石很新。最近,我想从字符串的第n个字符中提取字符串的一部分到最后。

像s [n,(s.size -n)这样的东西对我来说似乎很不优雅,所以我问了几个朋友。

有人建议我试试[n ..- 1],果然这样有效,但他无法给我一个很好的理由说明它应该有效。我发现它的工作相当令人费解,因为irb1.9的以下输出应该解释:


> s = "0123456789"
=> "0123456789"
> s[2..-1]
=> "23456789"
> (2..-1).to_a
=> []

你可以看到,范围对象2 ..- 1是空的 - 它没有成员,如果你从2向上向上移动,这绝对是你所期望的。这与范围对象应如何工作的文档一致。

索引具有范围的字符串的文档清楚地说:“如果给定范围,则返回包含由范围给出的偏移处的字符的子字符串” - 但这是一个空集。

我也找不到“Ruby编程语言”或使用s[n..-1]等索引字符串的Ruby文档中的示例,并且在其他官方来源中找不到它的示例。然而,它似乎是民间传说,即使手册中没有任何内容表明您可以通过这种方式索引带有范围的字符串,并且即使该范围没有成员也能获得结果,它仍可正常工作。

然而,我的朋友是正确的,它有效。

那么,有人可以解释为什么这对我有用吗?我也非常有兴趣了解它的工作原理是否是MRI / YARV的侥幸,或者是否绝对可以在所有Ruby实现中使用,如果是这样,它在哪里可以记录起来工作?

编辑添加:

下面的回答者声称只有范围的beginend属性才是出于这些目的,但我在TRPL或Ruby文档中找不到相关文档。答案还声称确实有这种“混合符号”范围索引的例子,但我能找到的唯一一个是在混合范围索引显示产生nil的上下文中,而不是一片一个字符串。因此,我认为这个答案并不令人满意。

编辑添加:

似乎正确答案是这确实是Ruby文档中的缺陷。

编辑添加:

该漏洞由Ruby文档团队修复:请参阅https://bugs.ruby-lang.org/issues/6106

2 个答案:

答案 0 :(得分:2)

你是对的,范围n..-1是空的。但这并不重要,因为String#[]不会将范围视为集合 - 它只使用范围的beginend属性。

关于文档:The rdoc documentation of String#[]列出String#[]对每种可能类型的参数(包括带负数的范围)的行为以及示例。所以你不必依赖民间传说。相关报价:

  

如果给定范围,则返回包含由范围给定的偏移处的字符的子字符串。 [...]如果偏移为负,则从str的结尾开始计算。   [...]

a = "hello there"
# ...
a[-4..-2]              #=> "her"

答案 1 :(得分:2)

这是文档中的错误。

Ruby的文档很糟糕,因为Pickaxe的书就像matz实际上正确而全面的HTML文档上的流星一样。这个话题有时会让我感到烦恼。您的问题的答案,来自1. 4 link

  

自我[nth]

     

从数组中检索第n个项目。指数从零开始。如果index为负数,则从数组末尾开始向后计数。最后一个元素的索引是-1。如果数组中不存在第n个元素,则返回nil。

     

自[start..end]

     

返回一个包含从开始到结束的对象的数组,包括两端。如果使用...(而不是..),则不包括end。如果end大于数组的长度,它将被舍入到长度。如果start超出数组范围,则返回nil。如果start大于数组范围内的end,则返回空数组([])。

为方便起见,

-1是数组的最后一个索引。