{{ currentPost.title }}
{{ currentPost.datetime }}

寫法

根據 Ruby Style Guide,建議的寫法是 casewhen是在同一層:

case
when song.name == 'Misty'
  puts 'Not again!'
when song.duration > 120
  puts 'Too long!'
when Time.now.hour > 21
  puts "It's too late"
else
  song.play
end

如果case前面有接變數,則對齊等號或是縮排一層:

kind = case year
       when 1850..1889 then 'Blues'
       when 1890..1909 then 'Ragtime'
       when 1910..1929 then 'New Orleans Jazz'
       when 1930..1939 then 'Swing'
       when 1940..1950 then 'Bebop'
       else 'Jazz'
       end

kind = case year
  when 1850..1889 then 'Blues'
  when 1890..1909 then 'Ragtime'
  when 1910..1929 then 'New Orleans Jazz'
  when 1930..1939 then 'Swing'
  when 1940..1950 then 'Bebop'
  else 'Jazz'
  end

由上面的例子也可以看出來then只有在一行的時候使用,如果是判斷條件完要執行多行的程式,則不寫 then

判斷式

除了一般的boolean判斷,when後面可以接的東西比你像想的還多…

case
when a == 5
  # 一般的boolean運算式。
when 'a', 'b'
  # 可接多的值。
when *['a', 'b']
  # 接多個值可以用這個方式寫成一個Array。
when 1..10
  # 可接一個Range
when /^[a-z]{3}/
  # 可接Regex。
when MyClass, MySubClass
  # 可接class,這時會判斷傳進來的物件是不是這個class的instance
else
  # 如果上面都沒有符合的,跑這裡。
end

實際上when是採用 ===做為判斷的,所以你可以在你自己的class實作 ===的運算式method,那就可以在case中使用了。例如:

class A
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def ===(given_a)
    name == given_a.name
  end
end

a = A.new('Kevin')
b = A.new('Kait')
c = A.new('Kevin')

case a
when b
  puts 'Has the same name with b.'
when c
  puts 'Has the same name with c.' # The result
else
  puts 'Has the same name with nobody.'
end

Refs