Class: Money::Splitter

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/money/splitter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(money, num) ⇒ Splitter

Returns a new instance of Splitter.

Raises:

  • (ArgumentError)


7
8
9
10
11
12
# File 'lib/money/splitter.rb', line 7

def initialize(money, num)
  @num = Integer(num)
  raise ArgumentError, "need at least one party" if num < 1
  @money = money
  @split = nil
end

Instance Attribute Details

#splitObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/money/splitter.rb', line 16

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

Instance Method Details

#[](index) ⇒ Object



72
73
74
75
76
77
78
79
80
81
# File 'lib/money/splitter.rb', line 72

def [](index)
  offset = 0
  split.each do |money, count|
    offset += count
    if index < offset
      return money
    end
  end
  nil
end

#each(&block) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/money/splitter.rb', line 91

def each(&block)
  split.each do |money, count|
    count.times do
      yield money
    end
  end
end

#first(count = (count_undefined = true)) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/money/splitter.rb', line 33

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

#last(count = (count_undefined = true)) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/money/splitter.rb', line 52

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

#reverseObject



99
100
101
102
103
# File 'lib/money/splitter.rb', line 99

def reverse
  copy = dup
  copy.split = split.reverse_each.to_h.freeze
  copy
end

#reverse_each(&block) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/money/splitter.rb', line 83

def reverse_each(&block)
  split.reverse_each do |money, count|
    count.times do
      yield money
    end
  end
end

#sizeObject



105
106
107
108
109
# File 'lib/money/splitter.rb', line 105

def size
  count = 0
  split.each_value { |c| count += c }
  count
end