Use of this adaptation of the rubinius Array#[] is slower than
the current implementation by a few clicks.
def [](one, two = nil)
# Normalise the argument variants
start, finish, count, simple, is_range = nil, nil, nil, false, false
case one
when Fixnum
if two
start, count = one, two
return nil if count < 0 # No need to go further
else
start, finish, simple = one, one, true
end
when Range
is_range = true
start, finish = one.begin, one.end
when nil
raise TypeError, "no implicit conversion from nil to integer"
else
raise TypeError, "can't convert #{one.class} into Integer"
end
# so it only needs to be calculated once...
total = self.length
# Convert negative indices
start += total if start < 0
if simple
return nil if start < 0 or start >= total
return at(start)
# ONE past end only, MRI compat
elsif start == total
return []
elsif start < 0 or start >= total
return nil
end
finish = (start + count - 1) if count # For non-ranges
finish += total if finish < 0
finish -= 1 if is_range and one.exclude_end?
# Going past the end is ignored (sort of)
finish = (total - 1) if finish >= total
if finish < 0
return [] if is_range
return nil
end
return [] if finish < start or count == 0
read(finish-start+1, start)
end