class Money::Splitter
def [](index)
def [](index) offset = 0 split.each do |money, count| offset += count if index < offset return money end end nil end
def each(&block)
def each(&block) split.each do |money, count| count.times do yield money end end end
def first(count = (count_undefined = true))
def first(count = (count_undefined = true)) if count_undefined each do |money| return money end elsif count >= size to_a else result = Array.new(count) index = 0 each do |money| result[index] = money index += 1 break if index == count end result end end
def initialize(money, num)
def initialize(money, num) @num = Integer(num) raise ArgumentError, "need at least one party" if num < 1 @money = money @split = nil end
def last(count = (count_undefined = true))
def last(count = (count_undefined = true)) if count_undefined reverse_each do |money| return money end elsif count >= size to_a else result = Array.new(count) index = 0 reverse_each do |money| result[index] = money index += 1 break if index == count end result.reverse! result end end
def reverse
def reverse copy = dup copy.split = split.reverse_each.to_h.freeze copy end
def reverse_each(&block)
def reverse_each(&block) split.reverse_each do |money, count| count.times do yield money end end end
def size
def size count = 0 split.each_value { |c| count += c } count end
def split
def split @split ||= begin subunits = @money.subunits low = Money.from_subunits(subunits / @num, @money.currency) high = Money.from_subunits(low.subunits + 1, @money.currency) num_high = subunits % @num split = {} split[high] = num_high if num_high > 0 split[low] = @num - num_high split.freeze end end