Æ, Ø и Å в Ruby - Почему («A» .. «Å»). To_a возвращает двойной алфавит? - PullRequest
0 голосов
/ 02 мая 2018

Я играл в IRB и обнаружил, что:

("A".."Z").to_a (конечно) возвращает:

=> ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

Но ("A".."Å").to_a возвращает:

=> ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", 
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", 
"AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", 
"AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ", "BA", "BB", "BC", "BD", 
"BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", 
"BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ", "CA", "CB", "CC", "CD", 
...
"ZR", "ZS", "ZT", "ZU", "ZV", "ZW", "ZX", "ZY", "ZZ"]

Я попытался прочитать о методе to_a, но не смог найти ничего, объясняющего это поведение.

Почему это происходит?

1 Ответ

0 голосов
/ 02 мая 2018

("A".."Å") работает аналогично "A".upto("Å"). Теперь о String#upto есть две вещи:

  • Используется String#succ для получения следующего значения.
  • Согласно спецификациям Ruby он прекращает итерацию, если размер текущей строки становится больше, чем размер конечной строки. Вероятно, это сделано для того, чтобы избежать бесконечных расстояний.

"Å" кодируется двумя байтами:

"Å".bytes # => [195, 133]

В то время как "A" кодируется только в одном:

"A".bytes # => [65]

Давайте начнем итерацию:

"A".succ # => "B"
"B".succ # => "C"
# ...
"Y".succ # => "Z"
"Z".succ # => "AA"

"AA".succ # => "AB"
# ...
"ZY".succ # => "ZZ"
"ZZ".succ # => "AAA"

Теперь "AAA" все еще "меньше", чем "Å" :

"AAA" < "Å" # => true

Но он имеет размер 3 байта:

"AAA".bytes # => [65, 65, 65]

Следовательно, согласно спецификации , диапазон здесь останавливается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...