I got a wrong value in a very simple piece (as I thought) of code:
org = 4
case org
when org <= 1
val = 'L'
when 2..3
val = 'M'
when org >= 4
val = 'H'
end
puts val
=> nil
Please, don't be angry, I expect that I missed something very obvious, but I really can't figure it out. Thanks.
This is a classic Ruby blunder. case
has two methods of being called, one where you pass in a thing to branch based on, and one where you don't.
If you do specify an expression in the case
statement then all the other conditions are evaluated and compared with ===
. In this case org <= 1
evaluates down to false
and org === false
is obviously not true. The same goes for all other cases, they're either true or false. That means none of them match.
If you don't specify an expression then case
behaves like a fancy if
.
Switch case org
to case
and it works. You can also switch to ranges:
val =
case org
when 0..1
'L'
when 2..3
'M'
else
'H'
end
The way your original code executes is as if it were:
org = 4
if (org <= 1) === org
val = 'L'
elsif (2..3) === org
val = 'M'
elsif (org >= 4) === org
val = 'H'
end
Which is not what you want.
As an alternative, you could write:
letters = %w(L L M M H)
val = letters[org.clamp(0,4)]
It uses Comparable#clamp
, which comes with Ruby 2.4.
For Ruby 2.3 and older, you can use :
val = letters[[0, org, 4].sort[1]]
This way, it's fine if org
is smaller than 0
or larger than 4
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With