Reputation: 135
I want to ask for a little explanation about if and unless, I know the two of this is an opposite of each other. All of this time I have used both without no problem until now I find something weird. Let's check my code :
ausysdir = AUDIO_SYSTEM_FOLDER_NAME
Dir.mkdir(ausysdir) if ausysdir != "" && !File.directory?(ausysdir) # Number 1
Dir.mkdir(ausysdir) unless ausysdir == "" && File.directory?(ausysdir) # Number 2
Now in the directory I work the folder ausdyr is already exist. But from the code above the the number one conditional which is if not return an error(this is what I expected, so great), But not with number 2 conditional which is unless, when I think that if and unless is an opposite, then my syntax above should be correct, am I right? Or my syntax is wrong? Or Unless have a different behaviour? Or do I missed something here?
Thank you very much.
EDIT : When I mean error, is an exception because the file is already exist.
Upvotes: 0
Views: 593
Reputation: 1240
TL;DR Don't use unless
with more than one condition. Most people have to think too hard to understand it, and then have about a 50/50 chance of getting it right.
Here is a test of two booleans using if
/unless
and &&
/or
:
def test(first, second)
puts "#{first}, #{second}"
puts " ...passes if #{first} && #{second}" if first && second
puts " ...passes unless #{first} && #{second}" unless first && second
puts " ...passes if #{first} || #{second}" if first || second
puts " ...passes unless #{first} || #{second}" unless first || second
end
test(true, true)
test(true, false)
test(false, true)
test(false, false)
The results:
true && true
...passes if true && true
...passes if true || true
true && false
...passes unless true && false
...passes if true || false
false && true
...passes unless false && true
...passes if false || true
false && false
...passes unless false && false
...passes unless false || false
Your first condition boils down to if false && false
, according to the false, false
results above, if false && false
doesn't pass. Reaction: Pretty straightforward and easy to see.
Your second condition boils down to unless false && true
, according to the false, true
results above, unless false && true
does pass. Reaction: That seems like it possibly might make sense if I think about it some more.
Upvotes: 1
Reputation: 434585
unless expr
is the same as if !expr
. But !(a && b)
is not !a && !b
as you seem to think, it is actually !a || !b
(this is one of De Morgan's laws BTW). So your if
and unless
statements are not at all equivalent.
Build the truth table if you don't believe me. Then study some Propositional Calculus (which every programmer should be familiar with) if you don't believe your truth table.
If your if
works then you're unless
would be:
unless ausysdir == "" || File.directory?(ausysdir)
Upvotes: 1