Ruby: Case Expressions Pro

Ruby case 原理

平常我们使用case语句时,条件基本都是是否相等、是否在Range中、是否匹配正则、是否为类的实例,这些背后的原理都是调用了比较对象的===方法。

case something
when Array then ...
when 1..100 then ...
when /some_regexp/ then ...
end
# 相当于
case something
when Array === something then ...
when 1..100 === something then ...
when /some_regexp/ === something then...
end

调用对象的方法进行比较

比方说我们有这样灯这样的一个类,想让如下的case语句正常执行,该用什么方法?

class Lamp
  def initialize(color)
    @color = color
  end

  def green?
    @color == "green"
  end

  def red?
    @color == "red"
  end

  def yellow?
    @color == "yellow"
  end
end

lamp = Lamp.new("red")

case lamp
when green?
  puts "it's green"
when red?
  puts "it's red"
when yellow?
  puts "it's yellow"
else
  "Unkown color"
end

那么我们可以把方法包装成一个proc,在proc当中call相当于===

is_even = ->(n) { n.even? }
is_even === 5 # => false
# 相当于
is_even.call(5)

使用Proc

case lamp
when -> (x) { x.green? }
  puts "it's green"
when -> (x) { x.red? }
  puts "it's red"
when -> (x) { x.yellow? }
  puts "it's yellow"
else
  "Unkown color"
end

Reference:

The Many Uses Of Ruby Case Statements

Lambdas/Procs in Case Expressions