2015-11-14 21 views
6

Recentemente ho iniziato a lavorare con la codifica in Ruby, e sono confuso da qualche comportamento.Codifica stringa in Ruby

sto usando 2.2.3p173 e sto mostrando il seguente:

__ENCODING__    #=> #<Encoding:UTF-8> Default encoding in 2.2.3 

"my_string".encoding  #=> #<Encoding:UTF-8> 
Object.to_s.encoding  #=> #<Encoding:US-ASCII> 
Object.new.to_s.encoding #=> #<Encoding:ASCII-8BIT> 

Qual è la causa di questa discrepanza nei codifiche?

risposta

4

Bella scoperta!

La risposta breve è che è completamente arbitraria e dipende da come Ruby crea internamente le stringhe che vengono restituite.

C'è un intero host di funzioni interne C che costruiscono stringhe vuote o stringhe letterali con codifica US-ASCII: rb_usascii_str_new e simili. Sono spesso usati per costruire stringhe aggiungendo piccoli frammenti di stringhe. Quasi ogni metodo to_s fa questo:

[].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> 

Allora perché non Object.new.to_s? La chiave qui è che Object#to_s è il metodo fallback to_s per ogni classe, quindi per renderlo generico-ancora informativo è stato codificato per generare il valore del puntatore interno dell'oggetto. Il modo più semplice per farlo è con sprintf e con lo specificatore %p. MA chi ha codificato l'involucro sprintf di Ruby rb_sprintf è diventato pigro e ha impostato la codifica su NULL che torna a ASCII-8BIT. Quindi, in generale tutto ciò che restituisce una stringa formattata avrà questa codifica:

Object.new.to_s 
#<Encoding:ASCII-8BIT> 
nil.sort rescue $!.to_s.encoding 
#<Encoding:ASCII-8BIT> 
[].each.to_s.encoding 
#<Encoding:ASCII-8BIT> 

Per quanto riguarda le stringhe definite da uno script, quelli ottenere la codifica predefinita UTF-8 come ci si aspetterebbe.

1

Object è definito in C se si tenta il seguente:

String(123456).encoding #=> #<Encoding:ASCII-8BIT> 
"123456".encoding  #=> #<Encoding:UTF-8> 

non ho scavare molto in codice sorgente ruby ​​ma looks piace è harcoded la codifica (rb_usascii_str_new2) per to_s

Problemi correlati