Вопрос
Во многих языках существует пара функций, chr()
и ord()
, которые преобразуют числа в символьные значения.На некоторых языках, ord()
называется asc()
.
У Руби есть Integer#chr
, который отлично работает:
>> 65.chr
A
Достаточно справедливо.Но как вы идете другим путем?
"A".each_byte do |byte|
puts byte
end
С принтами:
65
и это довольно близко к тому, чего я хочу.Но я бы действительно предпочел избежать цикла - я ищу что-то достаточно короткое, чтобы его можно было прочитать при объявлении const
.
Решение
Если строка #ord не существовала в 1.9, она существует в 2.0:
"A".ord #=> 65
Другие советы
В Ruby до серии 1.8 включительно оба следующих параметра будут выдавать 65 (для ASCII):
puts ?A
'A'[0]
Поведение изменилось в Ruby 1.9, оба вышеперечисленных действия приведут вместо этого к появлению буквы "A".Правильный способ сделать это в Ruby 1.9 - это:
'A'[0].ord
К сожалению, в ord
метод не существует в Ruby 1.8.
Попробуй:
'A'.unpack('c')
Я бы хотел добавить +1 комментарий dylanfm и AShelly, но добавить [0]:
'A'.unpack('C')[0]
Вызов unpack возвращает массив, содержащий одно целое число, которое не всегда принимается там, где требуется целое число:
$ 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 $
Я пытаюсь написать код, который работает на Ruby 1.8.1, 1.8.7 и 1.9.2.
Отредактировано, чтобы передать C для распаковки в верхнем регистре, потому что unpack("c") дает мне -1, где ord() дает мне 255 (несмотря на запуск на платформе, где символ C подписан).
Просто наткнулся на это, когда собирал чистую версию Stringprep на Ruby через RFC.
Остерегайтесь этого chr
сбой снаружи [0,255], вместо этого используйте переносимые замены 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)>
Кроме того, если у вас есть символ в строке, и вы хотите декодировать его без цикла:
puts 'Az'[0]
=> 65
puts 'Az'[1]
=> 122
Как насчет
ставит ?А
Если вы не возражаете против извлечения значений из массива, вы можете использовать "A".bytes
Ты можешь взять это:
65.chr.ord
'a'.ord.chr
Я пишу код для 1.8.6 и 1.9.3, и я не смог заставить ни одно из этих решений работать в обеих средах: (
Однако я наткнулся на другое решение:http://smajnr.net/2009/12/ruby-1-8-nomethoderror-undefined-method-ord-for-string.html
У меня это тоже не сработало, но я адаптировал его для своего использования:
unless "".respond_to?(:ord)
class Fixnum
def ord
return self
end
end
end
Сделав это, следующее будет работать в обеих средах
'A'[0].ord