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 1
Sure, 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
# >> 3
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 ||.
item.currency unless item.nil? || item.currency == :usd
Due to short circuit evaluation neither statement executes
item.currency != :usd
if item.nil?
.
This works because "if" or "unless" are themselves normal expressions (as opposed to regular expressions ;).
ReplyDeleteAs mentioned in the docs however, "This path leads to the gates of madness."!
Jay,
ReplyDeleteI'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.