Global and nonlocal statements#
Code Example
Runnable Example in Jac and JacLib
# Global and Nonlocal Statements
glob x = "global x";
glob a = 1 , b = 2;
def test_global {
# Global with single name
global x;
x = "modified global x";
print(x);
}
def test_multiple_globals {
# Global with multiple names
global a,b;
a = 10;
b = 20;
print(f"{a} {b}");
}
def outer {
y = "outer y";
def inner {
# Nonlocal with single name
nonlocal y ;
y = "modified by inner";
print(y);
}
print(y);
inner();
print(y);
}
def outer_multi {
p = 1;
q = 2;
r = 3;
def inner_multi {
# Nonlocal with multiple names
nonlocal p , q , r ;
p = 10;
q = 20;
r = 30;
}
print(f"{p} {q} {r}");
inner_multi();
print(f"{p} {q} {r}");
}
with entry {
print(x);
test_global();
print(x);
print(f"{a} {b}");
test_multiple_globals();
print(f"{a} {b}");
outer();
outer_multi();
}
Jac Grammar Snippet
Description
Global and Nonlocal Statements
The global and nonlocal statements control variable scope, allowing functions to modify variables from outer scopes rather than creating local shadows.
Module-Level Global Variables
Lines 3-4 declare module-level global variables. These variables exist at module scope and are accessible throughout the module.
Global Statement - Single Variable
Lines 6-11 demonstrate the global statement. Line 8: global x declares that x refers to the module-level global variable (line 3). Without this statement, line 9's assignment would create a new local variable instead of modifying the global.
Global Statement - Multiple Variables
Lines 13-19 show declaring multiple global variables. Line 15: global a, b is more concise than separate global statements for each variable.
Nonlocal Statement - Single Variable
Lines 21-34 demonstrate the nonlocal statement for nested functions. Line 26: nonlocal y declares that y refers to the enclosing function's variable (line 22), not a global or new local. Line 27's assignment modifies the outer function's y.
Nonlocal Statement - Multiple Variables
Lines 36-52 show declaring multiple nonlocal variables. Line 43: nonlocal p, q, r modifies all three variables from the enclosing scope.
Scope Resolution Rules
Without global or nonlocal, assignments create new local variables. These keywords alter this behavior:
| Keyword | Accesses | Scope Level | Use Case |
|---|---|---|---|
global |
Module-level variables | Global | Modify module state from functions |
nonlocal |
Enclosing function variables | Enclosing | Closures, nested function state |
Execution Flow
Lines 54-65 demonstrate the execution and effects:
Variable Modification Flow
flowchart TD
Start([Assignment in Function]) --> Check{global or<br/>nonlocal<br/>declared?}
Check -->|global| ModGlobal[Modify module-level<br/>global variable]
Check -->|nonlocal| ModEnclosing[Modify enclosing<br/>function variable]
Check -->|Neither| CreateLocal[Create new<br/>local variable]
ModGlobal --> Done([Assignment Complete])
ModEnclosing --> Done
CreateLocal --> Done
Scope Levels Example
flowchart TD
Global[Global Scope<br/>x, a, b] --> Outer1[outer function<br/>y variable]
Outer1 --> Inner1[inner function<br/>accesses y with nonlocal]
Global --> Outer2[outer_multi function<br/>p, q, r variables]
Outer2 --> Inner2[inner_multi function<br/>accesses p,q,r with nonlocal]
Global --> TestGlobal[test_global function<br/>accesses x with global]
Common Patterns
Modifying module state:
Closure with state:
Multiple scope levels:
Key Differences
Global vs Nonlocal:
globalreaches to module level (skips all intermediate scopes)nonlocalreaches to the nearest enclosing function scope (not global)globalcan declare variables that don't exist yetnonlocalrequires the variable to exist in an enclosing scope
Important Rules
- Without declaration: Assignments create new local variables
- With global: Assignments modify module-level variables
- With nonlocal: Assignments modify enclosing function's variables
- Reading vs Writing: You can read outer scope variables without declarations; declarations are needed for assignment
- Multiple names: Both statements support comma-separated variable lists