2017-09-14 2 views
0

J'ai un énumérateur qui boucle sur les données d'une API externe. L'API demande que je le notifie lorsque j'ai fini de faire une boucle. Ceci est assez facile lorsque le recenseur est autorisé à aller jusqu'à épuisement des données:Comment puis-je "fermer" un recenseur dans Ruby?

def api_enum 
    return enum_for(:api_enum) unless block_given? 
    loop_on_api_calls { |thing| yield thing } 
    notify_api_that_i_am_done 
end 

Mais qu'en ce cas?

api_enum.each do |thing| 
    do_stuff(thing) 
    break 
end 

Le break signifie que je ne vais jamais appeler notify_api_that_i_am_done. Comment pourrais-je structurer ceci pour garantir que notify_api_that_i_am_done est appelé? Y a-t-il un bon modèle pour cela?

+0

Quel est le problème avec 'break notify_api_that_i_am_done'? – spickermann

+0

@spickermann Honnêtement, je ne savais pas que c'était une chose. – abeger

Répondre

0

Vous pouvez simplement appeler break avec un argument:

api_enum.each do |thing| 
    do_stuff(thing) 
    break(notify_api_that_i_am_done) 
end 
0

Dans votre méthode api_enum, vous pouvez utiliser ensure pour exécuter toujours le code de nettoyage, indépendamment de toute exception levée ou l'utilisateur break ing. C'est une bonne idée à utiliser pour n'importe quel code de nettoyage puisque seulement de cette façon vous pouvez vous assurer qu'il s'exécute même si quelque chose déclenche une exception dans le bloc fourni par l'utilisateur.

Ceci peut être utilisé comme ceci:

def api_enum 
    return enum_for(:api_enum) unless block_given? 
    loop_on_api_calls { |thing| yield thing } 
ensure 
    notify_api_that_i_am_done 
end 

Avec ce modèle, vous n'avez pas besoin de suivre toutes les conventions d'appel spéciaux.