robintw
robintw

Reputation: 28531

More idiomatic ruby way to write @var = obj['blah'] unless obj['blah'].nil?

I'm sure there is a more idiomatic ruby way to write the code below:

@var = obj['blah'] unless obj['blah'].nil?

I've got a whole load of these to do (see below), and there must be a nicer way!

@num_x = obj['num_x'] unless obj['num_x'].nil?
@num_y = obj['num_y'] unless obj['num_y'].nil?
@num_iterations = obj['num_iterations'] unless obj['num_iterations'].nil?
@pe = obj['pe'] unless obj['pe'].nil?

I have a feeling that the ||= operator may be useful, but can't seem to quite work out how to use it.

Upvotes: 5

Views: 189

Answers (4)

Joc
Joc

Reputation: 1059

if @var already has a value which is not nil or false then you can use

@var &&= obj['blah']

but I would be tempted to find a simpler solution maybe merging hashes if there are lots of values.

such as:

obj = {:num_x => 23, :num_y => 75, :pe => 99}

locals = {:num_x => 1, :num_y => 2, :num_iterations => 3, :pe => 4}

puts locals.inspect #=> {:num_y=>2, :pe=>4, :num_iterations=>3, :num_x=>1}

locals.merge! obj

puts locals.inspect #=> {:num_y=>75, :pe=>99, :num_iterations=>3, :num_x=>23}

Which is used for setting options in many gems I have seen.

Upvotes: 0

glenn mcdonald
glenn mcdonald

Reputation: 15488

Like this:

obj['blah'] && var = obj['blah']

Upvotes: 1

mikej
mikej

Reputation: 66263

Depending on your circumstances, and unless the instance variables already have an existing value that you want to preserve if the value in obj is nil then it might not be a problem to just let them be set to nil.

Alternatively, you could write a little helper function like:

def set_instance_variables_for_non_nil_values(h, *keys)
  keys.each do |key|
    instance_variable_set "@#{key}", h[key] unless h[key].nil?
  end
end

Then in your example code you would use it like this:

set_instance_variables_for_non_nil_values obj, 'num_x', 'num_y',
  'num_iterations', 'pe'

Upvotes: 3

Peter
Peter

Reputation: 132257

the shortest I can think of for this common need is

@var = obj['blah'] or @var

though if obj['blah'] can be false, you'll need to go with your original version.

The ||= operator tests the left-hand side, not the right-hand side, so doesn't apply here.

Upvotes: 2

Related Questions