Spec-Zone.ru › Ruby 3

класс Encoding

Родитель:
Объект

Экземпляр 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 символами.

Изменение кодировки

Связанную Encoding строки String можно изменить двумя способами.

Во-первых, можно установить Encoding строки на новую Encoding без изменения внутреннего байтового представления строки с помощью 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#encode для различных форм транскодирования и класс 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 после версии 2.0, но её можно изменить с помощью магического комментария в первой строке файла исходного кода (или во второй, если в первой есть строка shebang). Комментарий должен содержать слово coding или encoding, за которым следует двоеточие, пробел и имя или псевдоним 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 или регулярных выражений.

Кодировка локали

Кодировка по умолчанию среды. Обычно выводится из локали.

см. Encoding.locale_charmap, Encoding.find('locale')

Кодировка файловой системы

Кодировка строк из файловой системы среды по умолчанию. Используется для строк имён или путей файлов.

см. Encoding.find('filesystem')

Внешняя кодировка

Каждый объект IO имеет внешнюю кодировку, которая указывает кодировку, которую Ruby будет использовать для чтения данных. По умолчанию Ruby устанавливает внешнюю кодировку объекта IO на кодировку по умолчанию. Кодировка по умолчанию устанавливается кодировкой локали или опцией интерпретатора -E. Encoding.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>

Внешнюю кодировку по умолчанию также можно установить через Encoding.default_external=, но делать этого не следует, так как строки, созданные до и после изменения, будут иметь несогласованную кодировку. Вместо этого используйте ruby -E для вызова ruby с правильной внешней кодировкой.

Если известно, что фактическая кодировка данных объекта IO не совпадает с внешней кодировкой по умолчанию, можно сбросить её внешнюю кодировку с помощью IO#set_encoding или установить её при создании объекта IO (см. опции IO.new).

Внутренняя кодировка

Для обработки данных объекта IO, имеющего кодировку, отличную от внешней, можно установить внутреннюю кодировку. Ruby будет использовать эту внутреннюю кодировку для транскодирования данных при чтении из объекта IO.

Обратно, при записи данных в объект IO происходит транскодирование из внутренней кодировки во внешнюю кодировку объекта IO.

Внутреннюю кодировку объекта IO можно установить с помощью IO#set_encoding или при создании объекта IO (см. опции IO.new).

Внутренняя кодировка необязательна, и при её отсутствии используется внутренняя кодировка Ruby по умолчанию. Если не установлена явно, эта кодировка по умолчанию — nil, что означает, что по умолчанию транскодирование не выполняется.

Внутреннюю кодировку по умолчанию можно установить с помощью опции интерпретатора -E. Encoding.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>]

Внутреннюю кодировку по умолчанию также можно установить через Encoding.default_internal=, но делать этого не следует, так как строки, созданные до и после изменения, будут иметь несогласованную кодировку. Вместо этого используйте ruby -E для вызова ruby с правильной внутренней кодировкой.

Пример с кодировкой IO

В следующем примере строка «Ru00E9sumu00E9» с кодировкой UTF-8 транскодируется для вывода в кодировку 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", ...} Показать исходный код
static VALUE
rb_enc_aliases(VALUE klass)
{
    VALUE aliases[2];
    aliases[0] = rb_hash_new();
    aliases[1] = rb_ary_new();

    GLOBAL_ENC_TABLE_EVAL(enc_table,
                          st_foreach(enc_table->names, rb_enc_aliases_enc_i, (st_data_t)aliases));

    return aliases[0];
}

Возвращает хеш доступных псевдонимов кодировки и исходных имен кодировки.

Encoding.aliases
#=> {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1968"=>"US-ASCII",
      "SJIS"=>"Windows-31J", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
compatible?(obj1, obj2) → enc or nil Показать исходный код
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);
}

Проверяет совместимость двух объектов.

Если оба объекта являются строками, они совместимы, когда их можно конкатенировать. Кодировка конкатенированной строки будет возвращена, если они совместимы, и nil, если нет.

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-битной кодировкой

default_external → enc Показать исходный код
static VALUE
get_default_external(VALUE klass)
{
    return rb_enc_default_external();
}

Возвращает стандартную внешнюю кодировку.

