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/