Class: Laziest::ArrayPromise
- Inherits:
-
Promise
- Object
- Promise
- Laziest::ArrayPromise
- Defined in:
- lib/laziest/array.rb
Overview
This class is a lazily-evaluated array based on an enumerator. A contract: The enumerator is guaranteed to never be rewound.
Instance Method Summary collapse
-
#[](index, length = nil) ⇒ Object
Array-related laziness.
- #__force_to__(index) ⇒ Object
- #__forced__? ⇒ Boolean
- #each(&block) ⇒ Object
-
#initialize(enumerator, array = [], nil_on_empty = false) ⇒ ArrayPromise
constructor
Accepts ‘array’ to allow a partially-evaluated enumerator/array to initialize.
-
#to_a ⇒ Object
Except this one, make it a no-op.
Constructor Details
#initialize(enumerator, array = [], nil_on_empty = false) ⇒ ArrayPromise
Accepts ‘array’ to allow a partially-evaluated enumerator/array to initialize.
6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/laziest/array.rb', line 6 def initialize enumerator, array=[], nil_on_empty = false @array = array @enumerator = enumerator @nil_on_empty = nil_on_empty super() do ::Kernel.loop do @array << @enumerator.next end @enumerator = nil # Needed for use in hashes, like group_by (nil_on_empty && @array.empty?) ? nil : @array end end |
Instance Method Details
#[](index, length = nil) ⇒ Object
Array-related laziness
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/laziest/array.rb', line 33 def [] index, length=nil return super if __forced__? if length.nil? if index.kind_of? ::Range enum = ::Enumerator.new do |y| index.each do |i| y << self[i] end end ArrayPromise.new enum else __force_to__ index @array[index] end else enum = ::Enumerator.new do |y| i = index length.times do y << self[i] i += 1 end end ArrayPromise.new enum end end |
#__force_to__(index) ⇒ Object
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/laziest/array.rb', line 59 def __force_to__ index begin @mutex.synchronize do while @array.length <= index @array << @enumerator.next end end rescue ::StopIteration end end |
#__forced__? ⇒ Boolean
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/laziest/array.rb', line 70 def __forced__? if @nil_on_empty && @array.empty? # Check if we're really empty. __force_to__ 1 # Either we'll be empty (and finalized as nil), so we'll revert to # calling super which forwards to nil and so on, # or we'll be nonempty (and normal logic proceeds) end !(@result.equal?(NOT_SET) && @error.equal?(NOT_SET)) end |
#each(&block) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/laziest/array.rb', line 20 def each(&block) return super if __forced__? return ::Enumerator.new{|y| each {|x| y << x}}.lazy unless ::Kernel.block_given? index = 0 ::Kernel.loop do __force_to__ index break unless @array.length > index yield @array[index] index += 1 end end |
#to_a ⇒ Object
Except this one, make it a no-op. (Also should prevent infinite recursion.)
104 105 106 107 |
# File 'lib/laziest/array.rb', line 104 def to_a return super if __forced__? self end |