Style question: if !x vs. unless x

Hi all,

One of the coolest things for me about learning ruby is that it’s the
first language I’ve learned in a decade where I actually had to learn a
new language. Once you know C/C++, you can pick up Java, PHP, perl,
Python, and even VB without really having to learn new grammar… you
just learn where the braces and dollar signs go. One of the joys of
ruby is that when I find myself using a klunky grammar construct, there
is often an elegant solution if I will just surrender my C++ thinking
style.

That paragraph could spark a thread of its own, but in this case, its
lead-up for a simpler question. Which do you find more readable:

this version

if !correct
handle_error
do_some_other_thing
end

or this version

unless correct
handle_error
do_some_other_thing
end

When dealing with single-lines, I find the inverted construct to be MUCH
more readable:

handle_error unless correct

but when I have to make a block, my C++ instincts really prefer the “if
!” version.

I’m just throwing this out here… what do you prefer, and why? Do you
find the “unless x” construct as (or more) readable than the “if !x”
construct? When I see a block beginning with unless, I really have to
stop reading and tease out the logic. Is this a good instinct thing, or
is it simply me lacking fluency in a common ruby idiom?

Hmm, I just discovered this syntax, and for small blocks, I prefer it
greatly:

( handle_error; do_some_other_thing ) unless correct

Though I worry that ( …, … ) syntax may have some side effects I’m
not expecting. That’s list declaration syntax, isn’t it? So using it
as a block might bend POLS…

-dB

On 4/11/06, David B. [email protected] wrote:

end
Another version that works, but is a little confusing to read for
anything larger than a handful of lines:

begin
handle_error
do_some_other_thing
end unless correct

This is essentially just creating an anonymous scope (the begin/end)
and appending the postcondition to that.

David B. wrote:

unless correct
“if !” version.

I’m just throwing this out here… what do you prefer, and why? Do
you find the “unless x” construct as (or more) readable than the “if
!x” construct?

-dB

Personally, I’ve been going with the ‘unless’ statement much more often,
but it depends on the context. I generally use “unless” when I think the
conditional is unusual and I normally would do what’s in the block:

unless something_is_weird
do stuff
end

But that’s just because I’m thinking about the normal meaning of
‘unless’.
I also use the ‘word’ versions of logical operators to make things more
clear for myself:

if not correct
#do something
end

is very easy to follow. Just beware of the lower precedence of those
constructs.
This could be just me, though.

-Justin

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Charlie B. wrote:

I never like to start a line off with unless. It just looks confusing
to me.

Multi-conditional unless statements look confusing to me. But I am with
Justin, depending on the context of the conditional may
make it seem more approriate to do “unless” vs. “if not”.

I tend to use both, although I no longer use multi-conditional unless
statements, ever.

Zach
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFEO/lEMyx0fW1d8G0RAjrsAJsEEZKFZcKlKo9t3NL775T2pIzrDwCfT6zu
dx1CSKYE5CnL/0M0SoX7Deg=
=1NrV
-----END PGP SIGNATURE-----

zdennis wrote:

I tend to use both, although I no longer use multi-conditional unless statements, ever.

Interesting. You mean like this?

if x
do_something
end unless y

I do like this syntax, though:

do_something if condition unless exception

Oh, wait. By multiconditional unless, you mean stuff like this:

unless ( a || b || c )
do_something
end

…yes?

-dB

On Apr 12, 2006, at 2:31 AM, David B. wrote:

Oh, wait. By multiconditional unless, you mean stuff like this:

unless ( a || b || c )
do_something
end

…yes?

I’m pretty sure he means:

unless condition

else

end

or

unless condition

elsif othercondition

else

end

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Logan C. wrote:

unless condition

elsif othercondition

else

end

I mean what Logan said plus the second half of what Dave said. I do not
like the following, and I find it a) sometimes confusing
to read and b) my brain has to think twice when reading, which is twice
to much:

unless condition

elsif

else

end

unless cond1 and cond2 and cond3

end

unless (cond1 and cond2) or cond3

end

do_something unless cond1 and cond2

In regards to the first half of Dave’s email:

if x
do_something
end unless y

I do like this syntax, though:

do_something if condition unless exception

I have never thought of chaining conditionals like that, although the
idea is very cool… and I find it readable in the case of
error handling. (I wont say exception handling because IMO the two
differ and exceptions should be handled by a different
mechanism then what error conditions should be handled under, the whole
90/10 rule applies of course.) =)

Zach

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFEPM/LMyx0fW1d8G0RAvJgAJwKfktuwgUbcI6iZ+Nd0mVzqxoq5gCeJhoX
f7Ygn98m+JdYMPB5ZkrvL4c=
=h6ey
-----END PGP SIGNATURE-----

I never like to start a line off with unless. It just looks confusing
to me.

2006/4/11, David B. [email protected]:

That paragraph could spark a thread of its own, but in this case, its
handle_error
do_some_other_thing
end

When dealing with single-lines, I find the inverted construct to be MUCH
more readable:

handle_error unless correct

In fact I’d usually make the above a single liner by using exceptions:

raise SomeError unless correct

continue normal processing

alternative

correct or raise SomeError

continue normal processing

but when I have to make a block, my C++ instincts really prefer the “if
!” version.

I usually use “unless” if there is a single negated expression and use
“if” otherwise. No distinction with regard to single line or block.

Hmm, I just discovered this syntax, and for small blocks, I prefer it
greatly:

( handle_error; do_some_other_thing ) unless correct

I don’t like that. Use the normal if … then … end - that looks
better, to me at least.

Kind regards

robert

I don’t think you can actually use elsif with an unless block:

$ irb --simple-prompt

unless true
elsif true
end
SyntaxError: compile error
(irb):2: parse error, unexpected kELSIF
elsif true
^
from (irb):3
if true
elsif true
end
=> nil

Personally, I use unless any time my primary test is for a negated
condition (and I don’t need elsif). It takes a little while to get used
to perhaps, but if you think about it as meaning “if not” (which is what
unless actually means) it works. The think I like about using “unless x”
as opposed to “if !x” or “if not x” is that there is no precedence to
think about, it’s totally clear that it negates the entire condition.

zdennis wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Logan C. wrote:

unless condition

elsif othercondition

else

end

I mean what Logan said plus the second half of what Dave said. I do not
like the following, and I find it a) sometimes confusing
to read and b) my brain has to think twice when reading, which is twice
to much:

unless condition

elsif

else

end

unless cond1 and cond2 and cond3

end

unless (cond1 and cond2) or cond3

end

do_something unless cond1 and cond2

In regards to the first half of Dave’s email:

if x
do_something
end unless y

I do like this syntax, though:

do_something if condition unless exception

I have never thought of chaining conditionals like that, although the
idea is very cool… and I find it readable in the case of
error handling. (I wont say exception handling because IMO the two
differ and exceptions should be handled by a different
mechanism then what error conditions should be handled under, the whole
90/10 rule applies of course.) =)

Zach

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFEPM/LMyx0fW1d8G0RAvJgAJwKfktuwgUbcI6iZ+Nd0mVzqxoq5gCeJhoX
f7Ygn98m+JdYMPB5ZkrvL4c=
=h6ey
-----END PGP SIGNATURE-----