Class: Candy::CandyArray

Inherits:
Object
  • Object
show all
Includes:
Crunch, Embeddable, Enumerable
Defined in:
lib/candy/array.rb

Overview

An array-like object that saves itself to a parent Candy::Piece object. MongoDB's atomic array operators are used extensively to perform concurrency-friendly updates of individual array elements without rewriting the whole array.

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Embeddable

#candy_adopt

Methods included from Crunch

#collection, #collection=, included

Constructor Details

- (CandyArray) initialize(*args)

Sets the initial array state.



21
22
23
24
# File 'lib/candy/array.rb', line 21

def initialize(*args)
  @__candy = from_candy(args)
  super()
end

Class Method Details

+ (Object) embed(parent, attribute, *args)

Creates the object with parent and attribute values set properly on the object and any children.



15
16
17
18
# File 'lib/candy/array.rb', line 15

def self.embed(parent, attribute, *args)
  this = self.new(*args)
  this.candy_adopt(parent, attribute)
end

Instance Method Details

- (Object) <<(val) Also known as: push

Appends a value to our array.



46
47
48
49
50
# File 'lib/candy/array.rb', line 46

def <<(val)
  property = candy_coat(@__candy_parent_key, val)
  @__candy_parent.operate :push, @__candy_parent_key => property
  self.candy << property
end

- (Object) ==(val)

Array equality.



74
75
76
# File 'lib/candy/array.rb', line 74

def ==(val)
  self.to_ary == val
end

- (Object) [](index)

Retrieves the value from our internal array.



36
37
38
# File 'lib/candy/array.rb', line 36

def [](index)
  candy[index]
end

- (Object) []=(index, val)

Set a value at a specified index in our array. Note that this operation _does not_ confirm that the array in Mongo still matches our current state. If concurrent updates have happened, you might end up overwriting something other than what you thought.



29
30
31
32
33
# File 'lib/candy/array.rb', line 29

def []=(index, val)
  property = candy_coat(nil, val)  # There are no attribute names on array inheritance
  @__candy_parent.set embedded(index => property)
  self.candy[index] = property
end

- (Object) candy Also known as: to_candy, to_ary

Returns the array of memoized values.



62
63
64
# File 'lib/candy/array.rb', line 62

def candy
  @__candy ||= []
end

- (Object) each(&block)

Iterates over each value in turn, so that we can have proper Enumerable support



41
42
43
# File 'lib/candy/array.rb', line 41

def each(&block)
  candy.each(&block)
end

- (Object) from_candy(array)

Unwraps all elements of the array, telling them who their parent is. The attribute doesn't matter because arrays don't have them.



69
70
71
# File 'lib/candy/array.rb', line 69

def from_candy(array)
  array.map {|element| Wrapper.unwrap(element, self)}
end

- (Object) length Also known as: size

Array length.



79
80
81
# File 'lib/candy/array.rb', line 79

def length
  self.to_ary.length
end

- (Object) shift(n = 1)

Pops the front off the MongoDB array and returns it, then resyncs the array. (Thus supporting real-time concurrency for queue-like behavior.)



55
56
57
58
59
# File 'lib/candy/array.rb', line 55

def shift(n=1)
  doc = @__candy_parent.collection.find_and_modify query: {"_id" => @__candy_parent.id}, update: {'$pop' => {@__candy_parent_key => -1}}, new: false
  @__candy = from_candy(doc[@__candy_parent_key.to_s])
  @__candy.shift
end