Knowing how to initialize properties, the question arises how they can
be accessed. As we already know, a cylinder of length
l
and radius
r
can be replaced by a cone of
the same length and radius by the rule
Cylinder(l, r) ==> Cone(l, r);
In this case, the properties length and radius of the cylinder
can be read quite easily.
But what if we want to set not only these properties,
but also the shader of the cone to
the shader of the cylinder? GroIMP does not provide the possibility
to write a pattern like Cylinder(l, r, s)
on the
left hand side of a rule where s
is linked to the
cylinder's shader. As with constructors, providing patterns for all possible
combinations of properties would not be feasible. However, there is
a solution to this problem which reads as follows:
x:Cylinder(l, r) ==> Cone(l, r).(setShader(x[shader]));
This rule contains two new features of the XL programming language:
A node pattern on the left hand side can be prefixed by an
identifier (and an additional colon inbetween)
in order to name the nodes which match the pattern during rule application.
This name is just the name of a local variable, so it can be used
to invoke methods on matching nodes, or to modify their contents.
The example uses the identifier x
to name
the cylinders which match the left hand side.
Properties can be accessed using a square bracket notation.
x[shader]
denotes a
property variable whose value is the shader
of cylinder x
.
The rule is integrated in the method swap
of
this example.
Click here to see how cylinders and cones are swapped,
thereby adopting size and colour of their predecessor.