De ce qui suit, 'ary' est logiquement égal à array. Notez que la ligne est absente des nouvelles versions de Ruby telles que 2.4.0!
volatile VALUE ary = array;
Je saute RETURN_SIZED_ENUMERATOR car un bloc est donné. Reportez-vous à sa source à include/ruby / intern.h.
Ensuite, nous allons dans un 'for' pour chaque élément du tableau 'ary'.
Ensuite, c'est la ligne qui vous intrigue, je crois. Tout d'abord, il prend le i-ème élément du tableau 'ary' via la macro RARRAY_AREF. Deuxièmement, il a passé la valeur de l'élément au bloc donné (c'est-à-dire 'a + 1') via rb_yield. Ainsi, il ne stocke rien.
rb_yield(RARRAY_AREF(ary, i));
Depuis rien n'a été écrit à rb_yield, la fonction retourne le tableau « aire » qui est [voir ci-dessus] est entrée « array ».
En le comparant à 'map!' peut vous aider davantage:
static VALUE rb_ary_collect_bang(VALUE ary)
{
long i;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
}
return ary;
}
Remarque Appel de fonction 'rb_ary_store' dans la boucle 'for'. C'est la chose! C'est rb_yield-s comme dans chaque variante, mais cela ne gomme pas le résultat retourné. Le résultat est stocké dans le i-ième élément de notre tableau [aimé] 'ary'.
Personnellement, je trouve [cette implémentation] (https://github.com/rubinius/rubinius/blob/master/core/array.rb#L64-L77) beaucoup plus facile à lire que YARV. –