पाठ 4 / 25

Conditionals, case and Ranges

Write expressive conditions with if, unless, modifiers, case/when and ranges.

Expressive control flow

Ruby's if, elsif and else are expressions that return a value, so label = if total > 1000 then "large" else "small" end works, as does the ternary operator. unless reads better for negative conditions (unless order.paid?), but avoid unless ... else. Statement modifiers put short conditions at the end of a line: return if items.empty? and send_reminder unless paid. case/when compares using the === operator, so when clauses can match ranges (when 90..100), classes (when Integer), regular expressions (when /\A\d{6}\z/) and lists of values, and case also returns a value. Ranges are objects: 1..10 includes the end, 1...10 excludes it, and endless ranges (18..) and beginless ranges (..17) express open intervals. Loops exist (while, until, loop do ... end with break), but idiomatic Ruby iterates with methods such as each, times and upto instead of index-based loops.

case/when matching with ===

Each when clause asks whether its pattern matches the value: ranges, classes and regexes all work.

A value token passing a series of differently shaped gates: a bracket range, a class badge and a pattern stencil.
Figure 2.1 — case/when dispatching on ranges, classes and patterns.

case/when, ranges and modifiers

case returns a value, and when clauses use ===.

def grade(marks)
  case marks
  when 85..100 then "A"
  when 70...85 then "B"
  when 40...70 then "C"
  when 0...40  then "Fail"
  else "Invalid"
  end
end

def describe(value)
  case value
  when Integer, Float then "number"
  when /\A\d{6}\z/    then "PIN code"
  when String         then "text"
  when nil            then "missing"
  else "something else"
  end
end

puts grade(72)              # B
puts describe("411001")     # PIN code

def ship(order)
  return "Nothing to ship" if order[:items].empty?   # guard clause with a modifier
  "Shipping #{order[:items].size} items"
end

adult = (18..).cover?(25)   # endless range: true
1.upto(3) { |n| puts n }

A sorting machine with smart slots

case/when is a sorting machine where each slot knows how to recognise its items: one slot takes any number between 85 and 100, another takes any text that looks like a PIN code, another takes anything that is a String.

त्वरित जाँच: Which operator does case/when use to compare the value with each when clause?

  • ==
  • equal?
  • ===
  • <=>
Answer

=== — when clauses call pattern === value, which ranges, classes and regexes implement meaningfully.