From: "marcandre (Marc-Andre Lafortune)" Date: 2012-03-29T05:14:54+09:00 Subject: [ruby-core:43811] [ruby-trunk - Bug #6203] Array#values_at does not handle ranges with end index past the end of the array Issue #6203 has been updated by marcandre (Marc-Andre Lafortune). Assignee set to marcandre (Marc-Andre Lafortune) Target version changed from 1.9.3 to 2.0.0 ruby -v set to trunk The patch from Mark Rada never made it through, but I concur that the problem is in rb_range_beg_len. I'll commit the fix below unless there's objection. I've already fixed RubySpec: https://github.com/rubyspec/rubyspec/commit/558a40edd5cd43a503641238cabe9f481ce9a723 diff --git a/range.c b/range.c index 61fb643..aa0628d 100644 --- a/range.c +++ b/range.c @@ -746,16 +746,16 @@ rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err) if (beg < 0) goto out_of_range; } + if (end < 0) + end += len; + if (!excl) + end++; /* include end point */ if (err == 0 || err == 2) { if (beg > len) goto out_of_range; if (end > len) end = len; } - if (end < 0) - end += len; - if (!excl) - end++; /* include end point */ len = end - beg; if (len < 0) len = 0; ---------------------------------------- Bug #6203: Array#values_at does not handle ranges with end index past the end of the array https://bugs.ruby-lang.org/issues/6203#change-25317 Author: ferrous26 (Mark Rada) Status: Open Priority: Normal Assignee: marcandre (Marc-Andre Lafortune) Category: core Target version: 2.0.0 ruby -v: trunk =begin When I use Array#values_at I expect that it would be the same as successive calls to (({Array#[]})). There is one case where this does not hold: a = [0,1,2,3,4,5] a[4..6] # => [4, 5] a.values_at(4..6) # => [4,5,nil] I think this is an inconsistency in the design of (({Array#values_at})). We can look at a more extreme case: a[4..100] # => [4, 5] a.values_at 4..100 # => [4, 5, nil] And now it doesn't make any sense. I think the best solution would be to make (({Array#values_at})) be equivalent to successive calls to (({Array#[]})). I have patched (({rb_range_beg_len()})) to handle the extra case and opened a pull request on github. =end -- http://bugs.ruby-lang.org/