
Using “and” and “or” in Ruby - fogus
http://avdi.org/devblog/2010/08/02/using-and-and-or-in-ruby/
======
raganwald
I use this a lot. I dislike side effects in the subject clause of an if
statement, so I used to rewrite:

    
    
        if user = User.find(...)
          ...
        end
    

as:

    
    
        user = User.find(...)
        if user
          ...
        end
    

I then got into the habit of using and:

    
    
        user = User.find(...) and begin
          ...
        end
    

It just seems to resemble something I'd say to a colleague: "user becomes blah
blah blah and then we do this with it..." Likewise:

    
    
        user = User.find(...) or begin
          user = User.create(...)
          SecurityTheatre.starring(user)
        end
    

This looks to me like it says "find the user or create the user." The
precedence of the words "or" and "and" seems obvious when you think of them as
words rather than as operators, while the precedence of operators naturally
seems higher/tighter.

JM2C...

~~~
KirinDave
I like your find-or-begin pattern, and I've used the or operator to pun that
way before as well.

But just a note, the if x = ... is not a side effect unless the variable "x"
already exists. There's not problem using that as a pun to get rid of lots of
if nesting. Similarly if x &&= ... is very good for avoiding an if-cascade,
albeit more obscure and perhaps less performant.

It's too bad there isn't a beautiful way to do monads or the thrush operator
in Ruby.

