I have an enumerator that loops on data from an external API. The API requests that I notify it when I'm done looping. This is pretty easy when the enumerator is allowed to go until it runs out of data:
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
But what about this case?
api_enum.each do |thing|
do_stuff(thing)
break
end
The break
means I'm never going to call notify_api_that_i_am_done
. How could I structure this to guarantee that notify_api_that_i_am_done
gets called? Is there a good pattern to for this?
In your
api_enum
method, you can useensure
to always execute cleanup code, regardless of any exception being thrown or the userbreak
ing. This is a good idea to use for any cleanup code since only tht way you can ensure that the it us run even if something raises an exception in the user-supplied block.This can be used like this:
With that pattern, you don't need to follow any special call conventions.