Ruby Quirk – the .shift method when manipulating arrays

One of the principles behind Ruby is the Principle of Least Surprise. So far, in my two months of joy learning and working with Ruby (mostly with the code acting as the backbone behind my primitive text layout engine–like a very very primitive alternative to LaTex), I’ve relied on this principle quite heavily–and successfully. But today, for the first time, I was very unpleasantly surprised.

I’m using the latest stable release of Ruby, version 1.8.6-p111 on Windows. I’ve recreated the same “error” or “bug” using the online live preview of Ruby on Ruby’s home website.

The code:

irb(main):001:0> x = [1,2,3,4]
=> [1, 2, 3, 4]
irb(main):002:0> x.shift.nil?
=> false
irb(main):003:0> x
=> [2, 3, 4]

Am I missing something here? I thought that the .nil? method was always nondestructive! (And that the only kinds of methods that permanently change something always end in “!” like “.gsub!”. Even if I used it as a conditional statement, like, “if x.shift.nil? … “, the use of that statement alone would alter the x array!

I’m pretty sure all the Ruby developers are aware of this–it’s just too blatant. My only suggestion to them is–this kind of behavior seems completely against the, you guessed it, Principle of Least Surprise.

UPDATE June 16, 2010: Apparently, after learning shell scripting, it has dawned on me that the “shift” command is an old shell built-in command that destructively removes the first element of the array (in zsh, bash, etc.). This is probably why Ruby did not bother with “shift!”. Still, if I were Matz, I would have favored uniformity over preserving old traditions — and my original post’s message still rings true to me. Of course, the safe alternative to x.shift.nil? is x[0].nil? — simply accessing the first element at index 0 instead of using shift.