非常教程

Ruby 2.4参考手册

编码 | Encoding

Encoding

Parent:Object

一个Encoding实例表示一个可在Ruby中使用的字符编码。它在Encoding命名空间下定义为常量。它有一个名称和可选的别名:

Encoding::ISO_8859_1.name
#=> "ISO-8859-1"

Encoding::ISO_8859_1.names
#=> ["ISO-8859-1", "ISO8859-1"]

处理编码的Ruby方法返回或接受Encoding实例作为参数(当一个方法接受Encoding实例作为参数时,它可以传递一个Encoding名称或别名)。

"some string".encoding
#=> #<Encoding:UTF-8>

string = "some string".encode(Encoding::ISO_8859_1)
#=> "some string"
string.encoding
#=> #<Encoding:ISO-8859-1>

"some string".encode "ISO-8859-1"
#=> "some string"

Encoding::ASCII_8BIT是一种特殊的编码,通常用于字节字符串,而不是字符串。但正如名字所认定的,它在ASCII范围内的字符被认为是ASCII字符。当您将ASCII-8BIT字符与其他ASCII兼容字符一起使用时,这非常有用。

更改编码

关联的字符串编码可以通过两种不同的方式进行更改。

首先,可以使用String#force_encoding将字符串的编码设置为新的编码,而不更改字符串的内部字节表示形式。这是你如何告诉Ruby一个字符串的正确编码的方式。

string
#=> "R\xC3\xA9sum\xC3\xA9"
string.encoding
#=> #<Encoding:ISO-8859-1>
string.force_encoding(Encoding::UTF_8)
#=> "R\u00E9sum\u00E9"

其次,可以对字符串进行转码,即将其内部字节表示转换为另一种编码。其相关的编码也被设置为其他编码。请参阅String#编码各种形式的代码转换,以及Encoding :: Converter类,以进一步控制代码转换过程。

string
#=> "R\u00E9sum\u00E9"
string.encoding
#=> #<Encoding:UTF-8>
string = string.encode!(Encoding::ISO_8859_1)
#=> "R\xE9sum\xE9"
string.encoding
#=> #<Encoding::ISO-8859-1>

脚本编码

所有的Ruby脚本代码都有一个关联的Encoding,其中源代码中创建的任何字符串文字都将与之关联。

默认的脚本编码是Encoding::UTF-8在v2.0之后,但它可以通过对源代码文件的第一行(或第二行,如果第一行有一个shebang行)的魔术注释进行更改。注释必须包含单词codingor encoding,后跟冒号空格以及编码名称或别名:

# encoding: UTF-8

"some string".encoding
#=> #<Encoding:UTF-8>

__ENCODING__关键字返回该关键词被写入文件的脚本编码方式:

# encoding: ISO-8859-1

__ENCODING__
#=> #<Encoding:ISO-8859-1>

ruby -K将更改默认的区域设置编码,但不建议这样做。即使Ruby源文件仅依赖于US-ASCII字符串或正则表达式,Ruby源文件也应该通过效力注释来声明它的脚本编码。

区域设置编码

环境的默认编码;通常从locale派生。

请参阅:: locale_charmap,:: find('locale')

文件系统编码

环境文件系统中字符串的默认编码。这用于文件名或路径的字符串。

请参阅:: find('filesystem')

外部编码

每个IO对象都有一个外部编码,用于指示Ruby将用于读取其数据的编码。默认情况下,Ruby将IO对象的外部编码设置为默认的外部编码。默认的外部编码由区域设置编码或解释器-E选项设置。:: default_external返回外部编码的当前值。

ENV["LANG"]
#=> "UTF-8"
Encoding.default_external
#=> #<Encoding:UTF-8>

$ ruby -E ISO-8859-1 -e "p Encoding.default_external"
#<Encoding:ISO-8859-1>

$ LANG=C ruby -e 'p Encoding.default_external'
#<Encoding:US-ASCII>

默认的外部编码也可以通过:: default_external =来设置,但是你不应该这样做,因为在改变之前和之后创建的字符串将会有不一致的编码。而是使用ruby -E正确的外部编码调用ruby。

