| |
---|
| | .IP \(bu 4 |
---|
| | Variable names may not contain whitespace. |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | Variable names may not begin with \'$\'. The one exception |
---|
| | Variable names may not begin with the \'$\' character. The one exception |
---|
| | to this is when you are referencing the value of an environment |
---|
| | variable. |
---|
| | variable. References to environment variables begin with \'$\': |
---|
| | |
---|
| | .nf |
---|
| | # A reference to an environment variable is legal |
---|
| | x = [$TERM] |
---|
| | |
---|
| | # Attempting to create a new variable starting with \'$\' is illegal |
---|
| | $MYVAR = something |
---|
| | .fi |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | Variable names cannot have the \'#\' character anywhere in them |
---|
| | because \*(TC sees that character as the beginning a comment. |
---|
| |
---|
| | From that point forward until the namespace is changed again, every |
---|
| | variable assignment |
---|
| | .B and |
---|
| | reference is "relative" to the namespace. What this really means is |
---|
| | that \*(TC sticks the namspace plus a period in front of every |
---|
| | that \*(TC sticks the namspace plus a \'.\' in front of every |
---|
| | variable assigned or referenced. It does this automatically and |
---|
| | invisibly, so \'Brand\' is turned into \'MyCar.Brand\' and so on. You |
---|
| | can actually check this by loading the example above into a test |
---|
| | configuration file and running the \'test-tc\' program on it. You will |
---|
| |
---|
| | create the actual variable name that will be returned in the symbol |
---|
| | table. |
---|
| | |
---|
| | You're likely scratching your head wondering why on earth this |
---|
| | feature present in \*(TC. There are, in fact, several reasons for it: |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | |
---|
| | feature present in \*(TC. There are several good reasons for it: |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | It reduces typing repetetive information throughout the configuration |
---|
| | file. In turn, this reduces the likelyhood of a typographical or |
---|
| | spelling error. |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | |
---|
| | It helps visibly organize the configuration file. A namespace makes |
---|
| | it clear which variables are related to each other somehow. This is no |
---|
| | big deal in small configurations, but \*(TC was written with the idea |
---|
| | of supporting configuration files that might contain thousands or |
---|
| | even tens of thousands of entries. |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | |
---|
| | It simplifies the application programmer's job. Say I want to write a |
---|
| | program that extracts all the information about your car from the |
---|
| | configuration file, but I don't know ahead of time how many things you |
---|
| | will describe. All I really have to know is that you are using |
---|
| |
---|
| | and so on, you can do so later |
---|
| | .B and the program does not have to be rewritten. |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | |
---|
| | It helps enforce correct configuration files. By default, you can |
---|
| | introduce new namespaces into the configuration file any time you |
---|
| | like. However, as described in the previous section on the |
---|
| | \*(TC API, the application programmer can limit you to a pre-defined |
---|
| |
---|
| | incorrect configuration file entries by limiting just which |
---|
| | namespaces you can enter to reference or create variables. |
---|
| | |
---|
| | |
---|
| | .SS Lexical Namespace Specifics |
---|
| | .SS Rules For Using Lexical Namespace |
---|
| | |
---|
| | Creating and using lexical namespaces is fairly straightforward, |
---|
| | but there are a few restrictions and rules: |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | |
---|
| | The default initial namespace is the empty string, "". In this one case, |
---|
| | \*(TC does nothing to variables assigned or referenced. That's |
---|
| | why our early examples of how to assign a value to a variable and |
---|
| | then reference those value in the previous section worked. |
---|
| | When the namespace is "", nothing is done to the variable names. |
---|
| | The namespace, "", is also called the "root namespace." |
---|
| | The default initial namespace is the empty string, "". In this one |
---|
| | case, \*(TC does nothing to variables assigned or referenced. That's |
---|
| | why our early examples in the previous section worked. When we |
---|
| | assigned a value to a variable and then referenced that variable |
---|
| | value, we did so while in the so-called "root" namespace, "". When |
---|
| | the namespace is "", nothing is done to the variable names |
---|
| | |
---|
| | Bear in mind that the programmer can change this default namespace to |
---|
| | something other than "" before the configuration file is parsed. If |
---|
| | they do this, they would be well advised to let their users know this |
---|
| | fact. |
---|
| | something other than "" before the configuration file is ever |
---|
| | processed. If they do this, they would be well advised to let their |
---|
| | users know this fact. |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | There two ways to change to a new namespace: |
---|
| | |
---|
| | .nf |
---|
| | [NewNameSpace] # Must appear on a line by itself or with a comment only |
---|
| | OR |
---|
| | NAMESPACE = NewNamespace |
---|
| | .fi |
---|
| | |
---|
| | If, at any point, you want to return to the root namespace, you can use |
---|
| | one of these two methods: |
---|
| | |
---|
| | .nf |
---|
| | [] |
---|
| | OR |
---|
| | NAMESPACE = |
---|
| | .fi |
---|
| | |
---|
| | So, why are there two ways to do the same thing? |
---|
| | |
---|
| | |
---|
| | |
---|
| | |
---|
| | |
---|
| | In other words, \*(TC always prepends the current namespace (plus a |
---|
| | separating period) to any variable assignment or reference it finds in |
---|
| | a configuration. The one exception is when the namespace is "", in |
---|
| | which case \*(TC does not add anything to the variable names. |
---|
| | |
---|
| | By default, the initial namespace is always "", but you can change this |
---|
| | as desired. Note, however, that the programmer can change this default |
---|
| | initial namespace if they wish. Also there is a programming option |
---|
| | (\'AllowNewNamespaces\', described in the previous section) which can limit |
---|
| | you to using only the namespaces the programmer has pre-defined. i.e., You |
---|
| | will not be able to create |
---|
| | .B new |
---|
| | namespaces of your own invention. |
---|
| | |
---|
| | You can change to a new namespace anytime within the configuration file |
---|
| | a number of ways: |
---|
| | |
---|
| | |
---|
| | So how do you access variables in a namespace different than the one |
---|
| | you are in currently? |
---|
| | |
---|
| | |
---|
| | What's the point of all this namespace business anyway? |
---|
| | So, why are there two ways to do the same thing? The first way is the more |
---|
| | common, and the more readable way to do it. It appears on a line by itself and |
---|
| | makes it clear that the namespace is being changed. However, because variable |
---|
| | references cannot be "nested", you can only use strings of text here. |
---|
| | |
---|
| | Suppose you want to change the namespace in a way that depends on the |
---|
| | value of another variable. For instance: |
---|
| | |
---|
| | .nf |
---|
| | LOCATION = Timbuktu |
---|
| | NAMESPACE = [LOCATION]-East |
---|
| | .fi |
---|
| | |
---|
| | In other words, the second form of a namespace change allows you to |
---|
| | employ the \*(TC string substitution and variable referencing |
---|
| | features. Bear in mind that \*(TC is case-sensitive so this |
---|
| | will not work as you expect: |
---|
| | |
---|
| | .nf |
---|
| | Namespace = something |
---|
| | .fi |
---|
| | |
---|
| | This just set the value of the variable \'Namespace\' to |
---|
| | \'something\' and has nothing whatsoever to do with lexical |
---|
| | namespaces. |
---|
| | |
---|
| | This all works, by the way, because \'NAMESPACE\' is |
---|
| | nothing more than (yet) another variable in the symbol table. \*(TC |
---|
| | just understands that variable to be special - it treats it as the |
---|
| | repository of the current lexical namespace. |
---|
| | |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | |
---|
| | Whichever method you use to change it, |
---|
| | .B the new namespace cannot begin with \'$\'. |
---|
| | Both of the following will cause an error: |
---|
| | |
---|
| | .nf |
---|
| | [$FOO] |
---|
| | OR |
---|
| | x = $FOO |
---|
| | NAMESPACE = [x] |
---|
| | .fi |
---|
| | |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | By default, all variable assignments and references are |
---|
| | .B relative to the currently active namespace: |
---|
| | |
---|
| | .nf |
---|
| | [MyNameSpace] |
---|
| | |
---|
| | foo = 123 # Creates a variable called \'MyNameSpace.foo\' |
---|
| | x = bar # Means: \'MyNameSpace.x = MyNameSpace.bar\' |
---|
| | .fi |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | If you want to set or reference a variable in a namespace different |
---|
| | than the current namespace, you must use a so-called "absolute" |
---|
| | variable name. You do this by "escaping" the variable name. To escape the |
---|
| | name, begin it with a \'.\' and then use the |
---|
| | .B full name (including namespace) |
---|
| | of that variable. (This is called the "fully qualified variable |
---|
| | name".) For example: |
---|
| | |
---|
| | .nf |
---|
| | [NS1] # Switch to the namespace \'NS1\' |
---|
| | foo = 14 # Creates \'NS1.foo\' |
---|
| | |
---|
| | [NS2] # Switch to the \'NS2\' namespace |
---|
| | foo = [.NS1.foo] # Sets \'NS2.foo = 14\' |
---|
| | .fi |
---|
| | |
---|
| | There is another clever way to do this without using the escape |
---|
| | character. \*(TC has no understanding whatsoever of what a |
---|
| | lexical namespace actually is. It does nothing more than |
---|
| | "glue" the current namespace to any variable names and references |
---|
| | in your configuration file. Internally, all variables are |
---|
| | named |
---|
| | .B relative to the root namespace. |
---|
| | This means that you can use the fully qualified variable name |
---|
| | without any escape character any time you are in the root |
---|
| | namespace: |
---|
| | |
---|
| | .nf |
---|
| | [NS1] # Switch to the namespace \'NS1\' |
---|
| | foo = 14 # Creates \'NS1.foo\' |
---|
| | |
---|
| | [] # Switch to the root namespace |
---|
| | foo = [NS1.foo] # Sets \'foo = 14\' - no escape needed |
---|
| | .fi |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | \*(TC keeps track of every new namespace you create and returns that |
---|
| | list to the calling program to use as it wishes. (See the section |
---|
| | above entitled, |
---|
| | .B The Initial Symbol Table And Lexical Namespaces |
---|
| | for details.) |
---|
| | |
---|
| | |
---|
| | .SS Pre-Defined Variables |
---|
| | |
---|
| |
---|
| | |