Что противоположно chr () в Ruby?

Во многих языках есть пара функций, chr() и ord(), которые преобразуют числа и символы. На некоторых языках ord() называется asc().

У Ruby есть Integer#chr, который отлично работает:

>> 65.chr
A

Справедливо. Но как пойти другим путем?

"A".each_byte do |byte|
   puts byte
end

печатает:

65

и это довольно близко к тому, что я хочу. Но я бы предпочел избежать цикла - я ищу что-то достаточно короткое, чтобы его можно было прочитать при объявлении const.

Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
101
0
80 004
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Как насчет

puts ?A

Пытаться:

'A'.unpack('c')

Теперь, когда Ruby 1.9 изменил значение 'A' [0], это более переносимый метод.

AShelly 22.11.2008 04:11

Кроме того, если у вас есть символ в строке и вы хотите декодировать его без цикла:

puts 'Az'[0]
=> 65
puts 'Az'[1]
=> 122

В Ruby до серии 1.8 включительно следующие строки будут производить 65 (для ASCII):

puts ?A
'A'[0]

Поведение изменилось в Ruby 1.9, вместо этого оба вышеперечисленных будут выдавать «A». Правильный способ сделать это в Ruby 1.9:

'A'[0].ord

К сожалению, метод ord не существует в Ruby 1.8.

К сожалению, «правильный» путь в Ruby 1.9 такой длинный, но, по крайней мере, он будет легче обнаруживаться при поиске «ord». Спасибо за очень подробный ответ.

RJHunter 22.11.2008 14:30

Я хотел бы +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 подписан char).

Ответ принят как подходящий

Если String # ord не существовал в 1.9, он есть в 2.0:

"A".ord #=> 65

У вас могут быть такие:

65.chr.ord
'a'.ord.chr

Только что наткнулся на это, когда собирал чистую версию 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)>

Спасибо, это, кажется, единственный ответ, который дает char и его инверсию в случае юникода правильно

Munyari 13.08.2016 19:25

Если вы не против вытащить значения из массива, вы можете использовать "A".bytes

Я пишу код для 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

Когда user18096 написал свой ответ, "A".unpack("C")[0], он был нацелен на Ruby 1.8.1, Ruby 1.8.7 и Ruby 1.9.2. Не работает ли это в вашей среде? Что за неудача?

RJHunter 14.04.2015 01:32

Привет, RJHunter, я пытаюсь преобразовать определенный символ в строке в его числовое значение. Следующий код работает в 1.9.3, но не в 1.8.6. self.status = tagAccountString[4].unpack('C')[0] В 1.8.6 я получаю Exception undefined method unpack 'для 0: Fixnum обрабатывает данные основных буферизованных тегов - выход` Следующий код работает (с моим предложенным решением) в обеих средах self.status = tagAccountString[4].ord Любые советы (например, лучшее решение) более чем приветствуются

hantscolin 15.04.2015 13:19
tagAccountString[4] возвращает String в новых Ruby, но используется для возврата Fixnum в Ruby 1.8. Вот почему вы увидели ошибку undefined method unpack for 0:Fixnum. Вы можете использовать status = tagAccountString[4,1].unpack('C')[0] или даже status, = tagAccountString.unpack('xxxxC'), если вы всегда хотите игнорировать четыре символа и преобразовать следующий.
RJHunter 18.04.2015 08:25

Спасибо RJHunter за объяснение и альтернативные решения. Однако, поскольку «мое» решение более читабельно и многоразово, я буду придерживаться его (если нет веской причины?)

hantscolin 22.04.2015 16:34

Другие вопросы по теме