Forum: Ruby Style question: if !x vs. unless x

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
David B. (Guest)
on 2006-04-11 22:05
(Received via mailing list)
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
Jamie M. (Guest)
on 2006-04-11 22:14
(Received via mailing list)
On 4/11/06, David B. <removed_email_address@domain.invalid> 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.
Justin C. (Guest)
on 2006-04-11 22:24
(Received via mailing list)
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?
<snip>
>
>
> -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
Charlie B. (Guest)
on 2006-04-11 22:40
(Received via mailing list)
I never like to start a line off with unless.  It just looks confusing
to me.
zdennis (Guest)
on 2006-04-11 22:43
(Received via mailing list)
-----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-----
David B. (Guest)
on 2006-04-12 10:33
(Received via mailing list)
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
Logan C. (Guest)
on 2006-04-12 11:23
(Received via mailing list)
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
zdennis (Guest)
on 2006-04-12 13:57
(Received via mailing list)
-----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-----
Robert K. (Guest)
on 2006-04-12 17:08
(Received via mailing list)
2006/4/11, David B. <removed_email_address@domain.invalid>:
> 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
Jon B. (Guest)
on 2006-04-12 19:10
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-----
This topic is locked and can not be replied to.