class Rulebook
Represents a collection of rules, organized by process name for fast lookup.
Definitions
def initialize(name = nil)
Initialize the rulebook.
Signature
-
parameter
nameString | Nil An optional name for this rulebook.
Implementation
def initialize(name = nil)
@name = name
@rules = {}
@processes = {}
end
def <<(rule)
Add a rule to this rulebook.
Signature
-
parameter
ruleBuild::Rule The rule to add.
Implementation
def << rule
@rules[rule.name] = rule
# A cache for fast process/file-type lookup:
processes = @processes[rule.process_name] ||= []
processes << rule
end
def [](name)
Look up a rule by its full name.
Signature
-
parameter
nameString The rule name, e.g.
"compile.cpp".-
returns
Build::Rule | Nil The matching rule, or
nil.
Implementation
def [] name
@rules[name]
end
def with(superclass, **state)
Generate a task subclass with methods for all rules in this rulebook.
Signature
-
parameter
superclassClass The base task class to inherit from.
-
parameter
stateHash Additional state methods to define on the subclass.
-
returns
Class The generated task subclass.
Implementation
def with(superclass, **state)
task_class = Class.new(superclass)
# name = @name
# task_class.send(:define_method, :to_s) do
# "name"
# end
# Define methods for all processes, e.g. task_class#compile
@processes.each do |key, rules|
# Define general rules, which use rule applicability for disambiguation:
task_class.send(:define_method, key) do |arguments, &block|
rule = rules.find{|rule| rule.applicable? arguments}
if rule
invoke_rule(rule, arguments, &block)
else
raise NoApplicableRule.new(key, arguments)
end
end
end
# Define methods for all rules, e.g. task_class#compile_cpp
@rules.each do |key, rule|
task_class.send(:define_method, rule.full_name) do |arguments, &block|
invoke_rule(rule, arguments, &block)
end
end
# Typically, this defines methods like #environment and #target which can be accessed in the build rule.
state.each do |key, value|
task_class.send(:define_method, key) do
value
end
end
return task_class
end
def self.for(environment)
Build a rulebook from all rule definitions in the given environment.
Signature
-
parameter
environmentBuild::Environment The environment to extract rules from.
-
returns
Build::Rulebook The populated rulebook.
Implementation
def self.for(environment)
rulebook = self.new(environment.name)
environment.defined.each do |name, define|
rulebook << define.klass.build(name, &define.block)
end
return rulebook
end