Sunday, July 22, 2007
Ruby: Multiple ifs (unless)
I recently ran into some code similar to the snippet below.
Based on reading the code I assumed it worked as expected; however, having never actually tried it myself I decided to hit irb for a moment with the following code.
Sure, I'm not using
The output shows the execution order: The rightmost if (or unless) is evaluated first and then it moves to the next conditional immediately to it's left.
Of course, the statement could be rewritten simply using ||.
Due to short circuit evaluation neither statement executes
item.currency if item.currency != :usd unless item.nil?Based on reading the code I assumed it worked as expected; however, having never actually tried it myself I decided to hit irb for a moment with the following code.
p 3 unless p 2 unless p 1Sure, I'm not using
if, but if and unless have the same precedence, so I thought the example was good enough.p 3 unless p 2 unless p 1
# >> 1
# >> 2
# >> 3The output shows the execution order: The rightmost if (or unless) is evaluated first and then it moves to the next conditional immediately to it's left.
Of course, the statement could be rewritten simply using ||.
item.currency unless item.nil? || item.currency == :usdDue to short circuit evaluation neither statement executes
item.currency != :usd if item.nil?.
Comments:
<< Home
This works because "if" or "unless" are themselves normal expressions (as opposed to regular expressions ;).
As mentioned in the docs however, "This path leads to the gates of madness."!
As mentioned in the docs however, "This path leads to the gates of madness."!
Jay,
I'm not sure that your example expression:
p 3 unless p 2 unless p 1
really shows what you want to.
The problem is that the p method returns nil, so that none of the unless logical expressions evaluate to true.
Here's a more realistic experiment:
irb(main):001:0> p 2
2
=> nil
irb(main):002:0> def q(a)
irb(main):003:1> p a
irb(main):004:1> a
irb(main):005:1> end
=> nil
irb(main):006:0> q 3 unless q 2 unless q 1
1
=> nil
the q method returns it's argument with the side effect of printing it. Note that the unless statement modifiers are evaluated right to left, so only the last invokation of q happens.
By the way, one of your recent blogs just triggered me to write this.
Post a Comment
I'm not sure that your example expression:
p 3 unless p 2 unless p 1
really shows what you want to.
The problem is that the p method returns nil, so that none of the unless logical expressions evaluate to true.
Here's a more realistic experiment:
irb(main):001:0> p 2
2
=> nil
irb(main):002:0> def q(a)
irb(main):003:1> p a
irb(main):004:1> a
irb(main):005:1> end
=> nil
irb(main):006:0> q 3 unless q 2 unless q 1
1
=> nil
the q method returns it's argument with the side effect of printing it. Note that the unless statement modifiers are evaluated right to left, so only the last invokation of q happens.
By the way, one of your recent blogs just triggered me to write this.
<< Home





