Ho trovato molto utile anche la spiegazione di Gary Wright.
http://www.ruby-forum.com/topic/1393096#990065
La risposta di Gary Wright è:
http://www.ruby-doc.org/core/classes/Array.html
I documenti certamente potrebbero essere più chiari, ma il comportamento effettivo è coerente e utile. Nota: presumo la versione 1.9.X di String.
Aiuta a considerare la numerazione nel modo seguente:
-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
L'errore comune (e comprensibile) è anche supporre che la semantica dell'indice a singolo argomento sia la stessa della semantica del
primo argomento nello scenario (o intervallo) a due argomenti. Non sono la stessa cosa in pratica e la documentazione non riflette questo. L'errore però è sicuramente nella documentazione e non nell'implementazione:
argomento singolo: l'indice rappresenta una posizione di singolo carattere all'interno della stringa. Il risultato è la stringa di singolo carattere trovata nell'indice o nulla perché non è presente alcun carattere nell'indice specificato.
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
due argomenti interi: gli argomenti identificano una parte della stringa da estrarre o sostituire. In particolare, è anche possibile identificare parti della stringa di larghezza zero in modo che il testo possa essere inserito prima o dopo i caratteri esistenti, compresi all'inizio o alla fine della stringa. In questo caso, il primo argomento non identifica una posizione di carattere ma identifica invece lo spazio tra i caratteri come mostrato nel diagramma sopra. Il secondo argomento è la lunghezza, che può essere 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"
Il comportamento di un intervallo è piuttosto interessante. Il punto iniziale è lo stesso del primo argomento quando vengono forniti due argomenti (come descritto sopra) ma il punto finale dell'intervallo può essere la 'posizione del carattere' come con l'indicizzazione singola o la "posizione del bordo" come con due argomenti interi. La differenza è determinata dall'uso dell'intervallo di punti doppi o di punti tripli:
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.
Se ripercorri questi esempi e insisti e usi la semantica dell'indice singolo per gli esempi di indicizzazione a doppio o intervallo, ti confonderai. Devi usare la numerazione alternativa che mostro nel diagramma ascii per modellare il comportamento reale.