Хорошая находка!
Короткий ответ - это полностью произвольно, и это зависит от того, как Ruby внутренне создает строки, которые возвращаются.
Существует целый ряд внутренних функций C, которые строят пустые строки или литералы с кодировкой US-ASCII: rb_usascii_str_new
и тому подобное. Они часто используются для построения строк путем добавления небольших фрагментов строк. Почти каждый to_s
метод делает это:
[].to_s.encoding
#<Encoding:US-ASCII>
{}.to_s.encoding
#<Encoding:US-ASCII>
$/.to_s.encoding
#<Encoding:US-ASCII>
1.to_s.encoding
#<Encoding:US-ASCII>
true.to_s.encoding
#<Encoding:US-ASCII>
Object.to_s.encoding
#<Encoding:US-ASCII>
Так почему бы не Object.new.to_s
? Ключ здесь состоит в том, что Object#to_s
- это метод возврата to_s
для каждого класса, поэтому, чтобы сделать его общим, но все же информативным, он закодировал его для вывода значения внутреннего указателя объекта. Самый простой способ сделать это - sprintf
и спецификатор %p
. BUT кто-то закодированный Ruby's sprintf
обертка rb_sprintf
получил ленивый и просто установил кодировку в NULL
, которая возвращается к ASCII-8BIT
. Так что в целом все, что возвращает отформатированную строку будет иметь эту кодировку:
Object.new.to_s
#<Encoding:ASCII-8BIT>
nil.sort rescue $!.to_s.encoding
#<Encoding:ASCII-8BIT>
[].each.to_s.encoding
#<Encoding:ASCII-8BIT>
Что касается строк, определенных с помощью сценария, те получают кодировку UTF-8 по умолчанию, как можно было бы ожидать.