Created
February 23, 2011 16:57
-
-
Save ericbeland/840710 to your computer and use it in GitHub Desktop.
Invisibly call methods on all array members
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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. Useful for dsl's and such. | |
class InvisibleProxyToArray | |
instance_methods.each do |m| | |
undef_method(m) unless m =~ /(^__|^nil\\?|object_id|^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) | |
@collection.inject(0){|tot, obj| tot + obj.send(total_symbol)} | |
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| | |
val = obj.send(property_symbol) | |
hsh[val] ||= [] | |
hsh[val] << obj | |
end | |
hsh | |
end | |
private | |
def method_missing(method, *args, &block) | |
@collection.each {|item| item.send(method, *args, &block)} | |
end | |
end | |
# a toy to demonstrate | |
class Thing | |
attr_reader :value | |
def initialize(value) | |
@value=value | |
end | |
def say_num | |
puts "My value is: #{@value}" | |
end | |
def status | |
['pillow talk, baby','chewing bubblegum', 'kicking ass'].sample | |
end | |
end | |
mythings=InvisibleProxyToArray.new([Thing.new(9), Thing.new(10), Thing.new(9), Thing.new(11)]) | |
puts "total: #{mythings.total(:value)}" | |
puts "summarize: #{mythings.summarize(:status)}" | |
puts "the fun part--call a method on all members with one line and no block" | |
mythings.say_num |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment