With the advent of Ruby 1.9, Ruby now supports encodings other than US-ASCII for strings, IO, and source code. On an installation of Ruby 1.9.3 MRI on Mac OSX Lion, Ruby has the following encodings:
By default, all Ruby source files are encoded with US-ASCII. The usual way of changing the encoding of a file is to use a so called "magic comment". The magic comment must come directly at the beginning of the file, or directly after a shebang comment. The syntax of the magic comment requires only one thing: The comment contains the text
coding: followed by the name of the encoding. So the following are all valid magic comments:
#encoding: UTF-8 #coding: UTF-8 #blah blah coding: US-ASCII
The magic comment tells the interpreter that the source code itself, in addition to all of the strings in it, are going to be encoded with the given encoding. So, while this is valid code:
#encoding: ISO-8859-1 puts "Olé!"
This is not:
#encoding: US-ASCII puts "Olé!"
Because the first snippet declares the files encoding to be ISO-8859-1 (an extension to US-ASCII that adds accented characters for languages such as French and Spanish), the character "é" is valid. However, in US-ASCII, "é" is an invalid character, and will cause an error.
Encodings and Individual Strings
You can also specify encodings for individual strings in your file (although the characters in literals must still be in the encoding declared by the magic comment, or inserted through escape sequences). This is done by two methods of the String class:
encode is used for transcoding. Given, say, the ISO-8859-1 string "Olé!", you could use
encode to convert that to UTF-8, which has all of the same characters. However, you can not transcode the ISO-8859-1 string to US-ASCII, unless it contains only ASCII characters (eg. "Hello").
encode has many options and can be configured extensively. See its documentation. Here's the catch of
encode: It is very likely that while the visual display and meaning of the characters remain the same, the underlying bytes most likely will not.
encode is free to change the underlying bytes of a string. Example:
#encoding: ISO-8859-1 "Olé!".encode("UTF-8") #Valid "Olé!".encode("US-ASCII") #Error
force_encoding is used to tell Ruby the encoding of a string that already has the correct bytes for that encoding (eg. a UTF-8 string read from a file in an ISO-8859-1 program).
force_encoding will never modify the underlying bytes of a string. Example:
#encoding: ISO-8859-1 "\u27d0".force_encoding("UTF-8")
Ruby also includes a fake encoding: ASCII-8 Bit, or BINARY. BINARY is the encoding used for binary data.