Class: Accessory::BoundLens

Inherits:
Object
  • Object
show all
Includes:
Access::FluentHelpers
Defined in:
lib/accessory/bound_lens.rb,
lib/accessory/access.rb

Overview

A BoundLens represents a Lens bound to a specified subject document. See Lens for the general theory.

A BoundLens can be used to traverse its subject document, using #get_in, #put_in, #pop_in, etc.

Ordinarily, you don’t create and hold onto a BoundLens, but rather you will temporarily create Lenses in method-call chains when doing traversals.

It may sometimes be useful to create a collection of Lenses and then “build them up” by extending their Lenses over various collection-passes, rather than building up Lenses and only binding them to subjects at the end.

Lenses are created frozen. Methods that “extend” a BoundLens actually create and return new derived Lenses.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Access::FluentHelpers

#[], #after_last, #all, #attr, #before_first, #between_each, #betwixt, #filter, #first, #ivar, #last, #subscript

Instance Attribute Details

#lensLens (readonly)

Returns the Lens for this BoundLens.

Returns:

  • (Lens)

    the Lens for this BoundLens



63
64
65
# File 'lib/accessory/bound_lens.rb', line 63

def lens
  @lens
end

#subjectLens (readonly)

Returns the subject this BoundLens will traverse.

Returns:

  • (Lens)

    the subject this BoundLens will traverse



60
61
62
# File 'lib/accessory/bound_lens.rb', line 60

def subject
  @subject
end

Class Method Details

.on(subject, lens) ⇒ Object .on(subject, *accessors) ⇒ Object

Creates a BoundLens that will traverse subject.

Overloads:

  • .on(subject, lens) ⇒ Object

    Creates a BoundLens that will traverse subject along lens.

    Parameters:

    • subject (Object)

      the data-structure this BoundLens will traverse

    • lens (Lens)

      the Lens that will be used to traverse subject

  • .on(subject, *accessors) ⇒ Object

    Creates a BoundLens that will traverse subject using a Lens built from accessors.

    Parameters:

    • subject (Object)

      the data-structure this BoundLens will traverse

    • accessors (Array)

      the accessors for the new Lens



38
39
40
41
42
43
44
45
46
47
# File 'lib/accessory/bound_lens.rb', line 38

def self.on(subject, *accessors)
  lens =
    if accessors.length == 1 && accessors[0].kind_of?(Lens)
      accessors[0]
    else
      Accessory::Lens[*accessors]
    end

  self.new(subject, lens).freeze
end

Instance Method Details

#+(other) ⇒ Lens Also known as: /

Returns a new BoundLens resulting from concatenating other to the receiver’s Lens.

See also:

Parameters:

  • other (Object)

    an accessor, an Array of accessors, or a Lens

Returns:

  • (Lens)

    the new BoundLens, containing a new joined Lens



94
95
96
97
98
99
100
# File 'lib/accessory/bound_lens.rb', line 94

def +(other)
  d = self.dup
  d.instance_eval do
    @lens = @lens + other
  end
  d.freeze
end

#get_and_update_in(&mutator_fn) ⇒ Array

Traverses subject using the chain of accessors held in this Lens, modifying the final value at the end of the traversal chain using the passed mutator_fn, and returning the original targeted value(s) pre-modification.

mutator_fn must return one of two data “shapes”:

  • a two-element Array, representing:

    1. the value to surface as the “get” value of the traversal

    2. the new value to replace at the traversal-position

  • the Symbol :pop — which will remove the value from its parent, and return it as-is.

Equivalent in Elixir: Kernel.get_and_update_in/3

Parameters:

  • subject (Object)

    the data-structure to traverse

  • mutator_fn (Proc)

    a block taking the original value derived from traversing subject, and returning a modification operation.

Returns:

  • (Array)

    a two-element Array, consisting of

    1. the old value(s) found after all traversals, and

    2. the updated subject



110
111
112
# File 'lib/accessory/bound_lens.rb', line 110

def get_and_update_in(&mutator_fn)
  @lens.get_and_update_in(@subject, &mutator_fn)
end

#get_inObject

Traverses subject using the chain of accessors held in this Lens, returning the discovered value.

Equivalent in Elixir: Kernel.get_in/2

Returns:

  • (Object)

    the value found after all traversals.



105
106
107
# File 'lib/accessory/bound_lens.rb', line 105

def get_in
  @lens.get_in(@subject)
end

#pop_inObject

Traverses subject using the chain of accessors held in this Lens, removing the final value at the end of the traversal chain from its position within its parent container.

Equivalent in Elixir: Kernel.pop_in/2

Parameters:

  • subject (Object)

    the data-structure to traverse

Returns:

  • (Object)

    the updated subject



125
126
127
# File 'lib/accessory/bound_lens.rb', line 125

def pop_in
  @lens.pop_in(@subject)
end

#put_in(new_value) ⇒ Object

Traverses subject using the chain of accessors held in this Lens, replacing the final value at the end of the traversal chain with new_value.

Equivalent in Elixir: Kernel.put_in/3

Parameters:

  • subject (Object)

    the data-structure to traverse

  • new_value (Object)

    a replacement value at the traversal position.

Returns:

  • (Object)

    the updated subject



120
121
122
# File 'lib/accessory/bound_lens.rb', line 120

def put_in(new_value)
  @lens.put_in(@subject, new_value)
end

#then(accessor) ⇒ Lens

Returns a new BoundLens resulting from appending accessor to the receiver’s Lens.

See also:

Parameters:

  • accessor (Object)

    the accessor to append

Returns:

  • (Lens)

    the new BoundLens, containing a new joined Lens



78
79
80
81
82
83
84
# File 'lib/accessory/bound_lens.rb', line 78

def then(accessor)
  d = self.dup
  d.instance_eval do
    @lens = @lens.then(accessor)
  end
  d.freeze
end

#update_in(&new_value_fn) ⇒ Array

Traverses subject using the chain of accessors held in this Lens, replacing the final value at the end of the traversal chain with the result from the passed new_value_fn.

Equivalent in Elixir: Kernel.update_in/3

Parameters:

  • subject (Object)

    the data-structure to traverse

  • new_value_fn (Proc)

    a block taking the original value derived from traversing subject, and returning a replacement value.

Returns:

  • (Array)

    a two-element Array, consisting of

    1. the old value(s) found after all traversals, and

    2. the updated subject



115
116
117
# File 'lib/accessory/bound_lens.rb', line 115

def update_in(&new_value_fn)
  @lens.update_in(@subject, &new_value_fn)
end