programming-examples/ruby/Patterns/iterator.rb

88 lines
1.3 KiB
Ruby
Raw Normal View History

2019-11-15 12:59:38 +01:00
# Provide a way to access the elements of an aggregate object sequentially
# without exposing its underlying representation.
# Iteration entity
class Account
attr_reader :balance
def initialize(balance)
@balance = balance
end
end
# Collection class
class Bank
include Enumerable
def initialize
@accounts = []
end
def each(&block)
@accounts.each(&block)
end
def add(account)
@accounts << account
end
end
# Usage
bank = Bank.new
bank.add Account.new(100)
bank.add Account.new(150)
bank.add Account.new(175)
puts bank.map { |account| account.balance }
# Internal iterator
class Collection
def initialize(array)
@array = array
@index = 0
end
def has_next?
@index < @array.length
end
def next_item
value = @array[@index]
@index += 1
value
end
def iterate(&block)
while has_next?
block.call(next_item) if block_given?
end
end
end
# Usage
collection = Collection.new([1, 2, 3, 4, 5])
collection.iterate { |elem| puts elem }
# External iterator
class Collection
def initialize(array)
@array = array
@index = 0
end
def has_next?
@index < @array.length
end
def next_item
value = @array[@index]
@index += 1
value
end
end
# Usage
collection = Collection.new([1, 2, 3, 4, 5])
puts "Item: #{collection.next_item}" while collection.has_next?