Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happen with a condition on a case?

Tags:

ruby

I was playing today and accidentally end up writting this, now I'm courious.

i = 101
case i
  when 1..100
     puts " will never happen "
  when i == 101
     puts " this will not appear "
  else
     puts " this will appear"
end

How ruby internally process when i == 101 is like i == (i == 101) ?

like image 718
Arnold Roa Avatar asked Jan 18 '26 15:01

Arnold Roa


2 Answers

Your code is equivalent to:

if (1..100) === 101
  puts " will never happen "
elsif (101 == 101) === 101 
  puts " this will not appear "
else
  puts " this will appear"
end

If we look at Range#=== we see that

(1..100) === 101

is equivalent to:

(1..100).include?(101)
   #=> false

(101 == 101) === 101 reduces to:

true === 101

We see from the doc for TrueClass#=== that this is equivalent to:

true == 101
  #=> false

Hence, the else clause is executed.

like image 86
Cary Swoveland Avatar answered Jan 20 '26 13:01

Cary Swoveland


The structure

case a
  when x
    code_x
  when y
    code_y
  else
    code_z
end

evaluates identically to

if x === a
  code_x
elsif y === a
  code_y
else
  code_z
end

Each when calls the method === on the argument of when, passing the argument of case as the parameter (x === a is identical to x.===(a)). The === method is slightly different than ==: it is typically called "case subsumption". For simple types like numbers and strings, it is the same thing as ==. For Range and Array objects, it is a synonym for .include?. For Regexp objects, it is quite similar to match. For Module objects, it tests whether the argument is an instance of that module or one of its descendants (basically, if x === a then a.instance_of?(x)). Thus, in your code,

if (1..101) === i
  ...
elsif (i == 101) === i
  ...
else
  ...
end

which performs pretty much the same tests as

if (1..101).include?(i)
  ...
elsif (i == 101) == i
  ...
else
  ...
end

Note that there is another form of case that does not employ ===:

case
  when x
    code_x
  when y
    code_y
  else
    code_z
end

which is identical to

if x
  code_x
elsif y
  code_y
else
  code_z
end
like image 40
Amadan Avatar answered Jan 20 '26 13:01

Amadan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!