Jeppe Liisberg
Jeppe Liisberg

Reputation: 3804

is there a nicer oneliner for handling "unless somthing.nil? || something[:key].nil?"

Is there a way to make this one liner better looking?

@var = params[:key1][:key2] unless params.blank? || params[:key1].blank?

Upvotes: 3

Views: 249

Answers (7)

Nakilon
Nakilon

Reputation: 35084

You can use this:

params.blank? || params[:key1].blank? || (@var = params[:key1][:key2])

But your way is more readable for me.

Upvotes: 1

Jeppe Liisberg
Jeppe Liisberg

Reputation: 3804

Wow, thanks for all the replies!

I'm going to sum up the answers - as the answer seems more subtle than just another oneliner ;-)

As gertas point out that params is always present in a controller action (which is indeed where I'm working), and that nil check is enough, my original code can thus be reduced to:

@var = params[:key1][:key2] unless params[:key1].nil?

This is quite readable but not as short as other suggestions, like

params[:key1].nil? || (@var = params[:key1][:key2])

@var =  params[:key1] && params[:key1][:key2]

or even

@var = (params[:key1] || {})[:key2]

I wondered how to use rubys try() method on hashes, and hellvinz gave the answer (rewritten to match my new/realized need):

@var = params[:key1].try(:fetch, :key2, nil)

Finally, Shinya Miyazaki came up with some interesting variations using fetch and merge:

@var = params.fetch(:key1, {}).fetch(:key2, nil)

@var = {:key1=>{}}.merge(params)[:key1][:key2]

I ended up going with "my own", to honor the principle of "Clarity over Brevity" as pointed out by Chris McCauley

Thanks again everyone! :-)

Upvotes: 1

Chris McCauley
Chris McCauley

Reputation: 26393

Clarity over Brevity!

Before changing your original code, ask yourself if the next person reading your code would find your code more or less comprehensible than the alternatives suggested here.

Personally I'd go with your original.

Upvotes: 0

Shinya
Shinya

Reputation: 146

This is a simple idea.

@var = params.fetch(:key1, {}).fetch(:key2, nil)

Using merge is interesting.

@var = {:key1=>{}}.merge(params)[:key1][:key2]

Upvotes: 0

gertas
gertas

Reputation: 17145

I assume that you are using it in controller (params allways present - not nil):

@var = (params[:key1] || {})[:key2]

Upvotes: 0

hellvinz
hellvinz

Reputation: 3500

Just to let you know that you can also do this, but i'm not sure it is better looking :) (and you have to be in ror):

@var = params.try(:fetch, :key1, nil).try(:fetch, :key2, nil)

Upvotes: 1

bragboy
bragboy

Reputation: 35542

Yes, there is.

@var =  params && params[:key1] && params[:key1][:key2]

Upvotes: 1

Related Questions