J'ai également trouvé l'explication de Gary Wright très utile.
http://www.ruby-forum.com/topic/1393096#990065
La réponse de Gary Wright est -
http://www.ruby-doc.org/core/classes/Array.html
Les documents pourraient certainement être plus clairs, mais le comportement réel est cohérent et utile. Remarque: je suppose que la version 1.9.X de String.
Il est utile de considérer la numérotation de la manière suivante:
-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'erreur courante (et compréhensible) est également de supposer que la sémantique de l'index à argument unique est la même que la sémantique du
premier argument dans le scénario (ou plage) à deux arguments. Ce n'est pas la même chose dans la pratique et la documentation ne reflète pas cela. L'erreur est cependant définitivement dans la documentation et non dans l'implémentation:
seul argument: l'index représente une position de caractère unique dans la chaîne. Le résultat est soit la chaîne de caractères unique trouvée à l'index, soit nil car il n'y a pas de caractère à l'index donné.
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
deux arguments entiers: les arguments identifient une partie de la chaîne à extraire ou à remplacer. En particulier, des parties de largeur nulle de la chaîne peuvent également être identifiées afin que le texte puisse être inséré avant ou après les caractères existants, y compris à l'avant ou à la fin de la chaîne. Dans ce cas, le premier argument n'identifie pas une position de caractère mais identifie à la place l'espace entre les caractères comme indiqué dans le diagramme ci-dessus. Le deuxième argument est la longueur, qui peut être 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"
Le comportement d'une plage est assez intéressant. Le point de départ est le même que le premier argument lorsque deux arguments sont fournis (comme décrit ci-dessus) mais le point final de la plage peut être la «position de caractère» comme pour l'indexation simple ou la «position de bord» comme pour deux arguments entiers. La différence est déterminée par l'utilisation de la plage à deux points ou de la plage à trois points:
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.
Si vous revenez à travers ces exemples et insistez pour utiliser la sémantique d'index unique pour les exemples d'indexation double ou plage, vous serez simplement confus. Vous devez utiliser la numérotation alternative que je montre dans le diagramme ascii pour modéliser le comportement réel.