2.40 :set()
This method can set attributes of an object. It is predefined for all objects, Models and Defaults.
Furthermore, it is possible to overwrite this method and thus to extend the way attributes are set by further actions (e.g. consistency checks).
You can find the attributes available for the relevant object type in the “Object Reference”.
Definition
boolean :set ( attribute Attribute input, anyvalue Value input { , anyvalue Index input } { , boolean SendEvent := true input } )
Parameters
- attribute Attribute input
- This parameter informs the method which attribute shall be set.
- anyvalue Value input
- In this parameter, the new value for the attribute is passed.
- anyvalue Index input
- This optional parameter needs to be specified if an indexed attribute shall be set. Its data type must match the index data type of the attribute. Thus, if a one-dimensional attribute should be set, an integer value is expected here. However, if the attribute is two-dimensional, an index value has to be passed here.
- boolean SendEvent := true input
- This optional parameter controls whether a changed event should be sent or not when the attribute is successfully set. If no event should be sent, false must be passed here. The default value is true so an event will be sent if nothing is specified here.
Return value
- true
- The method returns true if setting the attribute has been successful.
- false
- If setting the attribute was refused (either by the IDM or the IDM programmer), false is returned.
Implicit Invocation
The :set() method is also invoked implicitly. When an attribute (predefined or user-defined) is changed from the Rule Language (by assignment with := respectively ::= or the built-in function setvalue()) or with an interface function (e.g. DM_SetValue()), the :set() method is called, which then actually sets the attribute. The method :set() is invoked in the middle
and does the actual assignment of the new value.
To redefine the :set() method it is sufficient to simply write the following at an object:
window W {
:set(<no parameters !>)
{
...
Actions to set an attribute.
...
}
}
Within the method definition, the parameters Attribute, Value, Index and SendEvent can be queried and set, in order to then call e.g. with this:super() the method :set() of the superclass with the accordingly changed parameters. However, changing the parameters such as Attribute and Index is not useful because such code would be difficult to understand.
Suppression of Recursive Calls
If within the method :set() any attribute of the same object for which the :set() method has already been called is set, then the method :set() should actually be invoked implicitly again for the same object. Since the danger of an infinite recursion is very high in this case, such a recursive call is suppressed.
Example
window {
:set()
{
case (Attribute)
in .title:
this.title := "<" + Value + ">";
// No implicit call of :set().
// Due to ":=" a "changed" event is sent .
// With "::=" the IDM programmer could also suppress this .
OtherObject.title := "<" + Value + ">";
// :set() of OtherObject is invoked .
// The SendEvent parameter of :set() is set to "true" .
otherwise:
this:super();
endcase
}
}
In this example, the :set() method monitors the setting of the window title and the title is enclosed in <>
brackets. During the assignment this.title := … the method :set() is not called again. However, the method :set() for another object will still be invoked.
Call of the :set() Method on the Superclass
The above example also shows how to use this:super(). All attributes for which the overwritten method :set() does not feel responsible should be delegated to the superclass, so that the predefined method :set() will set these attributes at some point.
The value of the Value parameter is always taken into account and assigned to the attribute at the end. The example above could therefore also be written like this:
Example
window {
:set()
{
if Attribute = .title then
Value := “<” + Value + “>”;
OtherObject.title := “<” + Value + “>”;
endif
this:super();
}
}
Enforcing Recursive Calls
If the method :set() should be called again for the same object with the changed values, the :recall() method can be used to enforce that the :set() method passed as parameter is also invoked recursively. Caution should be taken, however, as this can very easily lead to infinite recursions.
Example
dialog SET
model record MRec {
integer MaxCount:=100;
integer Count:=0;
:set()
{
variable boolean RetVal := true;
case (Attribute)
in .Count:
if this.MaxCount < Value then // Consistency check .
Value := this.MaxCount; // Correct Value.
endif;
RetVal := this:super();
in .MaxCount:
if this.MaxCount > Value then
this.MaxCount := Value;
this:recall(:set, .Count, Value);
// Set .Count to Value, calling :set() again.
RetVal := true;
else
RetVal := false; // Decline setting .
endif
otherwise:
RetVal := this:super();
endcase
return RetVal;
}
}
MRec Rec {
}
on dialog start {
print Rec.Count; // set value = 0
Rec.Count := 110;
print Rec.Count; // set value = 100
print Rec.MaxCount; // set value = 100
Rec.MaxCount := 200;
print Rec.MaxCount; // set value = 100
Rec.MaxCount := 10;
print Rec.MaxCount; // set value = 10
print Rec.Count; // set value = 10
exit();
}
See also
Built-in function setvalue() in manual “Rule Language”
C function DM_SetValue in manual “C Interface - Functions”