class LazyArray
Attributes
head[R]
tail[R]
Public Class Methods
new()
click to toggle source
# File lib/extlib/lazy_array.rb, line 350 def initialize @frozen = false @loaded = false @load_with_proc = lambda { |v| v } @head = [] @tail = [] @array = [] @reapers = [] end
Public Instance Methods
<<(entry)
click to toggle source
# File lib/extlib/lazy_array.rb, line 171 def <<(entry) if loaded? lazy_load @array << entry else @tail << entry end self end
==(other)
click to toggle source
# File lib/extlib/lazy_array.rb, line 317 def ==(other) if equal?(other) return true end unless other.respond_to?(:to_ary) return false end # if necessary, convert to something that can be compared other = other.to_ary unless other.respond_to?(:[]) cmp?(other, :==) end
[](*args)
click to toggle source
# File lib/extlib/lazy_array.rb, line 102 def [](*args) index, length = extract_slice_arguments(*args) if length == 1 && args.size == 1 && args.first.kind_of?(Integer) return at(index) end if index >= 0 && lazy_possible?(@head, index + length) @head[*args] elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length) @tail[*args] else lazy_load @array[*args] end end
Also aliased as: slice
[]=(*args)
click to toggle source
# File lib/extlib/lazy_array.rb, line 134 def []=(*args) index, length = extract_slice_arguments(*args[0..-2]) if index >= 0 && lazy_possible?(@head, index + length) @head.[]=(*args) elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length) @tail.[]=(*args) else lazy_load @array.[]=(*args) end end
Also aliased as: splice
any?(&block)
click to toggle source
# File lib/extlib/lazy_array.rb, line 94 def any?(&block) (lazy_possible?(@tail) && @tail.any?(&block)) || (lazy_possible?(@head) && @head.any?(&block)) || begin lazy_load @array.any?(&block) end end
at(index)
click to toggle source
# File lib/extlib/lazy_array.rb, line 26 def at(index) if index >= 0 && lazy_possible?(@head, index + 1) @head.at(index) elsif index < 0 && lazy_possible?(@tail, index.abs) @tail.at(index) else lazy_load @array.at(index) end end
clear()
click to toggle source
# File lib/extlib/lazy_array.rb, line 270 def clear mark_loaded @array.clear self end
concat(other)
click to toggle source
# File lib/extlib/lazy_array.rb, line 181 def concat(other) if loaded? lazy_load @array.concat(other) else @tail.concat(other) end self end
delete_at(index)
click to toggle source
# File lib/extlib/lazy_array.rb, line 241 def delete_at(index) if index >= 0 && lazy_possible?(@head, index + 1) @head.delete_at(index) elsif index < 0 && lazy_possible?(@tail, index.abs) @tail.delete_at(index) else lazy_load @array.delete_at(index) end end
delete_if(&block)
click to toggle source
# File lib/extlib/lazy_array.rb, line 252 def delete_if(&block) if loaded? lazy_load @array.delete_if(&block) else @reapers << block @head.delete_if(&block) @tail.delete_if(&block) end self end
empty?()
click to toggle source
# File lib/extlib/lazy_array.rb, line 86 def empty? (@tail.nil? || @tail.empty?) && (@head.nil? || @head.empty?) && begin lazy_load @array.empty? end end
eql?(other)
click to toggle source
# File lib/extlib/lazy_array.rb, line 332 def eql?(other) if equal?(other) return true end unless other.class.equal?(self.class) return false end cmp?(other, :eql?) end
fetch(*args, &block)
click to toggle source
# File lib/extlib/lazy_array.rb, line 37 def fetch(*args, &block) index = args.first if index >= 0 && lazy_possible?(@head, index + 1) @head.fetch(*args, &block) elsif index < 0 && lazy_possible?(@tail, index.abs) @tail.fetch(*args, &block) else lazy_load @array.fetch(*args, &block) end end
first(*args)
click to toggle source
# File lib/extlib/lazy_array.rb, line 8 def first(*args) if lazy_possible?(@head, *args) @head.first(*args) else lazy_load @array.first(*args) end end
freeze()
click to toggle source
# File lib/extlib/lazy_array.rb, line 302 def freeze if loaded? @array.freeze else @head.freeze @tail.freeze end @frozen = true self end
frozen?()
click to toggle source
# File lib/extlib/lazy_array.rb, line 313 def frozen? @frozen == true end
include?(entry)
click to toggle source
# File lib/extlib/lazy_array.rb, line 78 def include?(entry) (lazy_possible?(@tail) && @tail.include?(entry)) || (lazy_possible?(@head) && @head.include?(entry)) || begin lazy_load @array.include?(entry) end end
index(entry)
click to toggle source
# File lib/extlib/lazy_array.rb, line 71 def index(entry) (lazy_possible?(@head) && @head.index(entry)) || begin lazy_load @array.index(entry) end end
insert(index, *entries)
click to toggle source
# File lib/extlib/lazy_array.rb, line 211 def insert(index, *entries) if index >= 0 && lazy_possible?(@head, index) @head.insert(index, *entries) elsif index < 0 && lazy_possible?(@tail, index.abs - 1) @tail.insert(index, *entries) else lazy_load @array.insert(index, *entries) end self end
kind_of?(klass)
click to toggle source
Calls superclass method
# File lib/extlib/lazy_array.rb, line 292 def kind_of?(klass) super || @array.kind_of?(klass) end
Also aliased as: is_a?
last(*args)
click to toggle source
# File lib/extlib/lazy_array.rb, line 17 def last(*args) if lazy_possible?(@tail, *args) @tail.last(*args) else lazy_load @array.last(*args) end end
lazy_possible?(list, need_length = 1)
click to toggle source
# File lib/extlib/lazy_array.rb, line 344 def lazy_possible?(list, need_length = 1) !loaded? && need_length <= list.size end
load_with(&block)
click to toggle source
# File lib/extlib/lazy_array.rb, line 283 def load_with(&block) @load_with_proc = block self end
loaded?()
click to toggle source
# File lib/extlib/lazy_array.rb, line 288 def loaded? @loaded == true end
pop(*args)
click to toggle source
# File lib/extlib/lazy_array.rb, line 223 def pop(*args) if lazy_possible?(@tail, *args) @tail.pop(*args) else lazy_load @array.pop(*args) end end
push(*entries)
click to toggle source
# File lib/extlib/lazy_array.rb, line 191 def push(*entries) if loaded? lazy_load @array.push(*entries) else @tail.push(*entries) end self end
replace(other)
click to toggle source
# File lib/extlib/lazy_array.rb, line 264 def replace(other) mark_loaded @array.replace(other) self end
respond_to?(method, include_private = false)
click to toggle source
Calls superclass method
# File lib/extlib/lazy_array.rb, line 298 def respond_to?(method, include_private = false) super || @array.respond_to?(method) end
reverse()
click to toggle source
# File lib/extlib/lazy_array.rb, line 149 def reverse dup.reverse! end
reverse!()
click to toggle source
# File lib/extlib/lazy_array.rb, line 153 def reverse! # reverse without kicking if possible if loaded? @array = @array.reverse else @head, @tail = @tail.reverse, @head.reverse proc = @load_with_proc @load_with_proc = lambda do |v| proc.call(v) v.instance_variable_get(:@array).reverse! end end self end
shift(*args)
click to toggle source
# File lib/extlib/lazy_array.rb, line 232 def shift(*args) if lazy_possible?(@head, *args) @head.shift(*args) else lazy_load @array.shift(*args) end end
slice!(*args)
click to toggle source
# File lib/extlib/lazy_array.rb, line 121 def slice!(*args) index, length = extract_slice_arguments(*args) if index >= 0 && lazy_possible?(@head, index + length) @head.slice!(*args) elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length) @tail.slice!(*args) else lazy_load @array.slice!(*args) end end
to_a()
click to toggle source
# File lib/extlib/lazy_array.rb, line 276 def to_a lazy_load @array.to_a end
Also aliased as: to_ary
unshift(*entries)
click to toggle source
# File lib/extlib/lazy_array.rb, line 201 def unshift(*entries) if loaded? lazy_load @array.unshift(*entries) else @head.unshift(*entries) end self end
values_at(*args)
click to toggle source
# File lib/extlib/lazy_array.rb, line 50 def values_at(*args) accumulator = [] lazy_possible = args.all? do |arg| index, length = extract_slice_arguments(arg) if index >= 0 && lazy_possible?(@head, index + length) accumulator.concat(head.values_at(*arg)) elsif index < 0 && lazy_possible?(@tail, index.abs) accumulator.concat(tail.values_at(*arg)) end end if lazy_possible accumulator else lazy_load @array.values_at(*args) end end
Private Instance Methods
cmp?(other, operator)
click to toggle source
# File lib/extlib/lazy_array.rb, line 432 def cmp?(other, operator) unless loaded? # compare the head against the beginning of other. start at index # 0 and incrementally compare each entry. if other is a LazyArray # this has a lesser likelyhood of triggering a lazy load 0.upto(@head.size - 1) do |i| return false unless @head[i].__send__(operator, other[i]) end # compare the tail against the end of other. start at index # -1 and decrementally compare each entry. if other is a LazyArray # this has a lesser likelyhood of triggering a lazy load -1.downto(@tail.size * -1) do |i| return false unless @tail[i].__send__(operator, other[i]) end lazy_load end @array.send(operator, other.to_ary) end
each() { |entry| ... }
click to toggle source
# File lib/extlib/lazy_array.rb, line 410 def each lazy_load if block_given? @array.each { |entry| yield entry } self else @array.each end end
extract_slice_arguments(*args)
click to toggle source
Extract arguments for slice an slice! and return index and length
@param [Integer, Array(Integer), Range] *args the index,
index and length, or range indicating first and last position
@return [Integer] the index @return [Integer,NilClass] the length, if any
@api private
# File lib/extlib/lazy_array.rb, line 391 def extract_slice_arguments(*args) first_arg, second_arg = args if args.size == 2 && first_arg.kind_of?(Integer) && second_arg.kind_of?(Integer) return first_arg, second_arg elsif args.size == 1 if first_arg.kind_of?(Integer) return first_arg, 1 elsif first_arg.kind_of?(Range) index = first_arg.first length = first_arg.last - index length += 1 unless first_arg.exclude_end? return index, length end end raise ArgumentError, "arguments may be 1 or 2 Integers, or 1 Range object, was: #{args.inspect}", caller(1) end
initialize_copy(original)
click to toggle source
# File lib/extlib/lazy_array.rb, line 360 def initialize_copy(original) @head = @head.try_dup @tail = @tail.try_dup @array = @array.try_dup end
lazy_load()
click to toggle source
# File lib/extlib/lazy_array.rb, line 366 def lazy_load return if loaded? mark_loaded @load_with_proc[self] @array.unshift(*@head) @array.concat(@tail) @head = @tail = nil @reapers.each { |r| @array.delete_if(&r) } if @reapers @array.freeze if frozen? end
mark_loaded()
click to toggle source
# File lib/extlib/lazy_array.rb, line 377 def mark_loaded @loaded = true end
method_missing(method, *args, &block)
click to toggle source
delegate any not-explicitly-handled methods to @array, if possible. this is handy for handling methods mixed-into Array like group_by
Calls superclass method
# File lib/extlib/lazy_array.rb, line 422 def method_missing(method, *args, &block) if @array.respond_to?(method) lazy_load results = @array.send(method, *args, &block) results.equal?(@array) ? self : results else super end end