OScript API/Built-in Package Index |
Frame provides two basic capabilities: structure and inheritance. The synergy between these two features, as well as their use within the Livelink Scripting Framework, provides developers with many powerful capabilities.
In its most basic form, a Frame consists of a set of named slots. Each slot can contain a single value and can be referenced with the dot operator. Thus, a Frame is the equivalent of a structure in most programming languages. A frame's slots are identified with a String and cannot be accidentally created (e.g., due to a typo) during an assignment. In addition, referencing a slot that does not exist will produce a runtime exception, rather than returning an Undefined value. There are operations in the Frame class that permit a Frame's structure to be examined and even modified.
In addition to the structuring mechanisms described above, Frame has the additional ability to have special slots, parent slots, which affect how slots are looked up within a Frame. A parent slot acts like a normal slot, except that it cannot be assigned to. In addition, when a Frame's slot is referenced with a dot operator (e.g., myFrame.someSlot), the presence of one or more parent slots can affect how and where the slot is used.
When a frame dot expression occurs on the left side of an assignment (i.e., an lvalue), then the following steps occur:
If the slot does not exist in the Frame, then the parent slots are searched in definition order for the specified slot name.
When a frame dot expression occurs in any other context where its value is desired (i.e., an rvalue), then the following steps occur:
If the slot does not exist in the Frame, then the parent slots are searched in definition order for the specified slot name.
In other words, Frame behaves as a prototype-based object (similar to OSpace's ObjRef datatype). Frame has the following advantages compared to ObjRef:
Frame has some shortcomings with respect to ObjRef:
If inheritance is ignored, both Frame and Assoc share certain features that make them amenable to being used to build structures within the OScript environment. Assoc values can have arbitrary keys of any datatype, whereas Frames must have named slots of type String. In addition, Assoc is most useful when the structure is extremely dynamic and where keys may need to be added at any time. Frame is more useful for safety and debugging because references to incorrectly typed slot names will be cause an error during testing and debugging, rather than continuing with possibly erroneous results. Of course, Assoc is also very useful when it is used for the purpose for which it was designed, as an Associative array. Assoc can efficiently map between arbitrary keys (of any datatype) and their associated values.
If a slot named "Destructor" is available on the Frame or its parents, and that slot's value is executable, then the slot will be invoked when the Frame is destroyed. Note that the Frame will still exist during the execution of Destructor(), and if the refcount of the Frame has increased during Destructor(), then the frame will NOT be deleted. Be careful with this feature.
Livelink values use a simple reference-counting scheme to determine when an unused value can be deleted. Powerful datatypes such as Assoc and Frame both share the unfortunate characteristic that it is possible to create cyclic data structures whose values can never be deleted automatically. Please be careful, as this can result in memory leaks and other even nastier side effects.
Here is an example of using Frame.New() to create a frame representing a 3D coordinate:
Frame coordinateProto = Frame.New( {}, { { "x", 0 }, { "y", 0 }, { "z", 0 } } ) Frame aCoordinate = Frame.New( { { "parentCoordinate", coordinateProto } }, \ { { "x", 5 } } ) echo( coordinateProto.x ) echo( coordinateProto.y ) echo( coordinateProto.z ) echo( aCoordinate.x ) aCoordinate.x = 55 echo( aCoordinate.x ) coordinateProto.x = 10 echo( aCoordinate.x ) coordinateProto.y = 10 echo( aCoordinate.y ) aCoordinate.y = 100 echo( aCoordinate.y ) echo( coordinateProto.zzzz ) // runtime error. feature not found exception.
The output from the above is:
0 0 0 5 55 55 // Changing the value of the proto slot doesn't change the child's slot 10 // Changing the value of the parent slot does change the child's inherited slot 100 // Child's override hides parent's value.
A constant indicating the datatype number of the datatype Frame.
Used with HasSlot to indicate that both the frame and its parents should be searched.
Used with HasSlot to indicate that only the frame should be searched.
Used with HasSlot to indicate that only the frame's parents should be searched.
Adds a parent definition to a Frame
Adds a non-parent slot of the specified name to the frame, optionally providing an initial value.
Determines whether a parent with the specified value exists.
Indicates whether a Frame has a slot with the specified name.
Creates a frame with the specified parents and slots.
Returns a List of parent definitions for the specified frame.
Removes the specified parent definition from a Frame.
Removes a slot from a frame.
Returns a List of Strings, corresponding to the names of the non-parent slots in theFrame.
Returns a List of non-parent slot descriptions.
A constant indicating the datatype number of the datatype Frame, such that, if Type( val ) == Frame.FrameType, then val is a Frame.
Used with Frame.HasSlot() to indicate that both the frame and its parents should be searched.
Used with Frame.HasSlot() to indicate that only the frame should be searched.
Used with Frame.HasSlot() to indicate that only the frame's parents should be searched.
Adds a parent to a frame.
Note that a parent slot cannot be added if a slot with the given name is already present on the Frame.
Frame to modify.
A List ({ slotName, parentValue }) specifying the parent slot.
TRUE if successful, FALSE otherwise.
Note that a parent slot cannot be added if a slot with the given name is already present on the Frame.
Adds a non-parent slot of the specified name to the frame, optionally providing an initial value.
Frame value to modify.
String name of the slot to add.
Initial value for the slot.
TRUE if the slot was added, FALSE if it failed.
Note that this function will do nothing if the slot already exists on the frame. In this case, it will return FALSE.
Determines whether a parent with the specified value exists.
Note that parentValue is not the slot name for the parent, but is the actual associated parent value.
Frame to examine.
Value of parent to look for.
TRUE if this frame has a parent slot with the specified value as its value. FALSE otherwise.
Note that parentValue is not the slot name for the parent, but is the actual associated parent value.
Returns true if a Frame has a slot with the specified name.
Frame within which to look for a slot.
Name of the slot for which to look.
If specified, Frame.kFrame, Frame.kParents, or the default Frame.kAnywhere.
TRUE if the slot was found. FALSE otherwise.
Using the above example frames, aCoordinate and coordinateProto:
echo( Frame.HasSlot( aCoordinate, "z" ) ) echo( Frame.HasSlot( aCoordinate, "z", Frame.kFrame ) ) echo( Frame.HasSlot( aCoordinate, "x", Frame.kParents ) ) echo( Frame.HasSlot( aCoordinate, "z", Frame.kAnywhere ) )
The output from the above is:
true false true true
Create a new frame with parent slots as specified in parentDefs and with instance slots as specified in instanceDefs.
A List of parent slot defs, each of which can consist of either a parent value or a List containing { parentSlotName, parentValue } .
A List of slot defs, each element of which is either a simple String slotName, or a List containing { slotName, slotValue } . See note below.
The newly created frame.
Note that both parentDefs and instanceDefs above can specify slot definitions as a List consisting of a slotName and a slotValue. However, both of these definition lists permit slot definitions to be specified in a simpler, defaulted form. In the case of parentDefs, a definition can consist of a single, non-List value. This value becomes associated with an unnamed parent slot. In the case of instanceDefs, a String can be specified instead of a List-based slot definition. In this case, the String will become the slot name. See the class description for an example.
Return a List of parent definitions for the specified frame.
Frame to examine.
A List of parent definitions, each of which is a two-element List containing { parentSlotName, parentValue } .
Using the above example frames, aCoordinate and coordinateProto:
echo( Frame.Parents( coordinateProto ) ) echo( Frame.Parents( aCoordinate ) )
The output from the above is:
{} {{'parentCoordinate',<LL:Frame>{{}x:10,y:10,z:0}</LL:Frame>}}
Removes the specified parent definition from a Frame.
This function does not remove the actual slot definition from the Frame, only the inheritance aspect. In order to remove the slot from the Frame, you must also use Frame.RemoveSlot().
Frame to modify.
A List ({ slotName, parentValue }) specifying the parent slot.
TRUE if successful, FALSE otherwise.
This function does not remove the actual slot definition from the Frame, only the inheritance aspect. In order to remove the slot from the Frame, you must also use Frame.RemoveSlot().
Removes a slot from a frame.
Frame from which to remove the slot.
Name of the slot to remove.
TRUE if successful, FALSE otherwise.
Note that this function will remove both parent slots and regular slots. However, when a parent slot is removed with this function, the parent will still be part of the Frame's prototype inheritance. In order to remove a parent from the Frame's inheritance, Frame.RemoveParent() must also be used.
Returns a List of Strings, corresponding to the names of the non-parent slots in theFrame.
The frame to examine.
See above.
Using the above example frames, aCoordinate and coordinateProto:
echo( Frame.SlotNames( coordinateProto ) ) echo( Frame.SlotNames( aCoordinate ) )
The output from the above is:
{'x','y','z'} {'x','y'}
Returns a List of non-parent slot descriptions. Each descriptions consists of a two-element List containing { slotName, slotValue }.
The frame to examine.
See above.
Using the above example frames, aCoordinate and coordinateProto:
echo( Frame.Slots( coordinateProto ) ) echo( Frame.Slots( aCoordinate ) )
The output from the above is:
{{'x',10},{'y',10},{'z',0}} {{'x',55},{'y',100}} // New or overridden slots are displayed.
Copyright © 2023 OpenText Corporation. All rights reserved. |