Class: CML::LogicTree

Inherits:
Object
  • Object
show all
Defined in:
lib/cml/logic.rb,
lib/cml/logic_tree/graph.rb,
lib/cml/logic_tree/solver.rb

Overview

Build and calculate things based on some CML’s dependendency tree as dictated by ‘only-if` CML logic.

Defined Under Namespace

Classes: Graph, Node, Solver

Constant Summary collapse

DEPTH_LIMIT =
10

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parser) ⇒ LogicTree

Returns a new instance of LogicTree.



9
10
11
12
13
14
15
16
17
# File 'lib/cml/logic.rb', line 9

def initialize( parser )
  @parser = parser
  @errors = []
  # Hash of Node instances, keyed by tag names.
  @nodes = @parser.tags.inject( {} ) do |memo, tag|
    memo[tag.name] = Node.new( self, tag )
    memo
  end
end

Instance Attribute Details

#errorsObject (readonly)

Returns the value of attribute errors.



5
6
7
# File 'lib/cml/logic.rb', line 5

def errors
  @errors
end

#nodesObject (readonly)

Returns the value of attribute nodes.



5
6
7
# File 'lib/cml/logic.rb', line 5

def nodes
  @nodes
end

#parserObject (readonly)

Returns the value of attribute parser.



5
6
7
# File 'lib/cml/logic.rb', line 5

def parser
  @parser
end

#root_nodesObject (readonly)

Returns the value of attribute root_nodes.



5
6
7
# File 'lib/cml/logic.rb', line 5

def root_nodes
  @root_nodes
end

Instance Method Details

#depth(node, recurse_depth = 1) ⇒ Object

Recursively determine the depth of a Node based on logic. For example:

    A
   / \
  B   C
 / \
D   E

Which gives depths of:

A = 1
B, C = 2
D, E = 3

If we’ve recursed 10 times, we’re probably in a cycle, so we just return a max of 10 here.



35
36
37
38
39
40
# File 'lib/cml/logic.rb', line 35

def depth( node, recurse_depth = 1 )
  return 1 unless node.has_logic? && recurse_depth < DEPTH_LIMIT
  depth = 1 + node.depends_on.map do |depended_node|
    self.depth( depended_node, recurse_depth + 1 )
  end.max
end

#graphObject



74
75
76
77
# File 'lib/cml/logic.rb', line 74

def graph
  @graph ||= Graph.new(self)
  @graph.structure
end

#has_grouped_logic?Boolean

Returns:

  • (Boolean)


51
52
53
54
55
56
# File 'lib/cml/logic.rb', line 51

def has_grouped_logic?
  @nodes.values.any? {|node| node.has_grouped_logic? }
rescue CML::TagLogic::Error, CML::LogicTree::Graph::Error
  # When logic contains errors, return no grouping (maintains backwards compatibility)
  false
end

#has_liquid_logic?Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/cml/logic.rb', line 58

def has_liquid_logic?
  @nodes.values.any? {|node| node.has_liquid_logic? }
end

#max_depthObject



42
43
44
45
46
47
48
49
# File 'lib/cml/logic.rb', line 42

def max_depth
  @nodes.values.map do |node|
    node.depth
  end.max
rescue CML::TagLogic::Error, CML::LogicTree::Graph::Error
  # When logic contains errors, return depth of 1 (maintains backwards compatibility)
  1
end

#valid?Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
69
70
71
72
# File 'lib/cml/logic.rb', line 62

def valid?
  @errors = []
  graph
  true
rescue CML::TagLogic::Error, CML::LogicTree::Graph::Error => e
  @errors << e.message
  false
rescue
  @errors << "CML only-if logic cannot be parsed."
  false
end