Quel est le contraire de chr () en Ruby?
Question
Dans de nombreuses langues, il existe une paire de fonctions, chr ()
et ord ()
, qui permettent de convertir des nombres en valeurs numériques. Dans certaines langues, ord ()
est appelé asc ()
.
Ruby a Integer # chr
, ce qui fonctionne très bien:
>> 65.chr
A
Assez bien. Mais comment allez-vous dans l'autre sens?
"A".each_byte do |byte|
puts byte
end
imprime:
65
et c'est assez proche de ce que je veux. Mais je préfère vraiment éviter une boucle - je cherche quelque chose d'assez court pour être lisible lors de la déclaration d'un const
.
La solution
Si String # ord n'existait pas dans la version 1.9, c'est le cas dans la version 2.0:
"A".ord #=> 65
Autres conseils
En Ruby jusqu’à la série 1.8 incluse, les éléments suivants produiront tous deux 65 (pour ASCII):
puts ?A
'A'[0]
Le comportement a changé dans Ruby 1.9, les deux réponses ci-dessus produiront "A". au lieu. La manière correcte de procéder dans Ruby 1.9 est la suivante:
'A'[0].ord
Malheureusement, la méthode ord
n'existe pas dans Ruby 1.8.
Essayez:
'A'.unpack('c')
J'aimerais ajouter +1 au commentaire de dylanfm et AShelly, mais ajouter le [0]:
'A'.unpack (' C ') [0]
L'appel de décompression renvoie un tableau contenant un seul entier, qui n'est pas toujours accepté lorsqu'un nombre entier est souhaité:
$ 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 $
J'essaie d'écrire du code qui fonctionne sur Ruby 1.8.1, 1.8.7 et 1.9.2.
Edité pour passer C et décompresser en majuscule, car unpack ("c") me donne -1, où ord () me donne 255 (bien qu’il soit exécuté sur une plate-forme où le caractère de C est signé).
Je viens de découvrir cela en assemblant une version Ruby pure de Stringprep via RFC.
Veillez à ce que chr
échoue en dehors de [0,255]. Utilisez plutôt des remplacements portables 1.9.x - 2.1.x:
[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)>
De plus, si vous avez le caractère dans une chaîne et que vous souhaitez le décoder sans boucle:
puts 'Az'[0]
=> 65
puts 'Az'[1]
=> 122
Que diriez-vous de
met? A
Si cela ne vous dérange pas d'extraire les valeurs d'un tableau, vous pouvez utiliser "A" .bytes
Vous pouvez avoir ceci:
65.chr.ord
'a'.ord.chr
J'écris du code pour les versions 1.8.6 et 1.9.3 et je ne pouvais utiliser aucune de ces solutions dans les deux environnements: (
Cependant, je suis tombé sur une autre solution: http://smajnr.net /2009/12/ruby-1-8-nomethoderror-undefined-method-ord-for-string.html
Cela n'a pas fonctionné pour moi non plus, mais je l'ai adapté à mon usage:
unless "".respond_to?(:ord)
class Fixnum
def ord
return self
end
end
end
Ceci fait, les éléments suivants fonctionneront dans les deux environnements
'A'[0].ord