tags:

views:

89

answers:

3

Is there a more elegant way of doing this logic in ruby

a = nil #=> obviously 'a' can have value but I am just setting it nil to make the eg more clear
b = a
unless b
  b = "value"
end

so that we have the value of b set in the end. We could have another variation of the above code like so

a = nil
b = a
b ||= "value"

and I can also use ternary statement to write the above code like

b = a ? a : "value"

but if you replace variable a and "value" with a long line of code then this ternary statement will start looking ugly too.

Can the above logic be made more elegant / expressive somehow or are we limited to just the above solutions?

+2  A: 

b ||= "value" is much like Perl's widely-loved // and //= operators, because in Ruby the only thing that tests false is nil (and, well, false). This makes it functionally identical to Perl's //= operator. How much more "elegant" can you get than a ||= b? Honestly, I don't know how much more compactly that idea can be conveyed other than making the operator shorter (and at that point you're just being silly).

Chris Lutz
+10  A: 

You almost answered your question yourself.

b = a
b ||= "value"

can be shortened to

b = a || "value"
ib
True and I don't think we can get it any better than that while keeping it clean as well as clear but I will still wait and see if anyone can come up with something better :)
nas
You just need to ensure that when you use this false is not a valid value for a.
Farrel
It's too bad that `or` doesn't fit nicely here since it doesn't bind closely enough: `b = ( a or "value" )`
thenduks
This solution is _fully_ equivalent to those samples in the question, so ensuring that `false` is not a valid value for `a` is not a defect of the answer, but the _question_!
ib
+1  A: 

I dislike using the || operator for the reason Farrel pointed out in ib's answer. It may be right here, but I'm always frightened it will trip me up one day. So I'm afraid I tend to go for the rather pedestrian:

b = "value"; b = a unless a == nil

Not pretty, I know, but safe and very, very explicit.

Shadowfirebird
Why not to express this more clearly: `b = a.nil? ? "value" : a` or `b = if a.nil? then "value" else a end`?
ib
Perhaps I'm misremembering, but doesn't the ternary operator in Ruby also have a gotcha? But I should have said "unless a.nil?", I agree.
Shadowfirebird
What "gotcha" do you mean?
ib