Class: Ward::ContextChain

Inherits:
Object
  • Object
show all
Defined in:
lib/ward/context_chain.rb

Overview

ContextChain combines one or more Context instances in order to be able to retrieve values from composed objects.

For example, if the chain contains two contexts, the first with a length attribute, and the second with a to_s attribute, the chain would resolve to calling target.length.to_s in order to retrieve a value for validation.

Instance Method Summary collapse

Constructor Details

#initializeContextChain

Creates a new ContextChain instance.



14
15
16
# File 'lib/ward/context_chain.rb', line 14

def initialize
  @contexts = []
end

Instance Method Details

#attributeSymbol

Returns the name of the attribute to be validated.

Returns the attribute for the first context. If the chain is empty, :base is always returned.

Returns:

  • (Symbol)

See Also:



27
28
29
# File 'lib/ward/context_chain.rb', line 27

def attribute
  @contexts.empty? ? :base : @contexts.first.attribute
end

#natural_nameString

Returns the ‘natural name’ of the contained contexts.

Returns:

  • (String)

See Also:



37
38
39
# File 'lib/ward/context_chain.rb', line 37

def natural_name
  @contexts.map { |context| context.natural_name }.join(' ')
end

#push(context) ⇒ Object Also known as: <<

Adds a new context to the end of the chain.

Parameters:

  • context (Ward::Context)

    The context to be added to the chain.



80
81
82
# File 'lib/ward/context_chain.rb', line 80

def push(context)
  @contexts << context
end

#to_aArray<Ward::Context>

Returns the contexts contained in the chain as an Array.

Returns:



71
72
73
# File 'lib/ward/context_chain.rb', line 71

def to_a
  @contexts.dup
end

#value(target) ⇒ Object

Returns the value of the chain for the given target object.

Parameters:

  • target (Object)

    The object from which the value is to be retrieved.

Returns:

  • (Object)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ward/context_chain.rb', line 48

def value(target)
  if @contexts.size > 1
    resolved = @contexts[0..-2].inject(target) do |intermediate, context|
      context.value(intermediate) unless intermediate.nil?
    end

    raise ArgumentError,
      "Couldn't retrieve a value for #{natural_name.downcase}; " \
      "something along the way evaluated to nil" if resolved.nil?

    @contexts.last.value(resolved)
  elsif @contexts.size == 1
    @contexts.first.value(target)
  else
    target
  end
end