Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Array#slice and Array#slice! behave differently?

I could not understand why, in Ruby, Array#slice and Array#slice! behave differently than Array#sort and Array#sort! (in the way that one returns the results on a new Array and the other works on the current object).

With sort the first one (without the bang), returns a sorted copy of the current Array, and sort! sorts the current Array.

slice, returns an Array with the specified range, and slice! deletes the specified range from the current object.

What's the reason the Array#slice! behaves like this instead of making the current object an Array with the specified range?

Example:

a = [0,1,2,3,4,5,6,7,8,9]

b = a.slice( 2,2 )

puts "slice:"
puts "  a = " + a.inspect
puts "  b = " + b.inspect

b = a.slice!(2,2)
puts "slice!:"
puts "  a = " + a.inspect
puts "  b = " + b.inspect

Output:

slice:
  a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  b = [2, 3]
slice!:
  a = [0, 1, 4, 5, 6, 7, 8, 9]
  b = [2, 3]

http://ideone.com/77xFva

like image 876
Vargas Avatar asked Jan 07 '14 16:01

Vargas


1 Answers

#slice and #slice! behaviors are equivalent: both "return a subarray starting at the start index and continuing for length elements", the same way as #sort and #sort! return a sorted array or #reverse and #reverse! return a reversed array.

The difference is that the bang methods also modify the object itself.

a = [4,2,6,9,1,5,8]
b = a.dup
a.sort == b.sort!             # => true
a == b                        # => false

b = a.dup
a.reverse == b.reverse!       # => true
a == b                        # => false

b = a.dup
a.slice(2,2) == b.slice!(2,2) # => true
a == b                        # => false
like image 188
wacko Avatar answered Sep 30 '22 13:09

wacko