Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
And Begin Idiom to avoid if with assignments
# After reading this comment
# http://avdi.org/devblog/2010/08/02/using-and-and-or-in-ruby/#comment-1098 ,
#
# I became aware of a cool idiom for Ruby.
#
# I've seen this in a lot of cases:
if (variable = expression_or_method(options))
variable.calculate_something
do_other_stuff(variable)
end
# This is another way to code the same concept:
variable = expression_or_method(options) and begin
variable.calculate_something
do_other_stuff(variable)
end
# The former case issues a warning because we're using = in an if statement.
# The latter seems more semantic to me too.
# What do you think??? Comments below!
@cv

This comment has been minimized.

Copy link

@cv cv commented Sep 1, 2010

It's pretty neat. Let's spread it :)

@adrianoalmeida7

This comment has been minimized.

Copy link

@adrianoalmeida7 adrianoalmeida7 commented Sep 1, 2010

Liked it. And it is even more readable.

@urubatan

This comment has been minimized.

Copy link

@urubatan urubatan commented Sep 1, 2010

I do not like either very much, I use the first some times, but most of the time I think it is best to split the assignment and the conditional expression, I think this way it is easier to validate and debug if needed.
But if we are talking about simpler cases, I like the last option (the one that looks like PERL :D )

@mclosson

This comment has been minimized.

Copy link

@mclosson mclosson commented Sep 1, 2010

Is there any difference when using and or && in this case? Haven't tried it but I'm assuming that if the expression_or_method returns false or nil then the rest will be shortcircuited and not bypassed.

@vinibaggio

This comment has been minimized.

Copy link

@vinibaggio vinibaggio commented Sep 1, 2010

@mclosson: I guess you're right, seems safer to me if expression_or_method returns nil

I liked this idiom, the resulting code is much cleaner.

@georgeguimaraes

This comment has been minimized.

Copy link
Owner Author

@georgeguimaraes georgeguimaraes commented Sep 1, 2010

@mclosson

if we had used && instead of and, the block would be evaluated and it would be like:
variable = ( expression_or_method(options) && something_the_block_returns )

This is not what we wanted to achieve. In our case, and using &&, it would be like:
(variable = expression_or_method(options) ) && something_the_block_returns

@vinibaggio

This comment has been minimized.

Copy link

@vinibaggio vinibaggio commented Sep 1, 2010

nice catch, george! 'and' and '&&' have differente precedences.

@georgeguimaraes

This comment has been minimized.

Copy link
Owner Author

@georgeguimaraes georgeguimaraes commented Sep 1, 2010

'&&' has a different precedence than 'and'

@carlosantoniodasilva

This comment has been minimized.

Copy link

@carlosantoniodasilva carlosantoniodasilva commented Sep 1, 2010

Here is a nice example of what George just explained:
http://blog.jayfields.com/2007/08/ruby-operator-precedence-of-and-which.html

I liked this idiom as well, specially the examples in the post linked at the top, from where this discussion started.

@hugobarauna

This comment has been minimized.

Copy link

@hugobarauna hugobarauna commented Sep 1, 2010

I use and prefer the first one. In my opinion the second options is more difficult to read.

@lfcipriani

This comment has been minimized.

Copy link

@lfcipriani lfcipriani commented Sep 1, 2010

I prefer the first one too, for me it's kind of weird to have a begin block after a assignment when reading the code. But I'm not against.

@tomas-stefano

This comment has been minimized.

Copy link

@tomas-stefano tomas-stefano commented Sep 1, 2010

I agree with Urubatan about the first but I prefer the third alternative described by the author of that comment.

variable = expression()
if variable
do_stuff_with(variable)
end

Cheers =]

@fpauser

This comment has been minimized.

Copy link

@fpauser fpauser commented Sep 1, 2010

The first one is easier to read and understand I think.

@tomafro

This comment has been minimized.

Copy link

@tomafro tomafro commented Sep 1, 2010

The fact that #2 relies on the precedence of 'and' seems a good reason not to use it. I much prefer #1.

@tomafro

This comment has been minimized.

Copy link

@tomafro tomafro commented Sep 1, 2010

I've added another alternative using unless, though I still prefer #1

@dui

This comment has been minimized.

Copy link

@dui dui commented Sep 1, 2010

haven't seen this much either. aesthetically to me doesn't appeal more than the if example.

We do use a similar idiom on our project for doing simple multiline memoization on some methods like this excerpt: http://gist.github.com/561113

@dui

This comment has been minimized.

Copy link

@dui dui commented Sep 1, 2010

and the only reason why 'and' even exists in ruby is the fact that it has a different precedence to '&&', so I don't think its a good reason not to use it, unless you want to argue using 'and' is never a good idea.

@rogerleite

This comment has been minimized.

Copy link

@rogerleite rogerleite commented Sep 1, 2010

I prefer the first case. Like hugobarauna said.

@danielvlopes

This comment has been minimized.

Copy link

@danielvlopes danielvlopes commented Sep 1, 2010

Pretty good. Both have use cases depending on the situation.

@dirceup

This comment has been minimized.

Copy link

@dirceup dirceup commented Sep 1, 2010

cool

@fnando

This comment has been minimized.

Copy link

@fnando fnando commented Sep 1, 2010

I'll go with assignment then checking.

variable = expression(something)
if variable
end

Can't be easier to read than that.

@smsohan

This comment has been minimized.

Copy link

@smsohan smsohan commented Sep 1, 2010

While the 2nd syntax is new to me and sounds "Techy" - I would still take the simple approach of assigning first and then checking. It way more readable to me this way.

@evanphx

This comment has been minimized.

Copy link

@evanphx evanphx commented Sep 1, 2010

Heavily dislike the 2nd syntax. It's extremely clever and hard to read. You should be asking yourself: Will the next person to read this code have a clear idea what I've done? I can't see yes being the answer.

@danielvlopes

This comment has been minimized.

Copy link

@danielvlopes danielvlopes commented Sep 1, 2010

Thinking in that way I agree with @evanphx. Second syntax is not common and most of people we don't know how it works.

@raggi

This comment has been minimized.

Copy link

@raggi raggi commented Sep 2, 2010

i prefer the if, by far.

@pahagon

This comment has been minimized.

Copy link

@pahagon pahagon commented Sep 2, 2010

In the second, there seems to be a condition

@sferik

This comment has been minimized.

Copy link

@sferik sferik commented Jul 25, 2011

Typically, when I'm doing something like this, I want to be able to specify an elsif or else condition, which isn't possible using begin, for instance:

if rubygem = Rubygem.find_by_name(gem_name)
  render :json => rubygem.public_versions
else
  render :text => "This rubygem could not be found.", :status => 404
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment