การวิเคราะห์ทางเทคนิคล่าสุดที่เน้นย้ำถึงข้อผิดพลาดมากมายในการแยกวิเคราะห์ของ YAML ได้จุดประกายการอภิปรายเกี่ยวกับรูปแบบไฟล์การกำหนดค่าในชุมชนนักพัฒนาอีกครั้ง แม้ว่า YAML จะถูกออกแบบมาให้เป็นมิตรกับมนุษย์มากกว่า JSON แต่ความซับซ้อนของมันได้สร้างพฤติกรรมที่ไม่คาดคิดซึ่งทำให้แม้แต่นักพัฒนาที่มีประสบการณ์ยังต้องประหลาดใจ
ความขัดแย้งของความเรียบง่าย
ปัญหาหลักเกิดจากเป้าหมายที่มีความทะเยอทะยานของ YAML ที่ต้องการให้มนุษย์อ่านได้ในขณะที่ยังคงความสามารถในการแยกวิเคราะห์ของเครื่องจักร ต่างจาก JSON ที่ใช้เพียงหกไดอะแกรมรถไฟในข้อกำหนดของมัน YAML ต้องการ 10 บทพร้อมการกำหนดหมายเลขส่วนลึกสี่ระดับและหน้าข้อผิดพลาดเฉพาะ ความซับซ้อนนี้ปรากฏในหลายวิธีที่เป็นปัญหาซึ่งนักพัฒนาพบเจอเป็นประจำ
ปัญหา Norway เป็นตัวอย่างที่สมบูรณ์แบบของปัญหาเหล่านี้ รหัสประเทศเช่น NO (Norway) จะถูกแปลงเป็นค่าบูลีน false โดยอัตโนมัติ ทำให้เกิดความล้มเหลวแบบเงียบๆ ในไฟล์การกำหนดค่า ในทำนองเดียวกัน ค่าต่างๆ เช่น on, off, yes และ no จะถูกตีความเป็นบูลีนแทนที่จะเป็นสตริง ทำให้เกิดพฤติกรรมที่ไม่คาดคิดเมื่อคำทั่วไปเหล่านี้ปรากฏในข้อมูลการกำหนดค่า
สรุปปัญหาการแยกวิเคราะห์ YAML:
- ปัญหา Norway: รหัสประเทศเช่น "NO" จะถูกแปลงเป็นค่าบูลีน
false
- การแปลงค่าบูลีน: "on", "off", "yes", "no" จะกลายเป็นค่าบูลีนโดยอัตโนมัติ
- ตัวเลขระบบหกสิบ: "22:22" จะถูกแยกวิเคราะห์เป็นนิพจน์ทางคณิตศาสตร์ (1342) แทนที่จะเป็นสตริง
- สตริงที่ไม่มีเครื่องหมายคำพูด: การแปลงประเภทข้อมูลอัตโนมัติสร้างพฤติกรรมที่ไม่คาดคิด
- ข้อกำหนดที่ซับซ้อน: 10 บทที่มีส่วนย่อยลึก 4 ระดับ เทียบกับ JSON ที่มีแผนภาพ railroad เพียง 6 อัน
ตัวเลขฐานหกสิบและความประหลาดใจอื่นๆ
หนึ่งในคุณลักษณะที่แปลกประหลาดที่สุดของ YAML คือการสนับสนุนตัวเลขฐานหกสิบ (base-60) ค่าที่เหมือนการประทับเวลาเช่น 22:22 จะถูกแยกวิเคราะห์เป็นนิพจน์ทางคณิตศาสตร์แทนที่จะเป็นสตริง ทำให้ได้ตัวเลขทศนิยม 1342 คุณลักษณะนี้ซึ่งน่าจะถูกเพิ่มเข้ามาเพื่อสนับสนุนค่าเวลา สร้างความสับสนในบริบทที่การแยกวิเคราะห์เช่นนี้ไม่คาดคิด
ชุมชนได้ระบุกับดักการแยกวิเคราะห์เพิ่มเติมรวมถึงการแปลงประเภทอัตโนมัติของสตริงที่ไม่มีเครื่องหมายคำพูด ระบบ anchor และ alias ที่ซับซ้อน และการสนับสนุนคีย์ที่ไม่ใช่สตริงซึ่งอาจเสียหายในรูปแบบที่ละเอียดอ่อน
โซลูชันชุมชนและวิธีแก้ไขปัญหา
นักพัฒนาได้พัฒนากลยุทธ์ต่างๆ เพื่อลดปัญหาของ YAML วิธีการที่พบบ่อยที่สุดคือการใส่เครื่องหมายคำพูดรอบค่าสตริงทั้งหมด ซึ่งจะขจัดปัญหาการแปลงประเภทอัตโนมัติส่วนใหญ่ เครื่องมือเช่น yamllint สามารถตรวจจับปัญหาหลายอย่างระหว่างการพัฒนา แม้ว่าสิ่งนี้จะเพิ่มความซับซ้อนให้กับสิ่งที่ควรเป็นรูปแบบการกำหนดค่าที่เรียบง่าย
เกือบทั้งหมดนี้ได้รับการแก้ไขโดยการใส่เครื่องหมายคำพูดรอบสตริง YAML มีกรณีการใช้งานที่คุณต้องการสิ่งที่ JSON ไม่ทำ เช่น การเรียกซ้ำหรือ anchors/aliases/tags
ทีมบางทีมได้นำ StrictYAML มาใช้ ซึ่งเป็นส่วนย่อยที่ขจัดคุณลักษณะที่เป็นปัญหาโดยสนับสนุนเพียงสตริง รายการ และพจนานุกรม ทีมอื่นๆ สร้าง JSON จากภาษาที่เหมาะสมกว่าแทนที่จะเขียน YAML ด้วยมือ ซึ่งให้การนามธรรมและความสามารถในการนำกลับมาใช้ใหม่ที่ดีกว่า
กลยุทธ์การลดความเสี่ยงของ YAML :
- ใส่เครื่องหมายคำพูดให้กับสตริงทั้งหมด: ช่วยขจัดปัญหาการแปลงประเภทข้อมูลอัตโนมัติส่วนใหญ่
- ใช้ yamllint: ช่วยตรวจจับปัญหาทั่วไปในระหว่างการพัฒนา
- หลีกเลี่ยงคีย์ที่มีปัญหา: อย่าใช้ "on", "off", "yes", "no" เป็นคีย์ที่ไม่มีเครื่องหมายคำพูด
- สร้าง JSON: ใช้ภาษาโปรแกรมมิ่งในการสร้าง JSON แทนการเขียน YAML ด้วยมือ
- การนำ StrictYAML มาใช้: ใช้เซ็ตย่อยที่ลบฟีเจอร์ที่มีปัญหาออกไป
การค้นหาทางเลือกที่ดีกว่า
การอภิปรายได้เน้นย้ำรูปแบบการกำหนดค่าทางเลือกหลายรูปแบบที่กำลังได้รับความสนใจ TOML เสนอความเรียบง่ายโดยไม่มีปัญหาของ YAML แต่ขาดการแสดงออกสำหรับการกำหนดค่าที่ซับซ้อน HashiCorp Configuration Language (HCL) ให้ความสามารถในการตรวจสอบที่เพิ่มความมั่นใจในการตั้งค่าขนาดใหญ่ ตัวเลือกที่เป็นการทดลองมากกว่าเช่น CUE, Dhall และ KDL พยายามแก้ไขข้อบกพร่องของ YAML ด้วยวิธีการที่แตกต่างกันในการจัดการการกำหนดค่า
JSON5 และ JSONC (JSON with comments) ได้เกิดขึ้นเป็นโซลูชันกึ่งกลาง โดยเพิ่มการสนับสนุนความคิดเห็นที่ทำให้ YAML น่าสนใจในขณะที่ยังคงพฤติกรรมการแยกวิเคราะห์ที่คาดเดาได้ของ JSON อย่างไรก็ตาม รูปแบบเหล่านี้ขาดการยอมรับอย่างแพร่หลายที่ทำให้ YAML แพร่หลายในเวิร์กโฟลว์การพัฒนาสมัยใหม่
รูปแบบการกำหนดค่าทางเลือก:
- TOML: รูปแบบที่เรียบง่ายโดยไม่มีข้อผิดพลาดของ YAML แต่มีความสามารถในการแสดงออกที่จำกัด
- HCL (HashiCorp): มีความสามารถในการตรวจสอบความถูกต้อง เหมาะสำหรับ infrastructure as code
- JSON5/JSONC: JSON ที่มีความคิดเห็นและเครื่องหมายจุลภาคต่อท้าย
- StrictYAML: ชุดย่อยของ YAML ที่มีเพียงสตริง รายการ และพจนานุกรม
- CUE/Dhall/KDL: รูปแบบทดลองที่แก้ไขข้อบกพร่องของ YAML
- Jsonnet: ภาษาเทมเพลตที่สร้าง JSON
ปัญหาความคงอยู่
แม้จะมีปัญหาที่มีการบันทึกไว้อย่างดี YAML ยังคงฝังลึกในเครื่องมือยอดนิยมเช่น Kubernetes, Ansible และระบบ CI/CD นับไม่ถ้วน สิ่งนี้สร้างเอฟเฟกต์เครือข่ายที่นักพัฒนาต้องทำงานกับ YAML โดยไม่คำนึงถึงความชอบของพวกเขา ความน่าสนใจทางสายตาของรูปแบบผ่านโครงสร้างที่ใช้การเยื้องยังคงดึงดูดผู้ใช้ แม้ในขณะที่พวกเขาพบกับความซับซ้อนในการแยกวิเคราะห์
การถกเถียงสะท้อนถึงความท้าทายที่กว้างขึ้นในการพัฒนาซอฟต์แวร์: การสร้างสมดุลระหว่างความสามารถในการอ่านของมนุษย์กับความสามารถในการแยกวิเคราะห์ของเครื่องจักร ในขณะที่ YAML ประสบความสำเร็จในการสร้างรูปแบบที่ดูสะอาดและอ่านได้ ความซับซ้อนที่ซ่อนอยู่มักจะทำลายผลประโยชน์ด้านผลิตภาพที่มันตั้งใจจะให้
ในขณะที่ชุมชนยังคงสำรวจทางเลือก ฉันทามติดูเหมือนจะเป็นการตระหนักรู้มากกว่าการละทิ้ง การเข้าใจข้อผิดพลาดของ YAML การใช้เครื่องมือที่เหมาะสม และการรู้ว่าเมื่อไหร่ควรเลือกทางเลือกดูเหมือนจะเป็นเส้นทางที่ปฏิบัติได้สำหรับทีมพัฒนาส่วนใหญ่
อ้างอิง: The yaml document from hell