ถ้าต้องการจะจัดการกับ string หรือที่เป็นชนิด utf-8 หรือที่เป็นอักขระที่ไม่ได้อยู่บน keyboard จะทำยังไง มาดูกัน
เราสามารถจัดการกับอักขระได้ โดย ruby จะมีตัวเลขที่ผ่านการ escape มาแล้วเป็นตัวอ้าง โดยที่เราสามารถใช้ได้ใน double quote จะเพิ่มอะไรไปก็ได้ สามารถอ้างถึงอักขระตัวใดก็ได้โดยการ encode ให้เป็นเลขฐาน 8 ในรูปแบบนี้ "\000" หรือฐาน 16 ในรูปแบบนี้ "\x00"
1
2
3
4
5
6
7
8
9
10
11
12
13
| octal = "\000\001\010\020"
octal.each_byte { |x| puts x }
hexadecimal = "\x00\x01\x10\x20"
hexadecimal.each_byte { |x| puts x }
|
ด้วยกลไกแบบนี้ เลยสามารถทำให้ ruby แสดงอักขระ utf-8 ที่เราไม่สามารถพิมพ์มันออกมาได้ ลองรัน code นี้ดู มันจะทำการสร้าง file ที่ชื่อว่า smiley.html มาให้ดู
1
2
3
4
| open('smiley.html', 'wb') do |f|
f << '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">'
f << "\xe2\x98\xBA"
end
|
ตัวยิ้มนี้ มันมีอยู่ตรงไหนบนแป้นพิมพ์ ???
อักขระจำพวกนี้ จะมี back slash นำหน้า เช่น
1
2
3
4
5
6
7
8
| "\a" == "\x07"
"\b" == "\x08"
"\e" == "\x1b"
"\f" == "\x0c"
"\n" == "\x0a"
"\r" == "\x0d"
"\t" == "\x09"
"\v" == "\x0b"
|
ตัว ruby มันเก็บ string เป้นลำดับของ byte ดังนั้น การที่มันจะเอา byte ต่างๆ ที่สามารถเอาออกมาให้ดูได้ เช่น ASCII, binary หรือปนๆ กัน มันก็ย่อมจะทำได้โดยไม่มีปัญหา
ตอนที่ ruby ได้แสดงอักขระต่างๆ ที่เราได้เห็น มันจะใช้อักขระ \xxx (ฐาน 8 ) เป็นตัวแทนของอักขระนั้นๆ ถ้าอักขระจำพวกข้างบนที่เพิ่งแสดงให้ดูไป มันก็จะออกมาให้ดูด้วย แต่ถ้าหากว่ามันไม่มีตัวแทนของอักขระนั้นๆ อยู่ มันก็จะแสดงออกมาในรูปฐาน 10 เช่น
1
2
| "\x10\x11\xfe\xff"
"\x48\145\x6c\x6c\157\x0a"
|
เจอ backslash แล้วก็งง ถ้าเราจะแสดงตัว backslash จะใช้ backslash นำหน้าอีกทีนึง เช่น
1
2
3
4
5
| "\\".size
"\\" == "\x5c"
"\\n"[0] == ?\\
"\\n"[1] == ?n
"\\n" =~ /\n/
|
แม้กระทั้ง shortcuts ต่างๆ ของ keyboard ก็แสดงได้ โดยจะอยู่ในรูป \C-x สำหรับการกด Ctrl+x หรือ \M-x สำหรับการกด Alt+x
1
2
| "\C-a\C-b\C-c"
"\M-a\M-b\M-c"
|
ถ้าเราใช้ ? นำหน้าอักขระต่างๆ เราจะได้ตัวเลขมาค่านึง(ขอเรียกว่า shorthand) ซึ่งสามารถใช้ได้กับ regular expression อีกด้วย
1
2
3
4
5
6
7
8
| ?\C-a
?\M-z
contains_control_chars = /[\C-a-\C-^]/
'Foobar' =~ contains_control_chars
"Foo\C-zbar" =~ contains_control_chars
contains_upper_chars = /[\x80-\xff]/
'Foobar' =~ contains_upper_chars
"Foo\212bar" =~ contains_upper_chars
|
ลองดููตัวอย่าง
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| def snoop_on_keylog(input)
input.each_byte do |b|
case b
when ?\C-c; puts 'Control-C: stopped a process?'
when ?\C-z; puts 'Control-Z: suspended a process?'
when ?\n; puts 'Newline.'
when ?\M-x; puts 'Meta-x: using Emacs?'
end
end
end
snoop_on_keylog("ls -ltR\003emacsHello\012\370rot13-other-window\012\032")
|
พอได้รับ input มาแล้ว ก็ไล่ตรวจทีละ byte พอเข้า case ไหน ก็แสดงใน case นั้น
ตัวอักขระพิเศษพวกนี้ จะสามารถแสดงได้ใน double quote เท่านั้น ซึ่งเคยย้ำไปแล้วในเรื่องเล่าอันก่อนๆ มาย้ำอีกที(ย้ำตัวเองด้วย) สำหรับ double quote นอกจากตัวฟันหนูสองซี่แล้ว ยังสามารถใช้ %{} หรือ %Q{} ได้อีกด้วย แต่สำหรับ single quote หรือฟันหนูซี่เดียว สามารถใช้ %q{} แทน ส่วน here document นั้น จะให้ผลเป็น double quote ครับ
แก้ไขล่าสุด วันที่ 3 สิงหาคม 2550 เวลา 3.09 น.