Мне также очень помогло объяснение Гари Райта.
http://www.ruby -forum.com / тема / 1393096 # 990065
Ответ Гэри Райта -
http://www.ruby -doc.org / ядро / классы / Array.html
Документы, конечно, могут быть более ясными, но фактическое поведение
самосогласованный и полезный.
Примечание: я предполагаю, что 1.9.X версия String.
Помогает рассмотреть нумерацию следующим образом:
-4 -3 -2 -1 <-- numbering for single argument indexing
0 1 2 3
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
0 1 2 3 4 <-- numbering for two argument indexing or start of range
-4 -3 -2 -1
Распространенная (и понятная) ошибка - слишком предположить, что семантика
индекса одного аргумента совпадают с семантикой
первый аргумент в сценарии с двумя аргументами (или диапазон). Они не
то же самое на практике, и документация не отражает это.
Ошибка определенно есть в документации, а не в
реализация:
один аргумент: индекс представляет позицию одного символа
внутри строки. Результатом является либо строка из одного символа
найдено в индексе или ноль, потому что нет символа в данном
индекс.
s = ""
s[0] # nil because no character at that position
s = "abcd"
s[0] # "a"
s[-4] # "a"
s[-5] # nil, no characters before the first one
два целочисленных аргумента: аргументы идентифицируют часть строки для
извлечь или заменить. В частности, части строки нулевой ширины
также можно определить, чтобы текст мог быть вставлен до или после
существующие символы, в том числе в начале или конце строки. В этом
в этом случае первый аргумент не идентифицирует позицию символа, но
вместо этого идентифицирует пространство между символами, как показано на диаграмме
выше. Второй аргумент - это длина, которая может быть 0.
s = "abcd" # each example below assumes s is reset to "abcd"
To insert text before 'a': s[0,0] = "X" # "Xabcd"
To insert text after 'd': s[4,0] = "Z" # "abcdZ"
To replace first two characters: s[0,2] = "AB" # "ABcd"
To replace last two characters: s[-2,2] = "CD" # "abCD"
To replace middle two characters: s[1..3] = "XX" # "aXXd"
Поведение диапазона довольно интересно. Отправной точкой является
такой же, как первый аргумент, когда предоставляются два аргумента (как описано
выше), но конечной точкой диапазона может быть «позиция символа» как
с одиночным индексированием или «положением края» как с двумя целыми числами
аргументы. Разница определяется тем, находится ли диапазон двойных точек
или используется диапазон из трех точек:
s = "abcd"
s[1..1] # "b"
s[1..1] = "X" # "aXcd"
s[1...1] # ""
s[1...1] = "X" # "aXbcd", the range specifies a zero-width portion of
the string
s[1..3] # "bcd"
s[1..3] = "X" # "aX", positions 1, 2, and 3 are replaced.
s[1...3] # "bc"
s[1...3] = "X" # "aXd", positions 1, 2, but not quite 3 are replaced.
Если вы вернетесь к этим примерам и будете настаивать на
семантика индекса для примеров двойного или диапазона индексации вы просто
смутиться. Вы должны использовать альтернативную нумерацию, которую я показываю в
диаграмма ascii для моделирования реального поведения.