Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Change Array#values_at to handle range index past end of array properly #109

Closed
wants to merge 2 commits into from

1 participant

@ferrous26

This refers to Redmine #6203:

This changes Array#vaules_at to behave more consistently with array slicing.

Without this patch:

    a = [0,1,2,3,4,5]
    a[4..6] # => [4, 5]
    a.values_at(4..6) # => [4,5,nil]
    a.values_at(4..600) # => [4,5,nil]

With this patch:

    a.values_at 4..6 # => [4, 5]
    a.values_at 4..600 # => [4, 5]
ferrous26 added some commits
@ferrous26 ferrous26 Ignore confest files generated by autoconf 5156447
@ferrous26 ferrous26 Make rb_range_beg_len handle index past end of length when range is n…
…ot exclusive

This handles an edge case in Array#values_at:

[0,1,2,3,4,5].values_at 4..5
[0,1,2,3,4,5].values_at 4..6
[0,1,2,3,4,5].values_at 4..7

Previously, the second and third case would include a nil
at the end of the array.

It is important to note that this change is only triggered
when the err parameter is set to 0 or 2, since there are
cases (i.e. Array#fill) where we do not want to adjust the
range.
51b79f7
@ferrous26 ferrous26 closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 26, 2012
  1. @ferrous26
  2. @ferrous26

    Make rb_range_beg_len handle index past end of length when range is n…

    ferrous26 authored
    …ot exclusive
    
    This handles an edge case in Array#values_at:
    
    [0,1,2,3,4,5].values_at 4..5
    [0,1,2,3,4,5].values_at 4..6
    [0,1,2,3,4,5].values_at 4..7
    
    Previously, the second and third case would include a nil
    at the end of the array.
    
    It is important to note that this change is only triggered
    when the err parameter is set to 0 or 2, since there are
    cases (i.e. Array#fill) where we do not want to adjust the
    range.
This page is out of date. Refresh to see the latest.
Showing with 10 additions and 1 deletion.
  1. +1 −0  .gitignore
  2. +3 −1 range.c
  3. +6 −0 test/ruby/test_array.rb
View
1  .gitignore
@@ -43,6 +43,7 @@ y.tab.c
/automake
/beos
/breakpoints.gdb
+/conftest
/config.cache
/config.h
/config.h.in
View
4 range.c
@@ -749,8 +749,10 @@ rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
if (err == 0 || err == 2) {
if (beg > len)
goto out_of_range;
+ if (end == len && !excl)
+ end -= 1;
if (end > len)
- end = len;
+ end = excl ? len : len - 1;
}
if (end < 0)
end += len;
View
6 test/ruby/test_array.rb
@@ -888,6 +888,12 @@ def test_values_at
assert_equal(@cls['a', 'c', 'e'], a.values_at(0, 2, 4))
assert_equal(@cls['j', 'h', 'f'], a.values_at(-1, -3, -5))
assert_equal(@cls['h', nil, 'a'], a.values_at(-3, 99, 0))
+ assert_equal(@cls['h', 'i', 'j'], a.values_at(7..9))
+ assert_equal(@cls['h', 'i', 'j'], a.values_at(7..10))
+ assert_equal(@cls['h', 'i', 'j'], a.values_at(7..11))
+ assert_equal(@cls['h', 'i', 'j'], a.values_at(7...10))
+ assert_equal(@cls['h', 'i', 'j'], a.values_at(7...11))
+ assert_equal(@cls['h', 'i', 'j'], a.values_at(7...12))
end
def test_join
Something went wrong with that request. Please try again.