module Pattern
# roll-up - iterating through an ordered array and rolling up
# related entries into a single entry
#
# require '/Users/chiefwahoo/rails/patterns/patterns.rb'
# class Array; include Pattern; end
#
# class Person
# attr_accessor :name, :address
# def initialize(name, address)
# @name = name; @address = address;
# end
# end
#
# # Assumes items are grouped by "key" in this case Person's name
# people = []
# people << Person.new("Compton, Kevin", "123 Mockingbird Lane")
# people << Person.new("Compton, Kevin", "9823 Beach View Drive")
# people << Person.new("Compton, Jessica", "823 City Park Avenue")
# people << Person.new("Compton, Megan", "123 California")
# people << Person.new("Compton, Megan", "876 Mount Vista")
#
# rollup_items = []
#
# people.rollup(
# Proc.new {|person| person.name},
# Proc.new {|person| "User #{person.name} has residences at: "},
# Proc.new {|container, person| container << " #{person.address};" },
# Proc.new {|container|
# rollup_items << container;
# puts "Detail is : #{container}" }
# )
#
# ### OUTPUT ###
# Detail is : User Compton, Kevin has residences at: 123 Mockingbird Lane; 9823 Beach View Drive;
# Detail is : User Compton, Jessica has residences at: 823 City Park Avenue; 9824 Beach View Drive;
# Detail is : User Compton, Keith has residences at: 777 College Avenue;
# Detail is : User Compton, Megan has residences at: 123 California; 876 Mount Vista;
# => nil
# irb(main):098:0> rollup_items
# => ["User Compton, Kevin has residences at: 123 Mockingbird Lane; 9823 Beach View Drive;", "User Compton, Jessica has residences at: 823 City Park Avenue; 9824 Beach View Drive;", "User Compton, Keith has residences at: 777 College Avenue;", "User Compton, Megan has residences at: 123 California; 876 Mount Vista;"]
#
def rollup(bookmark_detail_proc, initialize_item_proc, merge_into_item_proc, finalize_item_proc)
saved_bookmark = nil
current_item = nil

self.each do |line|
current_bookmark = bookmark_detail_proc.call(line)
if saved_bookmark != current_bookmark
finalize_item_proc.call(current_item) unless current_item.nil?

saved_bookmark = current_bookmark
current_item = initialize_item_proc.call(line)
end

merge_into_item_proc.call(current_item, line)
end
finalize_item_proc.call(current_item) unless current_item.nil?
end
end