当您知道IO对象的数据的实际编码不是默认的外部编码时,可以使用IO#set_encoding重置其外部编码,或者将其设置为创建IO对象(请参阅IO.new选项)。

内部编码

要处理编码与外部编码不同的IO对象的数据,可以设置其内部编码。当从IO对象读取数据时,Ruby将使用此内部编码对数据进行转码。

相反,当数据写入IO对象时,它将从内部编码转换为IO对象的外部编码。

IO对象的内部编码可以使用IO#set_encoding或IO对象创建来设置(请参阅IO.new选项)。

内部编码是可选的,未设置时,使用Ruby默认的内部编码。如果未明确设置,则默认的内部编码nil意味着默认情况下不会发生转码。

默认的内部编码可以通过解释器选项来设置-E。:: default_internal返回当前的内部编码。

$ ruby -e 'p Encoding.default_internal'
nil

$ ruby -E ISO-8859-1:UTF-8 -e "p [Encoding.default_external, \
  Encoding.default_internal]"
[#<Encoding:ISO-8859-1>, #<Encoding:UTF-8>]

默认的内部编码也可以通过:: default_internal =来设置,但不应该这样做,因为在更改之前和之后创建的字符串将具有不一致的编码。而是使用ruby -E正确的内部编码调用ruby。

IO编码示例

在下面的例子中,一个UTF-8编码的字符串“Ru00E9sumu00E9”被转码输出为ISO-8859-1编码,然后回读并转码为UTF-8:

string = "R\u00E9sum\u00E9"

open("transcoded.txt", "w:ISO-8859-1") do |io|
  io.write(string)
end

puts "raw text:"
p File.binread("transcoded.txt")
puts

open("transcoded.txt", "r:ISO-8859-1:UTF-8") do |io|
  puts "transcoded text:"
  p io.read
end

在写入文件时,不指定内部编码,因为它仅用于读取。在读取文件时,必须指定内部和外部编码以获得正确的结果。

$ ruby t.rb
raw text:
"R\xE9sum\xE9"

transcoded text:
"R\u00E9sum\u00E9"

公共类方法

aliases -> {"alias1" => "orig1", "alias2" → "orig2", ...} Show source

返回可用编码别名和原始编码名称的散列。

Encoding.aliases
#=> {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1986"=>"US-ASCII",
      "SJIS"=>"Shift_JIS", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
static VALUE
rb_enc_aliases(VALUE klass)
{
    VALUE aliases[2];
    aliases[0] = rb_hash_new();
    aliases[1] = rb_ary_new();
    st_foreach(enc_table.names, rb_enc_aliases_enc_i, (st_data_t)aliases);
    return aliases[0];
}

compatible?(obj1, obj2) → enc or nil Show source

检查两个对象的兼容性。

如果这些对象都是字符串,则它们在可串连时是兼容的。连接字符串的编码在兼容时会返回,如果不相同则返回零。

Encoding.compatible?("\xa1".force_encoding("iso-8859-1"), "b")
#=> #<Encoding:ISO-8859-1>

Encoding.compatible?(
  "\xa1".force_encoding("iso-8859-1"),
  "\xa1\xa1".force_encoding("euc-jp"))
#=> nil

如果对象是非字符串,则它们的编码在具有编码时是兼容的,并且:

  • 两种编码都是US-ASCII兼容的
  • 其中一种编码是7位编码
static VALUE
enc_compatible_p(VALUE klass, VALUE str1, VALUE str2)
{
    rb_encoding *enc;

    if (!enc_capable(str1)) return Qnil;
    if (!enc_capable(str2)) return Qnil;
    enc = rb_enc_compatible(str1, str2);
    if (!enc) return Qnil;
    return rb_enc_from_encoding(enc);
}

default_external → enc Show source

返回默认的外部编码。

对于从以下位置创建的字符串,默认使用默认的外部编码:

  • CSV
  • File data read from disk
  • SDBM
  • StringIO
  • Zlib::GzipReader
  • Zlib::GzipWriter
  • String#inspect
  • Regexp#inspect

从这些位置创建的字符串将具有此编码,但编码可能无效。一定要检查String#valid_encoding ?.

写入磁盘的文件数据在写入时将被转码为默认的外部编码。

默认的外部编码由区域设置或-E选项初始化。

static VALUE
get_default_external(VALUE klass)
{
    return rb_enc_default_external();
}

default_external = enc Show source

设置默认的外部编码。您不应该在ruby代码中将:: default_external设置为在创建值之前创建的字符串,而是在值更改后创建的字符串可能具有不同的编码,而应该使用ruby -E正确的default_external调用ruby。

有关如何使用默认外部编码的信息,请参阅:: default_external。

static VALUE
set_default_external(VALUE klass, VALUE encoding)
{
    rb_warning("setting Encoding.default_external");
    rb_enc_set_default_external(encoding);
    return encoding;
}

default_internal → enc Show source

返回默认的内部编码。如果默认内部编码不为零,则字符串将在下列位置转码为默认内部编码:

  • CSV
  • Etc.sysconfdir and Etc.systmpdir
  • File data read from disk
  • File names from Dir
  • Integer#chr
  • String#inspect and Regexp#inspect
  • Strings returned from Readline
  • Strings returned from SDBM
  • Time#zone
  • Values from ENV
  • Values in ARGV including $PROGRAM_NAME

另外对于String#编码和String#编码!,如果没有给出编码,则使用默认的内部编码。

语言环境编码(__ENCODING__),而不是:: default_internal,用作创建字符串的编码。

:: default_internal由源文件的internal_encoding或-E选项初始化。

static VALUE
get_default_internal(VALUE klass)
{
    return rb_enc_default_internal();
}

default_internal = enc or nil Show source

设置默认内部编码或在通过nil时删除默认内部编码。 您不应该在ruby代码中将:: default_internal设置为在创建之前创建的字符串,而在更改值之后可能会使用与更改后创建的字符串不同的编码。 相反,您应该使用ruby -E以正确的default_internal调用ruby。

有关如何使用默认内部编码的信息,请参阅:: default_internal。

static VALUE
set_default_internal(VALUE klass, VALUE encoding)
{
    rb_warning("setting Encoding.default_internal");
    rb_enc_set_default_internal(encoding);
    return encoding;
}

find(string) → enc Show source

使用指定名称 搜索编码。名称 应该是一个字符串。

Encoding.find("US-ASCII")  #=> #<Encoding:US-ASCII>

此方法接受的名称是编码名称和别名,包括以下特殊别名

“external”

默认的外部编码

“internal”

默认的内部编码

“locale”

区域设置编码

“filesystem”

文件系统编码

没有使用名称进行 编码时会引发ArgumentError 。Encoding.find("internal")但是,只有当没有编码命名为“internal”时返回nil,换句话说,即当Ruby没有默认的内部编码时。

static VALUE
enc_find(VALUE klass, VALUE enc)
{
    int idx;
    if (is_obj_encoding(enc))
        return enc;
    idx = str_to_encindex(enc);
    if (idx == UNSPECIFIED_ENCODING) return Qnil;
    return rb_enc_from_encoding_index(idx);
}

list → enc1, enc2, ...()

返回加载的编码列表。

Encoding.list
#=> [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
      #<Encoding:ISO-2022-JP (dummy)>]

Encoding.find("US-ASCII")
#=> #<Encoding:US-ASCII>

Encoding.list
#=> [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
      #<Encoding:US-ASCII>, #<Encoding:ISO-2022-JP (dummy)>]
static VALUE
enc_list(VALUE klass)
{
    VALUE ary = rb_ary_new2(0);
    rb_ary_replace(ary, rb_encoding_list);
    return ary;
}

locale_charmap → string Show source

返回语言环境charmap名称。如果没有适当的信息,它将返回零。

Debian GNU/Linux
  LANG=C
    Encoding.locale_charmap  #=> "ANSI_X3.4-1968"
  LANG=ja_JP.EUC-JP
    Encoding.locale_charmap  #=> "EUC-JP"

SunOS 5
  LANG=C
    Encoding.locale_charmap  #=> "646"
  LANG=ja
    Encoding.locale_charmap  #=> "eucJP"

结果是高度依赖平台,所以 :: find可能会导致错误。如果您甚至需要一些编码对象,即使是未知的语言环境,也可以使用:: find(“locale”)。

VALUE
rb_locale_charmap(VALUE klass)
{
    return locale_charmap(rb_usascii_str_new_cstr);
}

name_list → "enc1", "enc2", ...()

返回可用编码名称的列表。

Encoding.name_list
#=> ["US-ASCII", "ASCII-8BIT", "UTF-8",
      "ISO-8859-1", "Shift_JIS", "EUC-JP",
      "Windows-31J",
      "BINARY", "CP932", "eucJP"]
