class Rule
A rule is a function with a specific set of input and output parameters, which can match against a given set of specific arguments. For example, there might be several rules for compiling, but the specific rules depend on the language being compiled.
Nested
Definitions
def self.build(name, &block)
Build a frozen rule from a name and a definition block.
Signature
-
parameter
nameString The rule name in
"process.type"format.-
returns
Build::Rule The constructed and frozen rule.
Implementation
def self.build(name, &block)
rule = self.new(*name.split(".", 2))
rule.instance_eval(&block)
return rule.freeze
end
def initialize(process_name, type)
Initialize a rule with a process name and type.
Signature
-
parameter
process_nameString The process name, e.g.
"compile".-
parameter
typeString The file type, e.g.
"cpp".
Implementation
def initialize(process_name, type)
@name = process_name + "." + type
@full_name = @name.gsub(/[^\w]/, "_")
@process_name = process_name.gsub("-", "_").to_sym
@type = type
@apply = nil
@parameters = []
@primary_output = nil
end
attr :name
compile.cpp
attr :process_name
compile
attr :full_name
compile_cpp
def freeze
Freeze the rule and all its components.
Signature
-
returns
Build::Rule The frozen rule.
Implementation
def freeze
return self if frozen?
@name.freeze
@full_name.freeze
@process_name.freeze
@type.freeze
@apply.freeze
@parameters.freeze
@primary_output.freeze
super
end
def input(name, options = {}, &block)
Add an input parameter to the rule.
Signature
-
parameter
nameSymbol The parameter name.
-
parameter
optionsHash Parameter options.
Implementation
def input(name, options = {}, &block)
self << Parameter.new(:input, name, options, &block)
end
def parameter(name, options = {}, &block)
Add a generic argument parameter to the rule.
Signature
-
parameter
nameSymbol The parameter name.
-
parameter
optionsHash Parameter options.
Implementation
def parameter(name, options = {}, &block)
self << Parameter.new(:argument, name, options, &block)
end
def output(name, options = {}, &block)
Add an output parameter to the rule.
Signature
-
parameter
nameSymbol The parameter name.
-
parameter
optionsHash Parameter options.
Implementation
def output(name, options = {}, &block)
self << Parameter.new(:output, name, options, &block)
end
def <<(parameter)
Append a parameter to the rule.
Signature
-
parameter
parameterBuild::Rule::Parameter The parameter to add.
Implementation
def << parameter
@parameters << parameter
if parameter.output?
@primary_output ||= parameter
end
end
def applicable?(arguments)
Check if this rule can process these parameters
Implementation
def applicable?(arguments)
@parameters.each do |parameter|
next if parameter.implicit?
return false unless parameter.applicable?(arguments)
end
return true
end
def normalize(arguments, scope)
The scope is the context in which the dynamic rule computation is done, usually an instance of Task.
Implementation
def normalize(arguments, scope)
Hash[
@parameters.collect do |parameter|
[parameter.name, parameter.compute(arguments, scope)]
end
]
end
def files(arguments)
Derive the input and output file lists from the given arguments.
Signature
-
parameter
argumentsHash The argument set.
-
returns
Array(Build::Files::Composite, Build::Files::Composite) Input and output file composites.
Implementation
def files(arguments)
input_files = []
output_files = []
@parameters.each do |parameter|
# This could probably be improved a bit, we are assuming all parameters are file based:
value = arguments[parameter.name]
next unless value
case parameter.direction
when :input
input_files << value
when :output
output_files << value
end
end
return Build::Files::Composite.new(input_files), Build::Files::Composite.new(output_files)
end
def apply(&block)
Set the apply block that is executed when the rule is invoked.
Implementation
def apply(&block)
@apply = Proc.new(&block)
end
def apply!(scope, arguments)
Apply the rule in the given scope with the provided arguments.
Signature
-
parameter
scopeObject The task scope.
-
parameter
argumentsHash The normalised arguments.
Implementation
def apply!(scope, arguments)
scope.instance_exec(arguments, &@apply) if @apply
end
def result(arguments)
Signature
-
returns
Object | Nil The primary output value from the given arguments, if any.
Implementation
def result(arguments)
if @primary_output
arguments[@primary_output.name]
end
end
def hash
Signature
-
returns
Integer A hash value for this rule.
Implementation
def hash
[self.class, @name, @parameters].hash
end
def eql?(other)
Signature
-
returns
Boolean Whether this rule is equal to another by name and parameters.
Implementation
def eql?(other)
other.kind_of?(self.class) and @name.eql?(other.name) and @parameters.eql?(other.parameters)
end
def to_s
Signature
-
returns
String A human-readable representation of the rule.
Implementation
def to_s
"#<#{self.class} #{@name.dump}>"
end