varT: The Variable Table¶
The Variable Table, commonly referred to as varT, is the component within Lmod responsible for managing all environment variable modifications. While the Module Table (MT) tracks the state of modules, the varT tracks the state of the environment itself. It is a table where each key is the name of an environment variable (e.g., PATH), and each value is a Var object, defined in src/Var.lua, that intelligently manages the variable’s state.
Like the MT, the varT is a core part of the state that is snapshotted by the FrameStk during module evaluation, providing the same crucial benefits of isolation, statefulness, and reversibility for environment variables.
The Var Object: An Intelligent Wrapper¶
Instead of manipulating environment variable strings directly, Lmod uses the Var object as a sophisticated wrapper. This object provides the logic to correctly handle the different kinds of environment variables.
Path-Like Variables¶
For variables like PATH, LD_LIBRARY_PATH, or MANPATH, the Var object treats the value as a delimited list of paths. It provides methods to manipulate this list correctly:
`Var:prepend(value, nodups, priority)`: Adds a new path to the beginning of the list. It can handle de-duplication policies (nodups) and assign a priority to the path, which influences its position relative to other priority-aware paths.
`Var:append(value, nodups, priority)`: Adds a new path to the end of the list.
`Var:remove(value, where, priority)`: Removes a path from the list. The where parameter can specify removing the “first”, “last”, or “all” occurrences.
`Var:expand()`: Reconstructs the final, correctly delimited string from its internal representation of the path list, ready to be exported to the shell environment.
This abstraction is powerful because it frees the modulefile author from worrying about path separators or complex de-duplication logic.
Scalar Variables¶
For simple key-value variables, the Var object provides straightforward methods:
`Var:set(value)`: Sets the variable to a specific string value.
`Var:unset()`: Unsets the variable.
Other Variable Types¶
The Var object also handles other special types of shell modifications, such as aliases (setAlias/unsetAlias) and shell functions (setShellFunction/unsetShellFunction), treating them as distinct types of variables to be managed.
How varT is Used in the Lmod Lifecycle¶
The varT is managed almost exclusively through the FrameStk. The standard lifecycle within src/MainControl.lua for any command that modifies the environment (like setenv, prepend_path, etc.) is as follows:
Get the Current State: The first step is always to retrieve the current varT from the top frame of the FrameStk: local varT = frameStk:varT()
Find or Create the `Var` Object: Lmod then looks up the Var object for the specified variable name. If one doesn’t exist (i.e., this is the first time the variable is being modified in the session), it creates a new one: if (varT[name] == nil) then varT[name] = Var:new(name) end
Apply the Modification: Lmod then calls the appropriate method on the Var object, passing in the arguments from the modulefile command: varT[name]:prepend(value, nodups, priority)
Automatic State Capture: Because this modification was made to the varT instance held by the current frame on the FrameStk, the change is automatically captured. It will be committed to the parent frame upon a successful pop or discarded upon a LmodBreak, just like the MT state.
When Lmod needs to generate the final shell script to be eval’d, it iterates through the final varT, calls the expand() method on each Var object, and generates the necessary export or unset commands.
Key Takeaways¶
Abstraction for Variables: varT is a table of Var objects, which provide an intelligent layer of abstraction over raw environment variables.
Handles Complexity: The Var object contains all the necessary logic for handling path manipulation, de-duplication, and priorities.
Integrated with `FrameStk`: varT is a core piece of the state managed by FrameStk, ensuring that all environment changes are atomic and reversible.
The “How” of Environment Changes: If the MT tracks what modules are loaded, the varT tracks how those modules have changed the shell environment.