Unexpected Behavior in Ruby

I got the wrong value in a very simple part (as I thought) of the 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 do not be angry, I expect that I missed something very obvious, but I really can not understand it. Thank you

+5
source share
2 answers

This is a classic Ruby bug. case has two call methods: one in which you pass the thing to which the branch is being kept, and one where you do not.

If you specify an expression in a case expression, then all other conditions are evaluated and compared with === . In this case, org <= 1 evaluates to false and org === false is obviously incorrect. The same applies to all other cases, they are either true or false. This means that none of them matches.

If you do not 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 source code runs is like this:

 org = 4 if (org <= 1) === org val = 'L' elsif (2..3) === org val = 'M' elsif (org >= 4) === org val = 'H' end 

This is not what you want.

+7
source

Alternatively you can write:

 letters = %w(LLMMH) val = letters[org.clamp(0,4)] 

It uses the Comparable#clamp , which comes with Ruby 2.4.

For Ruby 2.3 and later, you can use:

 val = letters[[0, org, 4].sort[1]] 

So it is ok if org less than 0 or more than 4 .

+2
source

Source: https://habr.com/ru/post/1269993/


All Articles