Important note: all examples follow aTbRef naming conventions.
In brief pre-summary, attributes are heavy-weight: persistent, accessible through the document, must be cleaned up if used for storing intermediate states during an action. Variables are light-weight: they can be defined as needed, they are destroyed (cleaned-up once the function has run) but only accessible within the current function.
In a function, any attribute reference, e.g.
$MyString, refers to an attribute in the calling note (i.e. the current item in a selection). It is still possible to refer to the same attribute in another note via an offset reference, e.g.
$MyString("SomeNote"). Or, designators may be used
$MyString(parent) gets the MyString value of the current item; in an alias, it is the alais' parent, or
$MyString(parent(original)) will get the value of the same attribute but from the parent of the alias.
If the function needs to store a lot of interim values, as in some string manipulation tasks, this can involve using quite a few attributes. It is no problem for Tinderbox to create additional user attributes, even if only for this task, buy if many are needed do consider variables as an alternative. Note that these attributes need to be created before the function is used. Attributes can be created via the Add Displayed Attributes configuration panel (attribute name and data type only), or the Document Inspector's User tab. Only the Inspector allows configuration of all aspects of a user attribute.
If using attributes consider:
- Attributes have global scope vs. local scope for variables. This means that once saved in an attribute, a value is available from any action in the document (albeit you may need to use an offset reference, where the code references $AttributeName(name or path of target note)). So:
- Attributes have permanence—they are integral to the document, and saved with it.
- Functions that reference attributes can interact with multiple notes located anywhere within the current document (via offset references).
- Attributes must be defined outside of the context of Action code and they must already exist in a document before they can be used.
- Using attributes causes the function to be dependent on the document and its structure, whereas variables are self-contained within the function.
To minimise the build up of forgotten data consider:
- clear attributes, once they have used, with a reset at the end of the function (though before the return, if used).
- use attributes within a single note, or perhaps a note per function if complex, so as to compartmentalise where stored data is generated.
Alternatively, consider action code variables, as described below
(Action code) Variables
Using action code variables within functions can help their use without needing to use any attributes, other than explicitly storing output results. Variables are created when defined and cease to exist (i.e including the data they store) when the action containing them, such as a function, has finished being run. So if a function declares a variable and stores data in it, that value is only accessible within the function _and_ once the function is run the values are lost forever.
Such use makes a function more self-contained, especially if planning to use the same function (or library of functions) in different Tinderbox documents. This is because the function creates/destroys variables as needed and there is no need for user attributes (see above) which might not (yet) have been created in the current document. Using variables avoids that extra set-up of configuring attributes.
Variables created within a function only work within the scope of that function, as discussed here.
Which approach is better?
…is the wrong question to ask! It is perfectly fine to use either, or a mix of both. Use whichever appeals and makes sense for the user's style of work. The choice will likely depend on a mix of personal style and the nature of use of the functions.
Next: Additional examples