trait¶
A trait
is a named collection of related attibutes ( fields ).
Traits are not intended to hold data, but simply model a group of fields.
Container UDTs such as entity
, key
, record
, and union
can use traits by using the includes
keyword.
Multiple assertAll blocks can be specified to perform validation. Asserts defined as part of a trait will be part of asserts in definitions that include the trait.
trait Shape {
Colour : string
}
record Rectangle includes Shape {
Width : int
Height : int
}
record Circle includes Shape {
Radius : int
}
By includes
of Shape, Rectangle and Circle will contain the Colour attribute.
Traits can be used extensively to model UDTs with common attributes, or as simply a marker.
trait Datasource {
}
record File includes Datasource {
Name : string
}
record Database includes Datasource {
ConnString : string
}
A trait can include one or many traits.
trait HealthFacts {
CalorieCount : int
}
trait FoodItem {
ExpiryDate : date
}
trait FrozenFood {
StorageTemperature : int
}
record FrozenPizza includes HealthFacts, FoodItem, FrozenFood {
Toppings : list< string >
}
When combining traits in this way fields get aggregated, so FrozenPizza
will contain 4 fields.
Diamond-shaped Dependencies
Consider the following change on the declaration above.
trait FrozenFood includes HealthFacts {
StorageTemperature : int
}
By doing so, FrozenPizza
has 2 possible paths to the CalorieCount
field - via FrozenFood
and
direct.
ALFA emits a warning message when diamond-shaped dependency cases are encountered, however it will
continue with a single CalorieCount
field and it is not considered an error. In order to stop the
warning, the field can be explicitly declared in the base of the diamond types - FrozenPizza
in the example.
Multiple assertAll blocks can be specified to perform validation.