Ruby ยืดหยุ่นมากในเรื่องอาร์กิวเมนต์ของเมธอด มีทุกอย่างครบครัน: required arguments, optional arguments, และ keyword (named) arguments บทความนี้จะช่วยให้เข้าใจความแตกต่างและเลือกใช้ให้เหมาะสม
When in Doubt Use Standard Arguments (Required Arguments)
Required arguments เป็นค่าเริ่มต้น ต้องส่งครบตามจำนวน:
def write(file, data, mode)
end
write("cats.txt", "cats are cool!", "w")
ส่งไม่ครบจะได้ ArgumentError: wrong number of arguments
Flexible Methods With Optional Arguments (อาร์กิวเมนต์ตัวเลือก)
กำหนดค่าเริ่มต้นเพื่อทำให้เป็นตัวเลือกได้:
def write(file, data, mode = "w") end
เรียกได้ 2 อาร์กิวเมนต์ (mode จะเป็น "w") หรือ 3 อาร์กิวเมนต์เพื่อ override
Use Keyword Arguments to Increase Clarity (Keyword Arguments)
Required/optional arguments ขึ้นกับลำดับ สลับลำดับจะได้ผลผิด Keyword arguments แก้ปัญหานี้:
def write(file:, data:, mode: "ascii") end write(data: 123, file: "test.txt")
เรียกได้ไม่ตามลำดับ และเห็นความหมายชัดเจน เหมาะสำหรับหลีกเลี่ยงความสับสน เช่น Point.new(x: 10, y: 20)
Keyword arguments แจ้ง argument ที่ขาดหายไปชัดเจน: missing keywords: x, y
สามารถผสมกับ regular arguments ได้ Ruby built-in methods มักเพิ่ม optional arguments ใหม่เป็น keyword arguments (เช่น Float#round, Kernel#clone, String#lines ใน Ruby 2.4)
Use Variable Arguments to Capture as Many Values as Necessary (Variable Arguments)
รับค่าไม่จำกัดจำนวนด้วย splat operator:
def print_all(*args) end print_all(1, 2, 3, 4, 5)
คืนค่าเป็น Array สามารถผสมกับ arguments อื่นได้ แต่ต้องอยู่หลัง required/optional และก่อน keyword arguments
def print_all(title, *chapters) end
Use The Correct Order (ลำดับที่ถูกต้อง)
required → optional → variable → keyword
ตัวอย่างครบทุกประเภท:
def testing(a, b = 1, *c, d: 1, **x)
p a,b,c,d,x
end
testing('a', 'b', 'c', 'd', 'e', d: 2, x: 1)
**x คือ variable arguments สำหรับ keyword arguments (คืนค่า Hash)
The Catch-All Argument (Catch-All)
def print_all(*) end รับอาร์กิวเมนต์อะไรก็ได้แต่ไม่ใช้ เหมือน _ ในบล็อก ใช้ร่วมกับ super ได้:
class Food
def nutrition(vitamins, minerals)
puts vitamins; puts minerals
end
end
class Bacon < Food
def nutrition(*)
super
end
end
Food เปลี่ยน arguments ก็ไม่ต้องแก้ Bacon
Summary
เรียนรู้ Ruby method arguments ทั้ง required, optional, keyword, variable, และ catch-all ใช้ required เป็นพื้นฐาน เพิ่มความยืดหยุ่นด้วย optional เพิ่มความชัดเจนด้วย keyword arguments