DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Call A Function On All Items In An Array And Collect Responses

10.09.2008
| 3412 views |
  • submit to reddit
        
# The invisible proxy allows seamless calling of a method on all objects of an array.
# When an array is wrapped (passed into) one of these objects, you can call a function
# on all objects in the array with one line.

# This is not how this works exactly, but a good resource:
#   http://alisdair.mcdiarmid.org/2005/12/20/invisible-proxies-with-ruby

class InvisibleProxyToArray

  instance_methods.each do |m|
    undef_method(m) unless m =~ /(^__|^nil\\?|^send)/
  end
  
  def initialize(collection)
    @collection = collection
  end

  def respond_to?(symbol)
    @collection.first.respond_to?(symbol)
  end
   
  # calls a method on every member of the proxied array
  # and totals the return values
  def total(total_symbol)
    total=0
    @collection.each{|obj|total= total + obj.send(total_symbol)}
    total
  end
  
  
  # gives a string indicating object responses to being sent a symbol (which calls a property or method)
  # summarize(:status) will produce:  running (2), stopping (13)
  def summarize(summarize_symbol)
    msgs=[]
    hsh=hash_by_result(summarize_symbol, @collection)
    hsh.each {|status, resources_arr| msgs << "#{status} (#{resources_arr.length})"}
    msgs.join(',')
  end
  
  # returns a hash like {"running"=>[a , b], "dead"=>[a]} for :status or other messages
  # where a and b would be resources whose response for :status was "running"
  def hash_by_result(property_symbol,object_array)
    hsh={} 
    object_array.each do |obj|
      hsh[obj.send(property_symbol)] ||= []
      hsh[obj.send(property_symbol)] << obj 
    end
    hsh
  end
   
  
  private

  def method_missing(method, *args, &block)
    @collection.each {|item| item.send(method, *args, &block)}
  end
  
end