Стандартная внешняя кодировка используется по умолчанию для строк, созданных из следующих источников:

  • CSV

  • File данные, считанные с диска

  • SDBM

  • StringIO

  • Zlib::GzipReader

  • Zlib::GzipWriter

  • String#inspect

  • Regexp#inspect

Хотя строки, созданные из этих источников, будут иметь эту кодировку, кодировка может быть недействительной. Убедитесь, что проверили String#valid_encoding?.

File данные, записанные на диск, будут транскодированы в стандартную внешнюю кодировку при записи, если default_internal не равно nil.

Стандартная внешняя кодировка инициализируется опцией -E. Если -E не задана, она инициализируется в UTF-8 в Windows и в локаль в других операционных системах.

default_external = enc Показать исходный код
static VALUE
set_default_external(VALUE klass, VALUE encoding)
{
    rb_warning("setting Encoding.default_external");
    rb_enc_set_default_external(encoding);
    return encoding;
}

Устанавливает стандартную внешнюю кодировку. Не нужно устанавливать Encoding::default_external в коде Ruby, так как строки, созданные до изменения значения, могут иметь другую кодировку по сравнению со строками, созданными после изменения значения. Вместо этого используйте ruby -E для вызова Ruby с правильной стандартной внешней кодировкой.

См. Encoding::default_external для получения информации о том, как используется стандартная внешняя кодировка.

default_internal → enc Показать исходный код
static VALUE
get_default_internal(VALUE klass)
{
    return rb_enc_default_internal();
}

Возвращает стандартную внутреннюю кодировку. Строки будут транскодированы в стандартную внутреннюю кодировку в следующих местах, если стандартная внутренняя кодировка не равна nil:

  • CSV

  • Etc.sysconfdir и Etc.systmpdir

  • File данные, считанные с диска

  • File имена из Dir

  • Integer#chr

  • String#inspect и Regexp#inspect

  • Строки, возвращённые из Readline

  • Строки, возвращённые из SDBM

  • Time#zone

  • Значения из ENV

  • Значения в ARGV, включая $PROGRAM_NAME

Кроме того, String#encode и String#encode! используют стандартную внутреннюю кодировку, если кодировка не указана.

Кодировка скрипта (__ENCODING__), а не default_internal, используется в качестве кодировки создаваемых строк.

Encoding::default_internal инициализируется опцией -E или nil в противном случае.

default_internal = enc or nil Показать исходный код
static VALUE
set_default_internal(VALUE klass, VALUE encoding)
{
    rb_warning("setting Encoding.default_internal");
    rb_enc_set_default_internal(encoding);
    return encoding;
}

Устанавливает стандартную внутреннюю кодировку или удаляет стандартную внутреннюю кодировку, если передано nil. Не нужно устанавливать Encoding::default_internal в коде Ruby, так как строки, созданные до изменения значения, могут иметь другую кодировку по сравнению со строками, созданными после изменения. Вместо этого используйте ruby -E для вызова Ruby с правильной стандартной внутренней кодировкой.

См. Encoding::default_internal для получения информации о том, как используется стандартная внутренняя кодировка.

find(string) → enc Показать исходный код
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);
}

Поиск кодировки по заданному имени. имя должно быть строкой.

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

Имена, которые принимает этот метод, это имена кодировок и псевдонимы, включая следующие специальные псевдонимы:

“external”

стандартная внешняя кодировка

“internal”

стандартная внутренняя кодировка

“locale”

кодировка локали

“filesystem”

кодировка файловой системы

Возникает ArgumentError, если кодировка с именем не найдена. Только Encoding.find("internal") возвращает nil, если кодировки с именем “internal” нет, другими словами, если у Ruby нет стандартной внутренней кодировки.

list → [enc1, enc2, ...] Показать исходный код
static VALUE
enc_list(VALUE klass)
{
    VALUE ary = rb_ary_new2(0);

    RB_VM_LOCK_ENTER();
    {
        rb_ary_replace(ary, rb_default_encoding_list);
        rb_ary_concat(ary, rb_additional_encoding_list);
    }
    RB_VM_LOCK_LEAVE();

    return ary;
}