static VALUE
rb_enc_name_list(VALUE klass)
{
    VALUE ary = rb_ary_new2(enc_table.names->num_entries);
    st_foreach(enc_table.names, rb_enc_name_list_i, (st_data_t)ary);
    return ary;
}

公共实例方法

ascii_compatible? → true or false Show source

返回是否与ASCII兼容(的结果)。

Encoding::UTF_8.ascii_compatible?     #=> true
Encoding::UTF_16BE.ascii_compatible?  #=> false
static VALUE
enc_ascii_compatible_p(VALUE enc)
{
    return rb_enc_asciicompat(must_encoding(enc)) ? Qtrue : Qfalse;
}

dummy? → true or false Show source

对虚拟编码返回true。虚拟编码是字符处理未正确实施的编码,它用于有状态编码。

Encoding::ISO_2022_JP.dummy?       #=> true
Encoding::UTF_8.dummy?             #=> false
static VALUE
enc_dummy_p(VALUE enc)
{
    return ENC_DUMMY_P(must_encoding(enc)) ? Qtrue : Qfalse;
}

inspect → string Show source

返回一个表示程序员编码的字符串。

Encoding::UTF_8.inspect       #=> "#<Encoding:UTF-8>"
Encoding::ISO_2022_JP.inspect #=> "#<Encoding:ISO-2022-JP (dummy)>"
static VALUE
enc_inspect(VALUE self)
{
    rb_encoding *enc;

    if (!is_data_encoding(self)) {
        not_encoding(self);
    }
    if (!(enc = DATA_PTR(self)) || rb_enc_from_index(rb_enc_to_index(enc)) != enc) {
        rb_raise(rb_eTypeError, "broken Encoding");
    }
    return rb_enc_sprintf(rb_usascii_encoding(),
                          "#<%"PRIsVALUE":%s%s%s>", rb_obj_class(self),
                          rb_enc_name(enc),
                          (ENC_DUMMY_P(enc) ? " (dummy)" : ""),
                          enc_autoload_p(enc) ? " (autoload)" : "");
}

