¿Qué es lo contrario de chr () en Ruby?
Pregunta
En muchos idiomas hay un par de funciones, chr ()
y ord ()
, que convierten entre números y valores de caracteres. En algunos idiomas, ord ()
se llama asc ()
.
Ruby tiene Integer # chr
, que funciona muy bien:
>> 65.chr
A
Bastante justo. Pero, ¿cómo vas por el otro lado?
"A".each_byte do |byte|
puts byte
end
impresiones:
65
y eso está bastante cerca de lo que quiero. Pero realmente prefiero evitar un bucle: estoy buscando algo lo suficientemente corto como para ser legible al declarar un const
.
Solución
Si String # ord no existía en 1.9, sí existe en 2.0:
"A".ord #=> 65
Otros consejos
En Ruby hasta la serie 1.8 incluida, lo siguiente producirá 65 (para ASCII):
puts ?A
'A'[0]
El comportamiento ha cambiado en Ruby 1.9, los dos anteriores producirán " A " en lugar. La forma correcta de hacer esto en Ruby 1.9 es:
'A'[0].ord
Desafortunadamente, el método ord
no existe en Ruby 1.8.
Prueba:
'A'.unpack('c')
Me gustaría hacer +1 en dylanfm y el comentario de AShelly pero agregar el [0]:
La llamada desempaquetar devuelve una matriz que contiene un solo entero, que no siempre se acepta donde se desea un entero:
$ ruby -e 'printf("0x%02X\n", "A".unpack("C"))' -e:1:in `printf': can't convert Array into Integer (TypeError) from -e:1 $ ruby -e 'printf("0x%02X\n", "A".unpack("C")[0])' 0x41 $
Estoy tratando de escribir código que funcione en Ruby 1.8.1, 1.8.7 y 1.9.2.
Editado para pasar C para desempaquetar en mayúsculas, porque unpack (& ??quot; c ") me da -1 donde ord () me da 255 (a pesar de correr en una plataforma donde está firmado el carácter de C).
Acabo de encontrar esto al armar una versión pura de Ruby de Stringprep a través de RFC.
Tenga en cuenta que chr
falla fuera de [0,255], en su lugar use 1.9.x - 2.1.x reemplazos portátiles:
[22] pry(main)> "\u0221".ord.chr
RangeError: 545 out of char range
from (pry):2:in 'chr'
[23] pry(main)> x = "\u0221".unpack('U')[0]
=> 545
[24] pry(main)> [x].pack('U')
=> "ȡ"
[25] pry(main)>
Además, si tiene el carácter en una cadena y desea decodificarlo sin bucle:
puts 'Az'[0]
=> 65
puts 'Az'[1]
=> 122
¿Qué tal
pone? A
Si no le importa extraer los valores de una matriz, puede usar "A".bytes
Puede tener estos:
65.chr.ord
'a'.ord.chr
Estoy escribiendo código para 1.8.6 y 1.9.3 y no pude conseguir que ninguna de estas soluciones funcione en ambos entornos :(
Sin embargo, me encontré con otra solución: http://smajnr.net /2009/12/ruby-1-8-nomethoderror-undefined-method-ord-for-string.html
Eso tampoco funcionó para mí, pero lo adapté para mi uso:
unless "".respond_to?(:ord)
class Fixnum
def ord
return self
end
end
end
Una vez hecho eso, lo siguiente funcionará en ambos entornos
'A'[0].ord