หากไม่มีuse utf8
Perl แปลว่าสตริงของคุณเป็นลำดับของอักขระไบต์เดียว สตริงของคุณมีสี่ไบต์ดังที่คุณเห็นจากสิ่งนี้:
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
สามไบต์แรกประกอบเป็นตัวละครของคุณอันสุดท้ายคือ line-feed
การเรียกให้print
ส่งอักขระทั้งสี่นี้ไปยัง STDOUT จากนั้นคอนโซลของคุณจะหาวิธีแสดงอักขระเหล่านี้ หากคอนโซลของคุณถูกตั้งค่าให้ใช้ UTF8 ก็จะแปลว่าทั้งสามไบต์นั้นเป็นอักขระเดี่ยวของคุณและนั่นคือสิ่งที่แสดง
หากเราเพิ่มในutf8
โมดูลสิ่งต่างๆก็แตกต่างกันไป ในกรณีนี้ Perl ตีความสตริงของคุณเป็นเพียงสองอักขระ
$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10
โดยค่าเริ่มต้นเลเยอร์ IO ของ Perl จะถือว่าทำงานกับอักขระไบต์เดี่ยว ดังนั้นเมื่อคุณพยายามพิมพ์อักขระแบบหลายไบต์ Perl จะคิดว่ามีบางอย่างผิดปกติและแจ้งเตือนคุณ use diagnostics
เช่นเคยคุณจะได้รับคำอธิบายเพิ่มเติมสำหรับข้อผิดพลาดนี้ได้โดยรวม มันจะบอกว่า:
(S utf8) Perl พบอักขระแบบกว้าง (> 255) เมื่อไม่ได้คาดหวัง คำเตือนนี้เป็นค่าเริ่มต้นสำหรับ I / O (เช่นการพิมพ์) วิธีที่ง่ายที่สุดในการปิดคำเตือนนี้คือการเพิ่มเลเยอร์: utf8 ในเอาต์พุตเช่น binmode STDOUT, ': utf8' อีกวิธีหนึ่งในการปิดคำเตือนคือการไม่เพิ่มคำเตือน 'utf8'; แต่นั่นมักจะใกล้เคียงกับการโกงมากกว่า โดยทั่วไปคุณควรทำเครื่องหมายที่ filehandle ด้วยการเข้ารหัสอย่างชัดเจนโปรดดู open และ perlfunc / binmode
ตามที่คนอื่น ๆ ชี้ให้เห็นว่าคุณต้องบอกให้ Perl ยอมรับเอาต์พุตแบบหลายไบต์ มีหลายวิธีในการดำเนินการนี้ (ดูบทช่วยสอน Perl Unicodeสำหรับตัวอย่างบางส่วน) วิธีที่ง่ายที่สุดวิธีหนึ่งคือการใช้-CS
แฟล็กบรรทัดคำสั่งซึ่งจะบอกว่า filehandles มาตรฐานสามแบบ (STDIN, STDOUT และ STDERR) เพื่อจัดการกับ UTF8
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
เทียบกับ
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Unicode เป็นพื้นที่ขนาดใหญ่และซับซ้อน อย่างที่คุณเห็นโปรแกรมง่ายๆหลายโปรแกรมดูเหมือนจะทำสิ่งที่ถูกต้อง แต่ด้วยเหตุผลที่ไม่ถูกต้อง เมื่อคุณเริ่มที่จะแก้ไขส่วนหนึ่งของโปรแกรมสิ่งที่มักจะได้รับที่เลวร้ายยิ่งจนกว่าคุณจะได้รับการแก้ไขทั้งหมดของโปรแกรม