LaunchKit
All quizzes
Ruby 0 views

Two identical when clauses in one case

Question

What's the return value of the following Ruby code?

a   = [1, 2]
res = []

case a.size
when 2 then res << 1
when 2 then res << 2
end

res # => ???

The correct answer is

Explanation

TL;DR

A case statement tests its when clauses top to bottom and executes only the first one that matches, then exits. a.size is 2, the first when 2 matches and appends 1, and the second when 2 is never reached. res is [1].

Step by step

a   = [1, 2]
res = []

case a.size
when 2 then res << 1
when 2 then res << 2
end

res # => [1]

There is no fall-through in Ruby's case. Unlike a C switch, a matching branch does not continue into the next one, and no break is needed. A second clause with the same condition is simply dead code.

Under the hood

Each when tests its candidate against the case value with the case equality operator ===, in source order. The snippet is equivalent to:

a   = [1, 2]
res = []

if 2 === a.size
  res << 1
elsif 2 === a.size
  res << 2
end

res # => [1]

Once the if branch matches, the elsif condition is never evaluated. Ruby knows the duplicated clause is unreachable: run the original snippet with warnings enabled (ruby -w) and it prints a warning that the second when clause duplicates the first and is ignored.

Edge cases

To run one branch for several values, list them in a single when instead of repeating clauses:

result =
  case [1, 2].size
  when 2, 3 then :few
  else :many
  end

result # => :few

case is an expression: it returns the value of the branch that ran. When nothing matches and there is no else, it returns nil:

result =
  case 5
  when 2 then :two
  end

result # => nil

Share this quiz

Comments

No comments yet. Be the first.

Only used to confirm and publish your comment. Never shown publicly, never shared.

Markdown: **bold**, `code`, ```fenced blocks```, > quotes, [links](url). HTML and images are not rendered.