[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

idiomatic way to assign if not nil?

Jay Levitt

8/28/2007 11:25:00 PM

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?

19 Answers

Logan Capaldo

8/28/2007 11:46:00 PM

0

On 8/28/07, Jay Levitt <jay@jay.fm> 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.

>
> Does that exist in a DRYer form?
>
>
>

dougal.s

8/28/2007 11:47:00 PM

0

Hi Jay

On 29 Aug 2007, at 00:30, Jay Levitt 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
dougal.s@gmail.com
http://douglasfs...


Logan Capaldo

8/28/2007 11:53:00 PM

0

On 8/28/07, Douglas F Shearer <dougal.s@gmail.com> wrote:
> Hi Jay
>
> On 29 Aug 2007, at 00:30, Jay Levitt 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 = b if b
Not really DRYer :), you just repeat a instead of b :)

dblack

8/29/2007

0

Jay Levitt

8/29/2007 2:22:00 AM

0

On Aug 28, 8:00 pm, dbl...@wobblini.net wrote:
> >> On 29 Aug 2007, at 00:30, Jay Levitt wrote:
>
> >>> a = b if b
>
> >>> Does that exist in a DRYer form?
>
> 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.

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.login = options[:login] if options[:login]
user.password = options[:password] if options[:password]
user.other = options[:other] if options[:other]

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

Logan Capaldo

8/29/2007 2:32:00 AM

0

On 8/28/07, Jay Levitt <jay@jay.fm> wrote:
> On Aug 28, 8:00 pm, dbl...@wobblini.net wrote:
> > >> On 29 Aug 2007, at 00:30, Jay Levitt wrote:
> >
> > >>> a = b if b
> >
> > >>> Does that exist in a DRYer form?
> >
> > 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.
>
> 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.login = options[:login] if options[:login]
> user.password = options[:password] if options[:password]
> user.other = options[:other] if options[:other]
>
> Felt kinda repetitive. I guess I could DRY that up in an eval loop.
Is this not what #attributes= is for?
user.attributes = options

>
>
>

Joel VanderWerf

8/29/2007 2:34:00 AM

0

Jay Levitt wrote:
> user.login = options[:login] if options[:login]
> user.password = options[:password] if options[:password]
> 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...

[:login, :password, :other].each do |key|
user.send "#{key}=", options[key] if options.key?(key)
end

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Jay Levitt

8/29/2007 5:30:00 AM

0

On Aug 28, 10:31 pm, "Logan Capaldo" <logancapa...@gmail.com> wrote:
> On 8/28/07, Jay Levitt <j...@jay.fm> wrote:
> > 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.login = options[:login] if options[:login]
> > user.password = options[:password] if options[:password]
> > user.other = options[:other] if options[:other]
>
> > Felt kinda repetitive. I guess I could DRY that up in an eval loop.
>
> Is this not what #attributes= is for?
> user.attributes = options

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

Jay Levitt

8/29/2007 5:36:00 AM

0

On Aug 28, 10:34 pm, Joel VanderWerf <vj...@path.berkeley.edu> wrote:
> Jay Levitt wrote:
> > user.login = options[:login] if options[:login]
> > user.password = options[:password] if options[:password]
> > 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...
>
> [:login, :password, :other].each do |key|
> 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.

Ken Bloom

8/29/2007 1:18:00 PM

0

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

> On 8/28/07, Douglas F Shearer <dougal.s@gmail.com> wrote:
>> Hi Jay
>>
>> On 29 Aug 2007, at 00:30, Jay Levitt 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 = 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

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...