Class: LazyArray

Inherits:
Object show all
Defined in:
lib/extlib/lazy_array.rb

Overview

borrowed partially from StrokeDB

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (private)

delegate any not-explicitly-handled methods to @array, if possible. this is handy for handling methods mixed-into Array like group_by



416
417
418
419
420
421
422
423
424
# File 'lib/extlib/lazy_array.rb', line 416

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

Instance Method Details

#<<(entry) ⇒ Object Also known as: add



163
164
165
166
167
168
169
170
171
# File 'lib/extlib/lazy_array.rb', line 163

def <<(entry)
  if loaded?
    lazy_load
    @array << entry
  else
    @tail << entry
  end
  self
end

#==(other) ⇒ Object



311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/extlib/lazy_array.rb', line 311

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) ⇒ Object Also known as: slice



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/extlib/lazy_array.rb', line 94

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

#[]=(*args) ⇒ Object Also known as: splice



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/extlib/lazy_array.rb', line 126

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

#any?(&block) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
89
90
91
92
# File 'lib/extlib/lazy_array.rb', line 86

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) ⇒ Object



22
23
24
25
26
27
28
29
30
31
# File 'lib/extlib/lazy_array.rb', line 22

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

#clearObject



264
265
266
267
268
# File 'lib/extlib/lazy_array.rb', line 264

def clear
  mark_loaded
  @array.clear
  self
end

#concat(other) ⇒ Object



175
176
177
178
179
180
181
182
183
# File 'lib/extlib/lazy_array.rb', line 175

def concat(other)
  if loaded?
    lazy_load
    @array.concat(other)
  else
    @tail.concat(other)
  end
  self
end

#delete_at(index) ⇒ Object



235
236
237
238
239
240
241
242
243
244
# File 'lib/extlib/lazy_array.rb', line 235

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) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
# File 'lib/extlib/lazy_array.rb', line 246

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?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/extlib/lazy_array.rb', line 82

def empty?
  !any?
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


326
327
328
329
330
331
332
333
334
335
336
# File 'lib/extlib/lazy_array.rb', line 326

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) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/extlib/lazy_array.rb', line 33

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) ⇒ Object



4
5
6
7
8
9
10
11
# File 'lib/extlib/lazy_array.rb', line 4

def first(*args)
  if lazy_possible?(@head, *args)
    @head.first(*args)
  else
    lazy_load
    @array.first(*args)
  end
end

#freezeObject



296
297
298
299
300
301
302
303
304
305
# File 'lib/extlib/lazy_array.rb', line 296

def freeze
  if loaded?
    @array.freeze
  else
    @head.freeze
    @tail.freeze
  end
  @frozen = true
  self
end

#frozen?Boolean

Returns:

  • (Boolean)


307
308
309
# File 'lib/extlib/lazy_array.rb', line 307

def frozen?
  @frozen == true
end

#include?(entry) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
# File 'lib/extlib/lazy_array.rb', line 74

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) ⇒ Object



67
68
69
70
71
72
# File 'lib/extlib/lazy_array.rb', line 67

def index(entry)
  (lazy_possible?(@head) && @head.index(entry)) || begin
    lazy_load
    @array.index(entry)
  end
end

#insert(index, *entries) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
# File 'lib/extlib/lazy_array.rb', line 205

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) ⇒ Boolean Also known as: is_a?

Returns:

  • (Boolean)


286
287
288
# File 'lib/extlib/lazy_array.rb', line 286

def kind_of?(klass)
  super || @array.kind_of?(klass)
end

#last(*args) ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/extlib/lazy_array.rb', line 13

def last(*args)
  if lazy_possible?(@tail, *args)
    @tail.last(*args)
  else
    lazy_load
    @array.last(*args)
  end
end

#load_with(&block) ⇒ Object



277
278
279
280
# File 'lib/extlib/lazy_array.rb', line 277

def load_with(&block)
  @load_with_proc = block
  self
end

#loaded?Boolean

Returns:

  • (Boolean)


282
283
284
# File 'lib/extlib/lazy_array.rb', line 282

def loaded?
  @loaded == true
end

#popObject



217
218
219
220
221
222
223
224
# File 'lib/extlib/lazy_array.rb', line 217

def pop
  if lazy_possible?(@tail)
    @tail.pop
  else
    lazy_load
    @array.pop
  end
end

#push(*entries) ⇒ Object



185
186
187
188
189
190
191
192
193
# File 'lib/extlib/lazy_array.rb', line 185

def push(*entries)
  if loaded?
    lazy_load
    @array.push(*entries)
  else
    @tail.push(*entries)
  end
  self
end

#replace(other) ⇒ Object



258
259
260
261
262
# File 'lib/extlib/lazy_array.rb', line 258

def replace(other)
  mark_loaded
  @array.replace(other)
  self
end

#respond_to?(method, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


292
293
294
# File 'lib/extlib/lazy_array.rb', line 292

def respond_to?(method, include_private = false)
  super || @array.respond_to?(method)
end

#reverseObject



141
142
143
# File 'lib/extlib/lazy_array.rb', line 141

def reverse
  dup.reverse!
end

#reverse!Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/extlib/lazy_array.rb', line 145

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

#shiftObject



226
227
228
229
230
231
232
233
# File 'lib/extlib/lazy_array.rb', line 226

def shift
  if lazy_possible?(@head)
    @head.shift
  else
    lazy_load
    @array.shift
  end
end

#slice!(*args) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/extlib/lazy_array.rb', line 113

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_aObject Also known as: to_ary



270
271
272
273
# File 'lib/extlib/lazy_array.rb', line 270

def to_a
  lazy_load
  @array.to_a
end

#unshift(*entries) ⇒ Object



195
196
197
198
199
200
201
202
203
# File 'lib/extlib/lazy_array.rb', line 195

def unshift(*entries)
  if loaded?
    lazy_load
    @array.unshift(*entries)
  else
    @head.unshift(*entries)
  end
  self
end

#values_at(*args) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/extlib/lazy_array.rb', line 46

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