------
tomstuart
As per Tim Bray ([http://www.tbray.org/ongoing/When/201x/2010/06/29/No-
Default...](http://www.tbray.org/ongoing/When/201x/2010/06/29/No-Defaults)),
remembering this kind of nonsense is a waste of a perfectly good brain. Just
don't bother.

~~~
msie
I agree with you, but I always wonder if we discount memorization too much
that it impedes learning a language. We can't expect all of a language to be
"logical". There will be always quirks that have to be remembered. If we
discount those parts that have to be remembered then have we shortchanged
ourselves in mastery of a language? Warts and all?

------
draegtun
Also see this blog post: _Logical operators in Perl and Ruby_
[http://eli.thegreenplace.net/2007/06/02/logical-operators-
in...](http://eli.thegreenplace.net/2007/06/02/logical-operators-in-perl-and-
ruby/)

------
gmac
I knew this, but I always find it a rather disappointing choice in the
language design, as I think its capacity for inspiring bugs rather outweighs
its usefulness (which extends as far as making some parentheses unnecessary).

In a nutshell: there are two forms of the AND and OR operators, with different
precedences; in many contexts, you can use them interchangeably; but in some,
they'll behave differently, and could bite you.

------
jim_h
I'm slow this morning. That took me a couple of minutes to get the example.

'foo = 42 and foo / 2'

I was expecting an undefined variable since foo was never set because I was
thinking of it as foo = (42 and foo / 2)

Basically I would write the example as this in 2 lines to avoid confusion and
not use 'and':

foo = 42

foo / 2

Maybe another example in the article would have been better to show the power
of 'and'.

~~~
avdi
Writing it in two lines would defeat the purpose of demonstrating the
difference between && and 'and'.

~~~
CodeMage
Yep, that's an important point: you should probably have chosen a different
example. The one you used will either make people say "it's a lot better to
write it in two lines" or "oh, cool, I can write one liners like that".

Your post is explaining and demonstrating the use of "and" and "or", whose
purpose is to allow idioms which rely on short-circuiting logic to control
side effects, but that particular example didn't involve side effects _after_
the operator (which is the whole point).

Perhaps it would be a good idea to replace that example with one that shows
what would happen if you used "and" in an "if". It would serve the same
purpose as the one you have currently -- show the unintended effects of using
the wrong flavor of operator -- without confusing people or unintentionally
teaching bad practices.

~~~
stevejohnson
I agree that the numeric example in the blog post was a bad one. The use of
'and' just looks confusing in that situation. You might try something like
"foo = open_connection() and send_data()" instead.

------
jewbacca
This seems like a kind of hack-y laziness, specifically in the form of a poor
man's exception. It's no more "magic" than an if statement or any other kind
of block. I would probably use this plenty if I were to use Ruby (Haskell has
spoiled me for strict evaluation forever), but it definitely smells like
language bloat -- you wouldn't need to tell me it's Perl-inspired for me to
strongly suspect it.

------
sunkencity
Yeah I've looked briefly at and before and not gotten it's use, this is
awesome.

In a similar vein it's possible to just hang on a rescue at the end, very
practical and easy to read, like in a view:

<% percent = (count /total.to_f * 100 ).round_with_precision(2) rescue 0 %>

------
bryanlarsen
There's just too much semantic overload on those two operators. I myself have
misread these before. When I use these operators, I always follow with "raise"
or "begin". This customary usage is not going to cause confusion and covers
99% of their usage anyways.

------
code_duck
It works exactly the same in PHP, another twisted offspring of Perl.

------
aneth
If you're relying on obscure not well known operator precedence rules, you are
writing less maintainable code. It's as bad or worse than using meaningless
variable or function names. Use parentheses so your code communicates your
intention.

~~~
KirinDave
Except that it's not obscure at all. "and" and "or" exist specifically to
facilitate this kind of code. That's their primary purpose.

And it's not like that's exactly unusual in the ruby language. Post-
conditionals have a similar low precedence.

~~~
acgourley
Is "this kind of code" worth it? It certainly is aesthetically pleasing and
somewhat terse compared to a parenthesis jungle. But that does outweigh the
fact non-experts don't know exactly what the statement is doing?

~~~
sketerpot
To anyone who learns the idiom, this code is fine, and perfectly readable. I
don't even know Ruby yet, and it took me less than a minute to become fully
comfortable with this kind of code. This isn't a huge barrier to "non-
experts".

~~~
acgourley
Of course it took under a minute, you were reading a nice blog post on the
topic. The problem is not every instance of 'and' will include that
information. And so I worry that if I drop 'and' into some minor glue script I
write - it becomes less self documenting to my coworkers. It's a minor point,
but it can become a slippery slope (see: perl)

~~~
KirinDave
This entire argument is moot. No one cares how obscure a language looks to
someone who is not familiar with it. Do you regularly sit down and decide, “I
am going to use a language I don't know to accomplish something essential and
immediate?” And even if the answer is yes, then do you still not know the
language at the end of that exercise?

This is a very simple, easily understandable and easily readable feature of
Ruby. It's not obscure, complex, or even that unusual. Precedence is something
every competent programmer needs to understand, and it should be part of every
programmer's research to learn a new language. After all, this is a
conversation about the existence of "and" & "or", not their abuse.

~~~
Roboprog
I used to be competent, but now I guess I avoid writing stuff that relies on
_any_ knowledge of operator precedence.

I try to learn what I can of such precedence in the language of the day, since
I will have to maintain other people's "code" (cypher?), but I try to write
obvious "programs" (who is in this play, what are the acts?).

I've been at this over 2 decades, and it's much easier to read something that
uses a few parentheses, a well named intermediate variable or two, or even a
few functions, than it is to read bunch of multiple operators on the same line
gobble-de-gook. Watching somebody else generate a hundred thousand dollars of
wasted product in a manufacturing preparation process a few years back, due to
such a run-on if-statement being fouled up, was also a good confirmation of
this bias. I'm sure my current job in finance offers similar opportunities for
expensive blunders.

------
GrandMasterBirt
Wow, honestly this article helped :), I really did think it was a synonym and
did not realize the precedence implications.

------
sabat
The logic for and/or vs. &&/|| is borrowed directly from Perl. It makes sense
once you use them for a bit.

~~~
_delirium
Maybe I'm not good at the context-switching between parsing things as
operators versus as English, but I find them confusing in Perl except in some
very simple idiomatic cases, where they're fine because I read them as
boilerplate. The common _do_thing or die "error"_ idiom is perfectly readable,
but anything more complex and I start explicitly reasoning about short-circuit
semantics.

It's possible I have that reaction due to the strong negative consensus about
using short-circuiting as control flow in C being hammered into my head at an
early age, though.

