# Idiomatic way to assign if not nil?

I know I can use “a ||= b” to assign b to a if a is nil.

But what about an equivalent to

a = b if b

Does that exist in a DRYer form?

On 8/28/07, Jay L. [email protected] wrote:

I know I can use “a ||= b” to assign b to a if a is nil.

But what about an equivalent to

a = b if b
a &&= b will almost get you there

if a is not nil or false and b is not nil or false then a = b, but if
a is nil or false and b is not nil or false then a = a. So if you can
guarantee that a will always be truthy then you can do it. I’d stick
to a = b if b for sanity’s sake.

Hi Jay

On 29 Aug 2007, at 00:30, Jay L. wrote:

a = b if b

Does that exist in a DRYer form?

Best I could come up with just now was:

a = b || a

a = 123
=> 123
b = nil
=> nil
a = b || a
=> 123
a
=> 123
b = 456
=> 456
a = b || a
=> 456
a
=> 456

Cheers.

Douglas F Shearer
[email protected]

On 8/28/07, Douglas F Shearer [email protected] wrote:

a = b || a
a = b if b
Not really DRYer :), you just repeat a instead of b

On Aug 28, 8:00 pm, [email protected] wrote:

I don’t have the feeling that I’m repeating myself; the two b’s both
pull their weight. So I wouldn’t worry about it, from the DRY
perspective.

Yeah, it was more that I was doing a bunch of them at once to deal
with Rails’ attr_protected feature while in a unit test, so I ended up
writing:
user.other = options[:other] if options[:other]

Felt kinda repetitive. I guess I could DRY that up in an eval loop.

Hi –

On Wed, 29 Aug 2007, Logan C. wrote:

a = b || a
a = b if b
Not really DRYer :), you just repeat a instead of b

I have to say, when I type this:

a = b if b

I don’t have the feeling that I’m repeating myself; the two b’s both
pull their weight. So I wouldn’t worry about it, from the DRY
perspective.

David

On 8/28/07, Jay L. [email protected] wrote:

Felt kinda repetitive. I guess I could DRY that up in an eval loop.
Is this not what #attributes= is for?
user.attributes = options

On Aug 28, 10:31 pm, “Logan C.” [email protected] wrote:

Is this not what #attributes= is for?
user.attributes = options

Nope! That won’t assign any attributes that are attr_protected.

Jay L. wrote:

user.other = options[:other] if options[:other]

Felt kinda repetitive. I guess I could DRY that up in an eval loop.

No need for eval…

user.send “#{key}=”, options[key] if options.key?(key)
end

On Wed, 29 Aug 2007 08:53:19 +0900, Logan C. wrote:

a = b || a
a = b if b
Not really DRYer :), you just repeat a instead of b

But a is defintiely a variable, while b may be a function call.
In a = b if b, you compute the function twice.
In a = b or a, you compute the function only once.

–Ken

On Aug 28, 10:34 pm, Joel VanderWerf [email protected] wrote:

user.send “#{key}=”, options[key] if options.key?(key)
end

Perfect! In fact, I’ll go even better:

User.protected_attributes.each do |key|
user.send “#{key}=”, options[key] if options.key?(key)
end

Now I don’t have to update my tests when I add attr_protected
attributes to my model.

On 29 Aug 2007, at 14:40, Ken B. wrote:

Best I could come up with just now was:

a = b || a
a = b if b
Not really DRYer :), you just repeat a instead of b

But a is defintiely a variable, while b may be a function call.
In a = b if b, you compute the function twice.
In a = b or a, you compute the function only once.

Took the words right out of my mouth, I must read my email more
frequently…

Douglas F Shearer
[email protected]

On 8/29/07, Ken B. [email protected] wrote:

Best I could come up with just now was:

a = b || a
a = b if b
Not really DRYer :), you just repeat a instead of b

But a is defintiely a variable, while b may be a function call.
In a = b if b, you compute the function twice.
In a = b or a, you compute the function only once.

Methods that are expensive and/or have side effects should probably
not be named b

On Thu, 30 Aug 2007 23:40:39 -0700, aalfred wrote:

foo = bar if !bar.nil? # (case 1) or
foo = bar if foo.nil? && !bar.nil? # (case 2)

and rewrote them into:

foo ??= bar # case 1
foo !!= bar # case 2

Neat - you did that with superators? Or some other way?

Jay

On Aug 31, 12:40 am, aalfred [email protected] wrote:

foo ??= bar # case 1
foo !!= bar # case 2

How did you do that, given that those operators are (as you say) non-
existing, and the code in your resulting code produces a syntax error
(under 1.8.6, anyhow)? Did you modify the Ruby source?

On Aug 29, 1:25 am, Jay L. [email protected] wrote:

I know I can use “a ||= b” to assign b to a if a is nil.

But what about an equivalent to

a = b if b

Does that exist in a DRYer form?

Recently I had a similar problem. After some refactoring of code
I rewrote the code with two (non-existing, but very DRY operators)

foo = bar if !bar.nil? # (case 1) or
foo = bar if foo.nil? && !bar.nil? # (case 2)

and rewrote them into:

foo ??= bar # case 1
foo !!= bar # case 2

While this is not the same as your problem, it is quite similar.
I looks as this is not a completely isolated problem. Probably
because so many want to DRY their code. It looks like baroqueness
of code can survive only in the names of methods and variables

Alfred

On 9/2/07, Phrogz [email protected] wrote:

foo ??= bar # case 1
foo !!= bar # case 2

How did you do that, given that those operators are (as you say) non-
existing, and the code in your resulting code produces a syntax error
(under 1.8.6, anyhow)? Did you modify the Ruby source?

I don’t think he did any such thing. I think when he says he rewrote
it, he means just that, he rewrote it, not that it actually worked or
anything

I’ve not yet seen the right answer on the original question:
“idiomatic way to assign if not nil?”.

Since false isn’t nil, a||=b can’t a correct answer, AFAIK.

a=b if a.nil?

gegroet,
Erik V. - http://www.erikveen.dds.nl/

On Sunday 02 September 2007 09:21:25 am Erik V. wrote:

Erik V. - http://www.erikveen.dds.nl/
False isn’t nil, but nil is false.

I really enjoyed the article. It proved to be Very helpful to me and I

am sure to all the comment here!
http://www.dealsourcedirect.com/ion-tape2pc.html