Подтвердить что ты не робот

В чем разница между #encode и #force_encoding в ruby?

Я действительно не понимаю разницы между #encode и #force_encoding в Ruby для класса String. Я понимаю, что "kam".force_encoding("UTF-8") заставит "kam" быть в кодировке UTF-8, но как #encode(encoding) отличается?

http://ruby-doc.org/core-2.0/String.html#method-i-encoding

4b9b3361

Ответ 1

Разница довольно большая. force_encoding устанавливает заданное строковое кодирование, но не меняет сама строка, т.е. не изменяет ее представление в памяти:

'łał'.bytes #=> [197, 130, 97, 197, 130]
'łał'.force_encoding('ASCII').bytes #=> [197, 130, 97, 197, 130]
'łał'.force_encoding('ASCII')   #=> "\xC5\x82a\xC5\x82"

Кодирование предполагает, что текущая кодировка верна и пытается изменить строку, чтобы она читала то же самое во второй кодировке:

'łał'.encode('UTF-16') #=> 'łał'
'łał'.encode('UTF-16').bytes #=> [254, 255, 1, 65, 0, 97, 1, 66] 

Короче говоря, force_encoding изменяет способ чтения строки из байтов, а encode изменяет способ записи строки без изменения вывода (если возможно)

Ответ 2

Прочитайте это Изменение кодировки

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

Во-первых, можно установить 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>