Cela a à voir avec le fait que slice renvoie un tableau, documentation source pertinente de Array#slice :
* call-seq:
* array[index] -> obj or nil
* array[start, length] -> an_array or nil
* array[range] -> an_array or nil
* array.slice(index) -> obj or nil
* array.slice(start, length) -> an_array or nil
* array.slice(range) -> an_array or nil
ce qui me suggère que si vous donnez un début qui est hors limites, il retournera nil, donc dans votre exemple array[4,0]
demande le 4ème élément qui existe, mais demande de retourner un tableau de zéro éléments. Alors que array[5,0]
demande un index hors limites et renvoie donc nil. Cela a peut-être plus de sens si l'on se rappelle que la méthode slice renvoie un fichier nouveau sans modifier la structure de données originale.
EDITAR:
Après avoir examiné les commentaires, j'ai décidé de modifier cette réponse. La tranche appelle ce qui suit extrait de code lorsque la valeur de l'arg est de deux :
if (argc == 2) {
if (SYMBOL_P(argv[0])) {
rb_raise(rb_eTypeError, "Symbol as array index");
}
beg = NUM2LONG(argv[0]);
len = NUM2LONG(argv[1]);
if (beg < 0) {
beg += RARRAY(ary)->len;
}
return rb_ary_subseq(ary, beg, len);
}
si vous regardez dans le array.c
où le rb_ary_subseq
est définie, vous voyez qu'elle renvoie nil si la longueur est hors limites, et non l'index :
if (beg > RARRAY_LEN(ary)) return Qnil;
Dans ce cas, c'est ce qui se passe lorsque 4 est passé, il vérifie qu'il y a 4 éléments et ne déclenche donc pas le retour nil. Il retourne ensuite un tableau vide si le second argument est égal à zéro. Alors que si 5 est passé, il n'y a pas 5 éléments dans le tableau, donc il retourne nil avant que l'argument zéro soit évalué. code aquí à la ligne 944.
Je pense qu'il s'agit d'un bogue, ou du moins d'un phénomène imprévisible et non du "principe de la moindre surprise". Quand j'aurai quelques minutes, je soumettrai au moins un patch de test défaillant à ruby core.
3 votes
Voir aussi Pourquoi array.slice se comporte-t-il différemment pour (longueur, n)
0 votes
On dirait que le premier chiffre est l'index de départ, le second le nombre d'éléments à découper.