djberg96 ([info]djberg96) wrote,
@ 2009-08-05 17:01:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
Current mood:awake

Hash#fetch
I generally eschew Array#fetch. It's worthless in my opinion. But what about Hash#fetch? Ah, now there's a good reason for this one. Consider this:

def foo(name)
   code = SomeHash[name]
   raise ArgumentError, "Illegal prototype '#{name}'" unless code
   return code
end

There's one immediate problem. What if false is a valid key argument? Or what if you want to merely check if a particular key has been defined even if it's nil? The above code will fail. But Hash#fetch has slightly different semantics. It checks that the key is defined without concern for the actual value and so, can pick up false and nil key values

Basically, you've got three options. Option 1 is to fail with an IndexError if the key isn't defined:
SomeHash.fetch(:bogus) # Boom, IndexError
# vs.
SomeHash[:bogus] # nil

Option 2 lets you specify a default value if the key isn't found:
SomeHash.fetch(:bogus, 7) # 7

Option 3 allows the value of a code block to serve as the value. This is generally used to re-raise a custom exception.
SomeHash.fetch(:bogus){ raise MyError, "Key not found" }



(1 comment) - (Post a new comment)


[info]dothapk
2009-08-06 08:55 am UTC (link)
Well, it's not that bad with old Hash behavior: you can check if key exists with #has_key?:
def foo(name)
  raise ArgumentError, "Illegal name #{name}" unless SomeHash.has_key?(name)
  SomeHash[name]
end

(Reply to this)


(1 comment) - (Post a new comment)

Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…