I'm trying to avoid an error message when pulling from a hash which may or may not have a value. I either want it to return the value or return nil.
I thought the try
method would do it, but I'm still getting an error.
key not found: "en"
My hash is an hstore column called content
... content['en']
, etc.
content = {"es"=>"This is an amazing event!!!!!", "pl"=>"Gonna be crap!"}
Try method
@object.content.try(:fetch, 'en') # should return nil, but errors even with try method
I thought this would work but it doesn't. How else can I return a nil
instead of an error?
Also, the content field itself might also be nil
so calling content['en']
throws:
undefined method `content' for nil:NilClass
In Ruby, the values in a hash can be accessed using bracket notation. After the hash name, type the key in square brackets in order to access the value.
Hash#fetch() is a Hash class method which returns a value from the hash for the given key. With no other arguments, it will raise a KeyError exception.
We can check if a particular hash contains a particular key by using the method has_key?(key) . It returns true or false depending on whether the key exists in the hash or not.
See the Hash#fetch
Returns a value from the hash for the given key. If the key can’t be found, there are several options: With no other arguments, it will raise an KeyError exception; if default is given, then that will be returned; if the optional code block is specified, then that will be run and its result returned.
h = { "a" => 100, "b" => 200 }
h.fetch("z")
# ~> -:17:in `fetch': key not found: "z" (KeyError)
So use:
h = { "a" => 100, "b" => 200 }
h.fetch("z",nil)
# => nil
h.fetch("a",nil)
# => 100
Just use normal indexing:
content['en'] #=> nil
As of Ruby 2.0, using try
on a possibly nil
hash is not neat. You can use NilClass#to_h
. And for returning nil
when there is no key, that is exactly what []
is for, as opposed to what fetch
is for.
@object.content.to_h["en"]
If you need to allow for object.content.nil?
, then you'd use try
. If you want to allow for a missing key then you don't want fetch
(as Priti notes), you want the normal []
method. Combining the two yields:
object.content.try(:[], 'en')
Observe:
> h = { :a => :b }
=> {:a=>:b}
> h.try(:[], :a)
=> :b
> h.try(:[], :c)
=> nil
> h = nil
=> nil
> h.try(:[], :a)
=> nil
You could also use object.content.try(:fetch, 'en', nil)
if :[]
looks like it is mocking you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With