Hash#except in Ruby 3+
If you're an avid Rails user, you might be familiar with ActiveSupport 's Hash#except which has been around for roughly 15 years. As of Ruby 3.0, Hash#except is now a native Ruby method too! But... what does it do? Hash#except gives us a hash excluding all of the keys we've passed as arguments. Let's look at an example: jemma = { name: "Jemma",
username: "jemma",
password: "super secure" }
jemma.except(:password)
# => { name: "Jemma", username: "jemma" }
Before Ruby 3.0, if we were in a repo which wasn't using Rails, we could have done something like this: jemma = { name: "Jemma",
username: "jemma",
password: "super secure" }
jemma.reject { |k,_| k == :password }
# => { name: "Jemma", username: "jemma" }
While this works totally fine, it gets a little clunky if we're trying to exclude multiple different keys. Yet Hash#except can also take multiple arguments: jemma = { name: "Jemma",
username: "jemma",
password: "super secure" }
jemma.except(:name, :password)
# => { username: "jemma" }
Hash#except might look familiar because it's the inverse of Hash#slice . Hash#slice will give us a hash containing key / value pairs whose keys we specify as arguments, while Hash#except will give us a hash containing key / value pairs whose keys we don't specify as arguments.
We might be wondering, what happens if we pass a key that is not in the hash? jemma = { name: "Jemma", username: "jemma",
password: "super secure" }
jemma.except("key doesn't exist")
# => { name: "Jemma", username: "jemma",
password: "super secure" }
In this case, Ruby is technically still excluding this key from our hash - it just never appeared in the hash to begin with. (This is the same behavior as Hash#slice .) |