Cette question ne concerne pas comment utiliser des énumérateurs dans Ruby 1.9.1, mais je suis plutôt curieux comment ils travaillent. Voici quelques codes: dans le code ci-dessus, je peux utiliser Je suis conscient que si le rendement dans le J'ai regardé Enumerator.c mais c'est un hostile sur incompréhensible pour moi. Peut-être que quelqu'un pourrait fournir une implémentation en rubis, en utilisant des fibres, pas 1,8,6 énumérateurs à base de continuation, qui rend tout ce qui est clair? P> P> e = bunk.new.each code>, puis
e.next code> ,
e.next code> Pour obtenir chaque élément successif, mais comment est-ce exactement la suspension d'exécution, puis la reprise au bon endroit? p>
0UVETO code> est remplacé par
fibre.yield code>, il est facile de comprendre, mais ce n'est pas le cas ici. C'est un vieil
un clair code>, alors comment ça marche? P>
4 Réponses :
En fait dans votre e = bunk.New.ef.ach la clause de l'autre n'est pas exécutée initialement. Au lieu de cela, la clause "if! Block_given" exécute et renvoie un objet d'énumérateur. L'objet Enumerator conserve un objet de fibre interne. (Au moins c'est à quoi cela ressemble à Enumerator.c) p>
Lorsque vous appelez E.Ache, il appelle une méthode sur un énumérateur qui utilise une fibre interne pour suivre son contexte d'exécution. Cette méthode appelle le bunk.Chaque méthode à l'aide du contexte d'exécution des fibres. Le bunk.Chaque appel ici exécute la clause de l'autre et donne la valeur de la valeur. P>
Je ne sais pas comment le rendement est mis en œuvre ou comment une fibre suit le contexte d'exécution. Je n'ai pas regardé ce code. Presque tout l'énumérateur et la magie de fibres sont mises en œuvre dans c. P>
Vous demandez vraiment comment les fibres et le rendement sont mis en œuvre? Quel niveau de détail recherchez-vous? P>
Si je suis hors bas, corrigez-moi. P>
Merci pour votre réponse. Oui, je demande beaucoup de détails à ce sujet. Spécifiquement, j'aimerais savoir s'il est possible de tout mettre en œuvre dans Ruby ou s'il y a quelque chose de sournois dans C qui n'est pas possible dans Ruby. S'il est possible de la mettre en œuvre purement en rubis, j'aimerais voir le code! :)
Voici un énumérateur de rubis simple qui utilise des fibres et devrait plutôt bien se comporter comme l'original: et au cas où tout le monde se sent mal à l'emploi de l'utilisation d'exceptions pour le flux de contrôle: le véritable énumérateur augmente l'arrêt À la fin, aussi, donc je viens d'émuler le comportement d'origine. P> Utilisation: p>
Comme les autres affiches notées, je crois que cela crée sa propre "fibre" privée [en 1.9]. Dans 1.8.7 (ou 1.8.6 si vous utilisez la joyau BackPorts) d'une manière ou d'une autre, elle fait la même chose (peut-être parce que tous les threads de 1,8 sont l'équivalent des fibres, il les utilise simplement?) P>
Ainsi, dans les 1,9 et 1.8.x, si vous en portiez plusieurs d'entre eux ensemble aached_line.map.each_with_index {} p>
Il coule en fait à travers cette chaîne entière avec chaque ligne, comme un tuyau sur la ligne de commande p>
http://pragdave.blogs.pragprrog.com /pragdave/2007/12/pipelines-utilisation.html p>
hth. p>
Voici une excellente description détaillée wiki.github.com/rdp/Ruby_Tutorials_core/enumerator
Je pense que cela serait plus précis. Appeler chacun sur l'énumérateur doit être identique à celle d'appeler la méthode d'itérateur d'origine. Donc, je changerais légèrement la solution originale à ceci: