Why Array#slice and Array#slice! behave differently?
behavior, design-decisions, ruby
Solution
`#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
Problem
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