Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เชี่ยวชาญ Ruby Case Statement: เทคนิคขั้นสูงและ Best Practices

ไม่มีอะไรเรียบง่ายและน่าเบื่อกว่า case statement มันมาจาก C ใช้แทน if หลายๆ ตัว จบเรื่อง หรือไม่?

จริงๆ case statements ใน Ruby ริชและซับซ้อนกว่าที่คิด มาดูตัวอย่าง:


case "Hi there"
when String
  puts "case statements match class"
end
# outputs: "case statements match class"

ตัวอย่างนี้แสดงว่า case statements ไม่ได้ match แค่ ค่า แต่ match คลาส ด้วย เพราะภายใต้ Ruby ใช้ operator === (three equals operator)

ทัวร์เร็วกับ operator ===

เวลาเขียน x === y ใน Ruby คุณกำลังถามว่า "y อยู่ในกลุ่มที่ x แทนไหม?" นี่คำพูดทั่วไป รายละเอียดขึ้นอยู่กับประเภทของกลุ่ม


# เรียก Class.===(item) คืน true ถ้า item เป็น instance ของคลาส
String === "hello" # true
String === 1       # false

Strings, regular expressions และ ranges กำหนด ===(item) เอง พฤติกรรมคาดเดาได้ คุณเพิ่ม triple equals method ให้คลาสของตัวเองได้ด้วย

ตอนนี้เรารู้แล้ว เราทำเคล็ดลับกับ case ได้หลายอย่าง

Match ranges ใน case statements

ใช้ ranges ได้เพราะ range === n คืนค่า range.include?(n) อยู่ใน docs


case 5
when (1..10)
  puts "case statements match inclusion in a range"
end
# outputs "case statements match inclusion in a range"

Match regular expressions กับ case statements

ใช้ regex ได้เพราะ /regexp/ === "string" คืน true ก็ต่อเมื่อ string match regex ดู docs ของ Regexp


case "FOOBAR"
when /BAR$/
  puts "they can match regular expressions!"
end
# outputs "they can match regular expressions!"

Match procs และ lambdas

นี่แปลกหน่อย Proc#===(item) เทียบเท่า Proc#call(item) ดู docs ได้ หมายความว่าใช้ lambdas/procs ใน case statement เป็น dynamic matchers ได้


case 40
when -> (n) { n.to_s == "40" }
  puts "lambdas!"
end
# outputs "lambdas"

เขียน Matcher Classes เอง

เพิ่ม custom case behavior ให้คลาสของคุณง่ายแค่กำหนด === เอง ใช้ได้กับการแยก conditional logic ซับซ้อนเป็นคลาสเล็กๆ หลายตัว ตัวอย่าง:


class Success
  def self.===(item)
    item.status >= 200 && item.status < 300
  end
end

class Empty
  def self.===(item)
    item.response_size == 0
  end
end

case http_response
when Empty
  puts "response was empty"
when Success
  puts "response was a success"
end