Làm sao chuỗi ký tự tồn tại trong thế giới máy tính chỉ hiểu 0 & 1? Vâng... Giống như map domain name đến IP. Hoặc barcode đến sản phẩm. Chúng ta có thể... Map số đến ký tự! Như 97 đến "a". Hoặc 122 đến "z". Đó chính là cách có ký tự trong thế giới số. Nhưng số nào đi với ký tự nào? Để trả lời, chúng ta phát minh các hệ mapping ký tự khác nhau. Bắt đầu với ASCII. ASCII = "American Standard Code for Information Interchange". Tìm ASCII table, hoặc nhờ Ruby convert ký tự sang giá trị ASCII. Như: "a".ord # 97. Nhiều ký tự: "abc".bytes # [97, 98, 99]. Có integer thì lấy ký tự liên kết. Như: 97.chr # "a". ASCII encoding bao gồm: Control char (newline, tab, null), Symbol (parentheses, =, ?), Số (0-9), Chữ (a-z, A-Z). Như sau sẽ thấy, phạm vi này hạn chế. Tại sao? Vì không bao gồm ký tự & symbol ngôn ngữ khác, như Tiếng Trung hoặc Nhật.
ASCII Trong Thực Tế
Mapping số-string xảy ra behind the scenes. Nhưng có ứng dụng thực tế! Ví dụ: HTTP spec không cho phép ký tự nhất định trong URL. Nhưng encode ký tự invalid dạng ASCII & modern web server interpret đúng.
example.com/a+++ => example.com/a%2B%2B%2B
%2B là gì? Ký tự +, dạng ASCII-encoded. Cũng dùng knowledge này transform ký tự. Ví dụ: Xem ASCII table, convert lowercase thành uppercase bằng trừ 32. ("a".ord - 32).chr # "A" Cũng ngược lại. ("A".ord + 32).chr # "a" Có. Ruby có upcase & downcase. Nhưng có thể giúp interview question, coding challenge.
Unicode Là Gì?
ASCII chỉ encode 127 ký tự (256 extended ASCII), giới hạn ký tự biểu diễn. Giải pháp? Unicode. Unicode là hệ encoding chuỗi biểu diễn tới triệu ký tự. Không gian lớn hơn ASCII nhiều! Bây giờ bao gồm ký tự mọi ngôn ngữ, symbol mới & emoji. Unicode: ɑΩϕβΣπ (chữ Hy Lạp, không hiển thị được ASCII).
Cách Dùng Unicode Trong Ruby
Ruby hỗ trợ Unicode, enabled mặc định từ Ruby 1.9. Làm được: π = 3.141592. Hoặc:
def ★★★ puts "You get 3 stars, great job!" end ★★★ # "You get 3 stars, great job!"Vui! Nhưng không practical định nghĩa method/biến dùng symbol vì không trên bàn phím. Thực tế, có ký tự Unicode invisible hợp lệ. Ví dụ:
def puts "Invisible method" end Trông như method không tên, bình thường không cho phép. Nhưng chạy vì invisible Unicode char!
Phương Thức String Encoding
Ruby có method làm việc encoding khác nhau. Ví dụ: "abc".encoding.name # "UTF-8". Có vài trường hợp đặc biệt encoding hiện tại (encoding.name) không khớp encoding thực tế của string. Gặp khi đọc data từ web, file, DB hoặc nguồn ngoài. Dẫn đến InvalidByteSequenceError. Nếu xảy ra cần đổi encoding. Cách? Dùng encode:
"abcΣΣΣ".encode("ASCII", "UTF-8", undef: :replace) # "abc???" Convert từ UTF-8 (Unicode) sang ASCII, ký tự Σ không có ASCII, bảo Ruby replace. Mặc định replace undefined char bằng dấu hỏi. Nhưng đổi được. Như: "abcΣΣΣ".encode("ASCII", "UTF-8", invalid: :replace, undef: :replace, replace: "") # "abc". Hoặc dùng "fallback": "abcΣΣΣ".encode("ASCII", "UTF-8", fallback: {"Σ" => "E"}) # "abcEEE". Nghĩa: "Replace tất cả char từ UTF-8 sang ASCII, dùng fallback hash dịch char không tồn tại ASCII". Method khác, force_encoding, đổi encoding không bước dịch. Ví dụ: "abc½½½".force_encoding("iso-8859-1"). Lấy list encoding available với Encoding.aliases.
Tóm Tắt
Bạn đã học máy tính tạo ký tự từ số dùng encoding table! Cũng học ASCII & Unicode trong Ruby. Mở editor & vui vẻ practice 😃 Cảm ơn bạn đã đọc.