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