How delete on a Hash works in Ruby... or how you thought it worked

Are you new to Ruby? Or were you once? Cool, me too.

When you first bump into Hash#delete you think you might be able to use it and just remove the items you don't want, but it doesn't work that way.

You think "I'll just do this:"

hashy = {'this' => 'that', 'something' => 'else', 'secret' => 'I love NKOTB'}
    hashy = hashy.delete('secret')

And bingo you've got your hash without that nasty secret. But what you actually found is that delete will remove that key from the hash and return the deleted value and not the altered hash.

Perhaps this is old news to you, but to new developers this is the moment where they say "Oh, right, it gives me the value that I don't want."

Well here's a quick idea to give you what you want:

class Hash
      def except(which)
        self.tap{ |h| h.delete(which) }
      end
    end

Now you can use the same code above but run:

pre>hashy = {'this' => 'that', 'something' => 'else', 'secret' => 'I love NKOTB'} hashy = hashy.except('secret')

That'll return your hash without the part you want. That could be simplified to this:

hashy = {'this' => 'that', 'something' => 'else', 'secret' => 'I love NKOTB'}
    hashy.except('secret')

because the delete will alter the hash. So you need to be aware that if you want to keep the original hash you'll need to:

hashy = {'this' => 'that', 'something' => 'else', 'secret' => 'I love NKOTB'}
    new_hash = hashy.dup.except('secret')

Enjoy!