ภาษาไทยเขียนติดกันไปทั้งประโยคโดยไม่มีการเว้นวรรคระหว่างคำ เช่น "ไปโรงเรียนด้วยกัน" ไม่มีเครื่องหมายใดบอกว่าคำแต่ละคำแบ่งตรงไหน ต้องอาศัยการตัดคำ (word segmentation) ด้วยพจนานุกรมหรือโมเดลภาษาช่วยเดา — ด้วยเหตุนี้ diff ระดับคำในภาษาไทยจึงมีความกำกวมโดยธรรมชาติ ในขณะที่ diff ระดับอักขระกลับให้ผลที่ตรงไปตรงมากว่า เพราะไม่ต้องเดาขอบเขตคำเลย
Longest Common Subsequence
วิธี diff แบบคลาสสิกอิงจากการหา longest common subsequence (LCS) ของบรรทัดระหว่างข้อความสองเวอร์ชัน บรรทัดที่เป็นส่วนหนึ่งของ subsequence นี้ถือว่าไม่เปลี่ยนแปลง ส่วนที่เหลือจะถูกทำเครื่องหมายว่าถูกลบจากเวอร์ชันเก่าหรือเพิ่มในเวอร์ชันใหม่ วิธีนี้ให้ชุดการเปลี่ยนแปลงที่น้อยที่สุด ไม่ใช่ลำดับการลบและเพิ่มแบบใดก็ได้ที่บังเอิญใช้ได้
วิธีอ่านผลลัพธ์
บรรทัดที่ถูกลบมักถูกทำเครื่องหมายด้วย - สีแดง ส่วนบรรทัดที่เพิ่มด้วย + สีเขียว บรรทัดที่ "เปลี่ยนแปลง" ในความหมายทั่วไป ในทางเทคนิคจะแสดงเป็นการลบบรรทัดเก่าบวกกับการเพิ่มบรรทัดใหม่ — diff ไม่มีแนวคิดของการแก้ไขบรรทัดในตำแหน่งเดิมโดยตรง
ทำไมการเปรียบเทียบแบบบรรทัดต่อบรรทัดไม่ได้ตรงใจเสมอไป
หากมีการแทรกบรรทัดใหม่เข้าไปกลางข้อความ การเปรียบเทียบแบบบรรทัดต่อบรรทัดอาจแสดงว่าบรรทัดถัดไปทั้งหมด "เปลี่ยนแปลง" — เพราะอัลกอริทึมไม่ได้แยกแยะได้เสมอว่านี่คือการแทรกหรือการแทนที่จำนวนมาก สำหรับข้อความภาษาไทย ปัญหานี้ซับซ้อนขึ้นอีกชั้นในระดับคำ เพราะไม่มีขอบเขตคำที่ชัดเจนให้ diff อ้างอิงตั้งแต่แรก
ทำไมต้องใช้สิ่งนี้
- ดูให้แน่ชัดว่ามีอะไรเปลี่ยนแปลงระหว่างไฟล์การตั้งค่าหรือเอกสารสองเวอร์ชัน
- รีวิวโค้ดโดยเข้าใจตรรกะของอัลกอริทึมหาความแตกต่าง
- เปรียบเทียบผลลัพธ์ของสคริปต์ก่อนและหลัง refactoring เพื่อให้แน่ใจว่าไม่มี regression
Diff ระดับบรรทัดกับระดับอักขระ
การเปรียบเทียบทีละบรรทัดเหมาะกับโค้ดและไฟล์ตั้งค่า แต่สำหรับข้อความร้อยแก้วหรือประโยคยาวที่มีเพียงคำเดียวเปลี่ยนไป มันจะทำเครื่องหมายทั้งบรรทัดว่าถูกลบและเพิ่มใหม่ สำหรับภาษาไทยโดยเฉพาะ diff ระดับอักขระมักให้ผลที่นำไปใช้ได้จริงมากกว่า diff ระดับคำ เพราะไม่ต้องพึ่งการตัดคำที่อาจผิดพลาดได้