name → string Show source

返回编码的名称。

Encoding::UTF_8.name      #=> "UTF-8"
static VALUE
enc_name(VALUE self)
{
    return rb_fstring_cstr(rb_enc_name((rb_encoding*)DATA_PTR(self)));
}

names → array Show source

返回编码的名称和别名列表。

Encoding::WINDOWS_31J.names  #=> ["Windows-31J", "CP932", "csWindows31J"]
static VALUE
enc_names(VALUE self)
{
    VALUE args[2];

    args[0] = (VALUE)rb_to_encoding_index(self);
    args[1] = rb_ary_new2(0);
    st_foreach(enc_table.names, enc_names_i, (st_data_t)args);
    return args[1];
}

replicate(name) → encoding Show source

返回名称为name enc 复制编码。新编码应该具有相同的enc的字节结构。如果名称被另一种编码使用,请引发ArgumentError。

static VALUE
enc_replicate(VALUE encoding, VALUE name)
{
    return rb_enc_from_encoding_index(
        rb_enc_replicate(StringValueCStr(name),
                         rb_to_encoding(encoding)));
}

to_s → string Show source

返回编码的名称。

Encoding::UTF_8.name      #=> "UTF-8"
static VALUE
enc_name(VALUE self)
{
    return rb_fstring_cstr(rb_enc_name((rb_encoding*)DATA_PTR(self)));
}
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct