Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`try` method when trying to fetch hash value

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
like image 320
holden Avatar asked Jun 29 '13 16:06

holden


People also ask

How do I get the hash value in Ruby?

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.

What is fetch method in Ruby?

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.

How do you check if a key exists in a Ruby hash?

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.


4 Answers

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
like image 41
Arup Rakshit Avatar answered Oct 04 '22 13:10

Arup Rakshit


Just use normal indexing:

content['en'] #=> nil
like image 23
Linuxios Avatar answered Oct 04 '22 11:10

Linuxios


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"]
like image 45
sawa Avatar answered Oct 04 '22 12:10

sawa


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.

like image 164
mu is too short Avatar answered Oct 04 '22 12:10

mu is too short