Record and Table Types
The Record Type
A record is an ad-hoc data structure having named properties and values.
One way to define a record is in line. The general form is:
{name=expression, name=expression, ... }
Each expression may resolve to a value of any type. (Only those resultant values are stored in the record.)
Here’s an example:
record rec = {x=0.7, y=Sqrt(100), color=Colors.Blue};
Alternatively, we can define an empty record structure, to be filled in later:
record rec = {x=, y=, color=};
Alternatively, we can construct a record programmatically:
record rec; rec.Add('x', 0.7); rec.Add('y', Sqrt(100)); string name = 'color'; color value = Colors.Blue; rec.Add(name, value);
Regardless of how it’s been created, we can use a record instance just like any other object that has properties:
Print(rec.y); // Prints "10". rec.color = Colors.Red;
The Table Type
A table is an associative collection of keys and values. In some other programming languages, this kind of collection is called a dictionary.
One way to define a table is in line. The general form is:
{[keyExpression]=valueExpression, [keyExpression]=valueExpression, … }
Note that each keyExpression is enclosed in square brackets. That's what distinguishes table-creation notation from record-creation notation.
Each keyExpression and valueExpression may resolve to a value of any type. (Only those resultant values are stored in the table.)
Here’s an example:
table tab = {[5]='five', [line01]=line01.Length, ['how now']='brown cow', [Sqrt(16)]=Series(1,10,1)}
Alternatively, we can construct a table programmatically:
table tab = {}; tab.Add(5, 'five'); tab.Add(line01, line01.Length); tab.Add('how now', 'brown cow'); double key = Sqrt(16); int[] value = Series(1,10,1); tab.Add(key, value);
Regardless of how it’s been created, you can use a table instance in the same way we would use a list, except that the index key can be any object rather than (necessarily) an integer:
Print(tab['how now']); // Prints "brown cow". Print(tab[4]}; // Prints "{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}". tab[line01] = point02.X;
One purpose of a table is to preserve a set of values so that they can be compared later. For example:
// Create and populate the table. global table lineLengths = {}; // Create an empty table. var lines = Nodes(n => n is Line); // Get all of the Line nodes in the GC model. foreach (line in lines) // Add the length of each line to the table, lineLengths.Add(line, line.Length); // keyed by the line, itself. // Do something that causes one or more lines to change. // Then, afterwards... foreach (line in table.Keys()) // Step through all of the keys in the table, which are { // (still) all of the Line nodes we're interested in. var diff = line.Length – lineLengths[line]; // If the line's length has changed, show if (diff != 0) // the difference in the script console.. PrintFormat("The length of {0} has changed by {1}.", line, diff); }
Another purpose of a table is to serve as a lookup/conversion table. For example:
global table casementSizes = { // Each key is a casement model number. Each value is a record // providing the height and width dimensions of that model. [1824]={height=2.0, width=1.5}, [1828]={height=2.4, width=1.5}, [1836]={height=3.0, width=1.5}, ... (etc.) ... };; // Subsequently, we might enter the following expression into the YTranslation property of // one of our Point nodes. (Imagine we also have an Expression node named "casementNumber".) casementSizes[casementNumber].Height
Interoperability Between Records and Tables
Records and tables are type-compatible. When a record is converted to a table, all of the record’s property names become string keys within the new table. When a table is converted to a record, only those table keys that are legal property names become properties within the new record; other items in the table are ignored.
Under the hood, a record is implemented as a special kind of table. Consequently, all records support the same methods as tables. For example, we can say:
record rec = { ... (something) ... }; double value = rec.GetItem('z', 0.0}; // GetItem is a table method. If the record "rec" includes // a property named "z", that property's value is returned. // Otherwise, the given default value, 0.0, is returned.