Возвращает список загруженных кодировок.

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)>]
locale_charmap → string Показать исходный код
VALUE
rb_locale_charmap(VALUE klass)
{
#if NO_LOCALE_CHARMAP
    return rb_usascii_str_new_cstr("US-ASCII");
#else
    return locale_charmap(rb_usascii_str_new_cstr);
#endif
}

Возвращает имя локали charmap. Возвращает nil, если нет соответствующей информации.

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"

Результат сильно зависит от платформы. Поэтому Encoding.find(Encoding.locale_charmap) может вызвать ошибку. Если вам нужен объект кодировки даже для неизвестной локали, можно использовать Encoding.find(“locale”).

name_list → ["enc1", "enc2", ...] Показать исходный код
static VALUE
rb_enc_name_list(VALUE klass)
{
    VALUE ary;

    GLOBAL_ENC_TABLE_ENTER(enc_table);
    {
        ary = rb_ary_new2(enc_table->names->num_entries);
        st_foreach(enc_table->names, rb_enc_name_list_i, (st_data_t)ary);
    }
    GLOBAL_ENC_TABLE_LEAVE();

    return ary;
}

Возвращает список доступных имен кодировок.

Encoding.name_list
#=> ["US-ASCII", "ASCII-8BIT", "UTF-8",
      "ISO-8859-1", "Shift_JIS", "EUC-JP",
      "Windows-31J",
      "BINARY", "CP932", "eucJP"]
END_OF_DOCUMENT_MARKER

Публичные методы экземпляра

ascii_compatible? → true или false Показать исходный код
static VALUE
enc_ascii_compatible_p(VALUE enc)
{
    return rb_enc_asciicompat(must_encoding(enc)) ? Qtrue : Qfalse;
}

Возвращает значение, указывающее, является ли кодировка ASCII-совместимой.

Encoding::UTF_8.ascii_compatible?     #=> true
Encoding::UTF_16BE.ascii_compatible?  #=> false
dummy? → true или false Показать исходный код
static VALUE
enc_dummy_p(VALUE enc)
{
    return ENC_DUMMY_P(must_encoding(enc)) ? Qtrue : Qfalse;
}

Возвращает true для фиктивных кодировок. Фиктивная кодировка — это кодировка, для которой обработка символов не реализована должным образом. Она используется для состоятельных кодировок.

Encoding::ISO_2022_JP.dummy?       #=> true
Encoding::UTF_8.dummy?             #=> false
inspect → строка Показать исходный код
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)" : "");
}

Возвращает строку, представляющую кодировку для программистов.

Encoding::UTF_8.inspect       #=> "#<Encoding:UTF-8>"
Encoding::ISO_2022_JP.inspect #=> "#<Encoding:ISO-2022-JP (dummy)>"
name → строка

Возвращает имя кодировки.

Encoding::UTF_8.name      #=> "UTF-8"
Псевдоним для: to_s
names → массив Показать исходный код
static VALUE
enc_names(VALUE self)
{
    VALUE args[2];

    args[0] = (VALUE)rb_to_encoding_index(self);
    args[1] = rb_ary_new2(0);

    GLOBAL_ENC_TABLE_EVAL(enc_table,
                          st_foreach(enc_table->names, enc_names_i, (st_data_t)args));

    return args[1];
}

Возвращает список имен и псевдонимов кодировки.

Encoding::WINDOWS_31J.names  #=> ["Windows-31J", "CP932", "csWindows31J", "SJIS", "PCK"]
replicate(name) → кодировка Показать исходный код
static VALUE
enc_replicate_m(VALUE encoding, VALUE name)
{
    int idx = rb_enc_replicate(name_for_encoding(&name), rb_to_encoding(encoding));
    RB_GC_GUARD(name);
    return rb_enc_from_encoding_index(idx);
}

Возвращает дублированную кодировку enc с именем name. Новая кодировка должна иметь ту же структуру байтов, что и enc. Если name используется другой кодировкой, вызовите ArgumentError.

to_s → строка Показать исходный код
static VALUE
enc_name(VALUE self)
{
    return rb_fstring_cstr(rb_enc_name((rb_encoding*)DATA_PTR(self)));
}

Возвращает имя кодировки.

Encoding::UTF_8.name      #=> "UTF-8"
Также псевдоним для: name

Ruby Core © 1993–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API