Class: Babl::Builder::ChainBuilder
- Inherits:
-
Object
- Object
- Babl::Builder::ChainBuilder
- Defined in:
- lib/babl/builder/chain_builder.rb
Overview
Builder provides a simple framework for defining & chaining BABL’s operators easily.
Compiling a template is a multi-phase process:
1- [BABL => ChainBuilder] Template definition (via Builder#construct_node & Builder#construct_terminal) :
The operator chain is created by wrapping blocks (current block stored in 'scope')
2- [Builder => BoundOperator] Template binding (via Builder#bind) :
A BoundOperator is created for each operator and passed to the next, in left-to-right
order. This step is necessary to propagate context from root to leaves. A typical
use-case is the 'enter' operator, which requires the parent context in which it is called.
3- [BoundOperator => Node] Node precompilation (via Builder#precompile):
BoundOperators are transformed into a Node tree, in right-to-left order. Each node
contains its own rendering logic, dependency tracking & documentation generator.
4- [Node => CompiledTemplate] Compilation output: (via Template#compile):
The resulting Node is used to compute the dependencies & generate the documentation.
Finally, we pack everything is a CompiledTemplate which is exposed to the user.
Instance Method Summary collapse
- #bind(bound) ⇒ Object
-
#construct_node(**new_context) ⇒ Object
Append an operator to the chain, and return a new Builder object.
-
#construct_terminal ⇒ Object
Append a terminal operator, and return a new Builder object.
-
#initialize(&block) ⇒ ChainBuilder
constructor
A new instance of ChainBuilder.
- #precompile(node, **context) ⇒ Object
- #wrap ⇒ Object
Constructor Details
#initialize(&block) ⇒ ChainBuilder
Returns a new instance of ChainBuilder.
28 29 30 |
# File 'lib/babl/builder/chain_builder.rb', line 28 def initialize(&block) @scope = block end |
Instance Method Details
#bind(bound) ⇒ Object
36 37 38 |
# File 'lib/babl/builder/chain_builder.rb', line 36 def bind(bound) @scope[bound] end |
#construct_node(**new_context) ⇒ Object
Append an operator to the chain, and return a new Builder object
51 52 53 54 55 56 57 |
# File 'lib/babl/builder/chain_builder.rb', line 51 def construct_node(**new_context) wrap { |bound| bound.nest(bound.context.merge(new_context)) { |node| yield(node, bound.context) } } end |
#construct_terminal ⇒ Object
Append a terminal operator, and return a new Builder object
41 42 43 44 45 46 47 48 |
# File 'lib/babl/builder/chain_builder.rb', line 41 def construct_terminal construct_node do |node, context| unless [Nodes::InternalValue.instance, Nodes::TerminalValue.instance].include?(node) raise Errors::InvalidTemplate, 'Chaining is not allowed after a terminal operator' end yield context end end |
#precompile(node, **context) ⇒ Object
32 33 34 |
# File 'lib/babl/builder/chain_builder.rb', line 32 def precompile(node, **context) bind(BoundOperator.new(context)).precompile(node) end |
#wrap ⇒ Object
59 60 61 |
# File 'lib/babl/builder/chain_builder.rb', line 59 def wrap self.class.new { |bound| yield bind(bound) } end |