Lesson 6 - Understanding Local Scopes (Localizing Containers)
As has been mentioned in previous Lessons, by default, all element names in a GoldSim model must be unique (i.e., they are “global” variables). For example, if you try to create two elements with the same name (e.g., X), you will see that GoldSim will not allow it:
This is because at some point you may reference the element in another element. If two elements had the same name, it would be ambiguous which element was being referenced.
Having said that, if indeed all element names were required to be unique in a GoldSim model, it would be very difficult and cumbersome to build large, complex models. For example:
- Imagine that it was decided to have one portion of the model built by one person (in one Container), and a second portion of the model built by another person (in a different Container). To do this, you would build the two Containers separately, and then copy them into one model (and connect them together appropriately). However, if all elements were global, you would need to ensure that none of the element names in one Container conflicted with any in the other Container. If these two Containers were large (hundreds or thousands of elements), this would be very difficult to avoid!
- Even if only one person was building the model, using unique names in a large model can be awkward. Many models have similar or parallel sub-systems (e.g., 5 different business units, 3 different ponds, 4 different locations) in which the various names for the elements in a sub-system should logically be the same (e.g., Revenues, Volume, etc.).
To get around these difficulties, all advanced programming languages provide an ability to create “local” variables (such that a variable can only be referenced within a specified “scope” or region of the model). GoldSim is no different: it provides the ability to create local variables, and hence build models which have elements with non-unique names.
To do this in GoldSim, we will use a special property of Containers to create local variables. To illustrate this, do the following:
- Start with a new model.
- Add a Data element named X (set it equal to 1).
- Now add a Container named C1.
- Enter C1 and add a Data element. Try to name it X. GoldSim will not allow you to do this, so instead name it Y. Set it equal to 2.
- Return to the top of the model.
- Now right-click on the Container C1. The context menu will look like this:
- Select Localize. When you do this, you will notice that the icon for the Container will change (it will go from a box to a box with a lid, and the arrow to enter the Container will change from blue to red):
- Now enter the Container again.
- Open the Data element Y and rename it X. You will see that GoldSim will now allow this!
This model now has two elements named X: one is at the top level of the model (and is global), and the other is inside Container C1 (and is local). How can this be? Why does it not cause ambiguity? The reason is that the X inside C1 has a limited scope. That is, because C1 has been localized, X can only be seen within C1. By default, it cannot be seen outside of C1.
The best way to understand this is to continue to experiment with this model. Return to the top of the model and do the following:
- Create an Expression named Z, and define it as 2 * X. You will notice that it links to the X at the top of the model.
- Now delete the X at the top of the model.
- Open Z and you will see that it displays an error (stating it cannot find X).
There still is an X in the model, but it cannot be seen by Z (since X is inside a local Container).
Now do the following:
- Enter C1.
- Create an Expression named Z, and define it as 2 * X. You will notice that it links to the X within C1.
So what should be apparent is that the X inside C1 can be “seen” by anything inside C1, but cannot be seen by anything outside C1. This is quite useful, as we can now build multiple localized Containers and do not need to be concerned with conflicting names.
Of course, if you can never reference anything within a localized Container from the outside, it would not be of much value. At some point, you will need to access variables within the localized Container. GoldSim allows you to do this by exposing outputs within a localized Container. Let’s do this now in the model we have been working with:
- Return to the top of the model.
- Add a Data element named X again. Define it as 1. So we now again have a global X and a local X in the model.
- Open Z. It is still defined as 2*X. We want to redefine it as the global X plus the local X (inside C1). In order to do this start to type the equation as “X +”. Then right click and select Insert Link… to insert an element. In the Insert Link browser, browse to the X inside C1 and select it.
- When you press OK, the following dialog will appear:
The dialog explains that in order to reference X outside of C1 it must be “exposed” on the Container.
- Press Yes and the equation will look like this:
The first X is the global X. Note that the X inside the localized Container, once it is exposed, is referenced as C1.X. That is, GoldSim allows you to propagate outputs outside of localized Containers by exposing them as if they were outputs of the localized Container itself. Once an output is exposed, it is referenced in expressions by using the form ContainerID.OutputID. There is no confusion with the other element named X in the model, since you must refer to the X that is in Container C1 as C1.X (not simply X). It is important to understand, however, that inside Container C1, you would access X in the normal way, by entering X directly in expressions.
Several additional points should be noted regarding localized Containers:
- Whenever you localize a Container, any outputs which are already referenced outside of the Container are automatically exposed.
- You can “globalize” a localized Container by right-clicking on it and selecting Globalize. Note, however, that if doing so would create a conflict, GoldSim will not allow it:
- If you copy and paste a global Container within the same scope, the Container will be pasted (with an underscore and a number after the ID), but it will be pasted as a localized Container (so that all of the contents do not need to be renamed):
- Localized Containers can be nested, so that a localized Container (referred to here as the parent) can itself contain a localized Container (referred to here as the child). In such a case, the scope of the parent localized Container does not extend into the child localized Container. That is, the parent can only “see” elements outside the child Container (unless they are exposed on the child).
- It was noted earlier in this Unit that in their simplest form, the use of Containers does not have any impact on how the model does its calculations. That is, if Containers are simply used to organize and structure models, where an element is within the model hierarchy has no impact on how the calculations are carried out (and hence the results that are computed). However, once Containers are localized this is no longer the case, since localization can affect which element is linked to. That is, the position of elements in the hierarchy controls who they will link to.
This Lesson simply provided the basics of creating and using localized Containers. Because this is such an important (and somewhat advanced) topic, you are strongly encouraged to read a more detailed description of localized Containers in GoldSim Help.