module AWS::Core::Collection
Provides useful methods for enumerating items in a collection.
Public Instance Methods
Yields once for every item in this collection.
collection.each {|item| ... }
@note If you want fewer than all items, it is generally better
to call {#page} than {#each} with a `:limit`.
@param [Hash] options
@option options [Integer] :limit (nil) The maximum number of
items to enumerate from this collection.
@option options [next_token] :next_token (nil)
Acts as an offset. `:next_token` may be returned by {#each} and {#each_batch} when a `:limit` is provided.
@return [nil_or_next_token] Returns nil if all items were enumerated.
If some items were excluded because of a `:limit` option then a `next_token` is returned. Calling an enumerable method on the same collection with the `next_token` acts like an offset.
# File lib/aws/core/collection.rb, line 46 def each options = {}, &block each_batch(options) do |batch| batch.each(&block) end end
Yields items from this collection in batches.
collection.each_batch do |batch| batch.each do |item| # ... end end
## Variable Batch Sizes
Each AWS
service has its own rules on how it returns results. Because of this batch size may very based on:
-
Service limits (e.g.
S3
limits keys to 1000 per response) -
The size of response objects (
SimpleDB
limits responses to 1MB) -
Time to process the request
Because of these variables, batch sizes may not be consistent for a single collection. Each batch represents all of the items returned in a single resopnse.
@note If you require fixed batch sizes, see {#in_groups_of}. @param (see each
) @option (see each
) @return (see each
)
# File lib/aws/core/collection.rb, line 79 def each_batch options = {}, &block _each_batch(options.dup, &block) end
Use this method when you want to call a method provided by Enumerable, but you need to pass options:
# raises an error because collect does not accept arguments collection.collect(:limit => 10) {|i| i.name } # not an issue with the enum method collection.enum(:limit => 10).collect(&:name)
@param (see each
) @option (see each
) @return [Enumerable::Enumerator] Returns an enumerator for this
collection.
# File lib/aws/core/collection.rb, line 97 def enum options = {} to_enum(:each, options) end
Returns the first item from this collection.
@return [item_or_nil] Returns the first item from this collection or
nil if the collection is empty.
# File lib/aws/core/collection.rb, line 107 def first options = {} enum(options.merge(:limit => 1)).first end
Yields items from this collection in groups of an exact size (except for perhaps the last group).
collection.in_groups_of (10, :limit => 30) do |group| # each group should be exactly 10 items unless # fewer than 30 items are returned by the service group.each do |item| #... end end
@param [Integer] size Size each each group of objects
should be yielded in.
@param [Hash] options @option (see each
) @return (see each
)
# File lib/aws/core/collection.rb, line 129 def in_groups_of size, options = {}, &block group = [] nil_or_next_token = each_batch(options) do |batch| batch.each do |item| group << item if group.size == size yield(group) group = [] end end end yield(group) unless group.empty? nil_or_next_token end
Returns a single page of results in a kind-of array ({PageResult}).
items = collection.page(:per_page => 10) # defaults to 10 items items.is_a?(Array) # => true items.size # => 8 items.per_page # => 10 items.last_page? # => true
If you need to display a “next page” link in a web view you can use the more? method. Just make sure the generated link contains the ‘next_token`.
<% if items.more? %> <%= link_to('Next Page', params.merge(:next_token => items.next_token) %> <% end %>
Then in your controller you can find the next page of results:
items = collection.page(:next_token => params[:next_token])
Given a {PageResult} you can also get more results directly:
more_items = items.next_page
@note This method does not accept a ‘:page` option, which means you
can only start at the begining of the collection and request the next page of results. You can not choose an offset or know how many pages of results there will be.
@param [Hash] options A hash of options that modifies the
items returned in the page of results.
@option options [Integer] :per_page (10) The number of results
to return for each page.
@option options [String] :next_token (nil) A token that indicates
an offset to use when paging items. Next tokens are returned by {PageResult#next_token}. Next tokens should only be consumed by the same collection that created them.
# File lib/aws/core/collection.rb, line 191 def page options = {} each_opts = options.dup per_page = each_opts.delete(:per_page) per_page = [nil,''].include?(per_page) ? 10 : per_page.to_i each_opts[:limit] = per_page items = [] next_token = each(each_opts) do |item| items << item end Core::PageResult.new(self, items, per_page, next_token) end
Protected Instance Methods
# File lib/aws/core/collection.rb, line 211 def _each_batch options, &block # should be defined in the collection modules raise NotImplementedError end
# File lib/aws/core/collection.rb, line 216 def _each_item next_token, options = {}, &block # should be defined in classes included the collection modules raise NotImplementedError end
# File lib/aws/core/collection.rb, line 227 def _extract_batch_size options batch_size = options.delete(:batch_size) batch_size = nil if batch_size == '' batch_size = batch_size.to_i if batch_size batch_size end
# File lib/aws/core/collection.rb, line 234 def _extract_limit options limit = options.delete(:limit) || _limit limit = nil if limit == '' limit = limit.to_i if limit limit end
# File lib/aws/core/collection.rb, line 221 def _extract_next_token options next_token = options.delete(:next_token) next_token = nil if next_token == '' next_token end
Override this method in collection classes that provide an alternative way to provide the limit than passinging it to the enumerable method as :limit.
An example of when this would be useful:
collection.limit(10).each {|item| ... }
The collection class including this module should define _limit and return the cached limit value (of 10 from this example). This value may still be overridden by a locally passed ‘:limit` option:
# limit 5 wins out collection.limit(10).each(:limit => 5) {|item| ... }
# File lib/aws/core/collection.rb, line 257 def _limit nil end