github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/docs/commands/global.md (about) 1 # `global` 2 3 > Define a global variable and set it's value 4 5 ## Description 6 7 Defines, updates or deallocates a global variable. 8 9 ## Usage 10 11 ``` 12 # Assume data type and value from STDIN 13 <stdin> -> global var_name 14 15 # Assume value from STDIN, define the data type manually 16 <stdin> -> global datatype var_name 17 18 # Define value manually (data type defaults to string; `str`) 19 global var_name=data 20 21 # Define value and data type manually 22 global datatype var_name=data 23 24 # Define a variable but don't set any value 25 global var_name 26 global datatype var_name 27 ``` 28 29 ## Examples 30 31 As a method: 32 33 ``` 34 » out "Hello, world!" -> global hw 35 » out "$hw" 36 Hello, World! 37 ``` 38 39 As a function: 40 41 ``` 42 » global hw="Hello, world!" 43 » out "$hw" 44 Hello, World! 45 ``` 46 47 ## Detail 48 49 ### Deallocation 50 51 You can unset variable names with the bang prefix: 52 53 ``` 54 !global var_name 55 ``` 56 57 ### Type Annotations 58 59 When `set` or `global` are used as a function, the parameters are passed as a 60 string which means the variables are defined as a `str`. If you wish to define 61 them as an alternate data type then you should add type annotations: 62 63 ``` 64 » set int age = 30 65 ``` 66 67 (`$age` is an integer, `int`) 68 69 ``` 70 » global bool dark_theme = true 71 ``` 72 73 (`$dark_theme` is a boolean, `bool`) 74 75 When using `set` or `global` as a method, by default they will define the 76 variable as the data type of the pipe: 77 78 ``` 79 » open example.json -> set: file 80 ``` 81 82 (`$file` is defined a `json` type because `open` wrote to `set`'s pipe with a 83 `json` type) 84 85 You can also annotate `set` and `global` when used as a method too: 86 87 ``` 88 out 30 -> set: int age 89 ``` 90 91 (`$age` is an integer, `int`, despite `out` writing a string, `str, to the pipe) 92 93 > `export` does not support type annotations because environmental variables 94 > must always be strings. This is a limitation of the current operating systems. 95 96 ### Scoping 97 98 Variable scoping is simplified to three layers: 99 100 1. Local variables (`set`, `!set`, `let`) 101 2. Global variables (`global`, `!global`) 102 3. Environmental variables (`export`, `!export`, `unset`) 103 104 Variables are looked up in that order of too. For example a the following 105 code where `set` overrides both the global and environmental variable: 106 107 ``` 108 » set foobar=1 109 » global foobar=2 110 » export foobar=3 111 » out $foobar 112 1 113 ``` 114 115 #### Local variables 116 117 These are defined via `set` and `let`. They're variables that are persistent 118 across any blocks within a function. Functions will typically be blocks 119 encapsulated like so: 120 121 ``` 122 function example { 123 # variables scoped inside here 124 } 125 ``` 126 127 ...or... 128 129 ``` 130 private example { 131 # variables scoped inside here 132 } 133 134 ``` 135 136 ...however dynamic autocompletes, events, unit tests and any blocks defined in 137 `config` will also be triggered as functions. 138 139 Code running inside any control flow or error handing structures will be 140 treated as part of the same part of the same scope as the parent function: 141 142 ``` 143 » function example { 144 » try { 145 » # set 'foobar' inside a `try` block 146 » set foobar=example 147 » } 148 » # 'foobar' exists outside of `try` because it is scoped to `function` 149 » out $foobar 150 » } 151 example 152 ``` 153 154 Where this behavior might catch you out is with iteration blocks which create 155 variables, eg `for`, `foreach` and `formap`. Any variables created inside them 156 are still shared with any code outside of those structures but still inside the 157 function block. 158 159 Any local variables are only available to that function. If a variable is 160 defined in a parent function that goes on to call child functions, then those 161 local variables are not inherited but the child functions: 162 163 ``` 164 » function parent { 165 » # set a local variable 166 » set foobar=example 167 » child 168 » } 169 » 170 » function child { 171 » # returns the `global` value, "not set", because the local `set` isn't inherited 172 » out $foobar 173 » } 174 » 175 » global $foobar="not set" 176 » parent 177 not set 178 ``` 179 180 It's also worth remembering that any variable defined using `set` in the shells 181 FID (ie in the interactive shell) is localised to structures running in the 182 interactive, REPL, shell and are not inherited by any called functions. 183 184 #### Global variables 185 186 Where `global` differs from `set` is that the variables defined with `global` 187 will be scoped at the global shell level (please note this is not the same as 188 environmental variables!) so will cascade down through all scoped code-blocks 189 including those running in other threads. 190 191 #### Environmental variables 192 193 Exported variables (defined via `export`) are system environmental variables. 194 Inside Murex environmental variables behave much like `global` variables 195 however their real purpose is passing data to external processes. For example 196 `env` is an external process on Linux (eg `/usr/bin/env` on ArchLinux): 197 198 ``` 199 » export foo=bar 200 » env -> grep foo 201 foo=bar 202 ``` 203 204 ### Function Names 205 206 As a security feature function names cannot include variables. This is done to 207 reduce the risk of code executing by mistake due to executables being hidden 208 behind variable names. 209 210 Instead Murex will assume you want the output of the variable printed: 211 212 ``` 213 » out "Hello, world!" -> set hw 214 » $hw 215 Hello, world! 216 ``` 217 218 On the rare occasions you want to force variables to be expanded inside a 219 function name, then call that function via `exec`: 220 221 ``` 222 » set cmd=grep 223 » ls -> exec $cmd main.go 224 main.go 225 ``` 226 227 This only works for external executables. There is currently no way to call 228 aliases, functions nor builtins from a variable and even the above `exec` trick 229 is considered bad form because it reduces the readability of your shell scripts. 230 231 ### Usage Inside Quotation Marks 232 233 Like with Bash, Perl and PHP: Murex will expand the variable when it is used 234 inside a double quotes but will escape the variable name when used inside single 235 quotes: 236 237 ``` 238 » out "$foo" 239 bar 240 241 » out '$foo' 242 $foo 243 244 » out %($foo) 245 bar 246 ``` 247 248 ## Synonyms 249 250 * `global` 251 * `!global` 252 253 254 ## See Also 255 256 * [Reserved Variables](../user-guide/reserved-vars.md): 257 Special variables reserved by Murex 258 * [Variable and Config Scoping](../user-guide/scoping.md): 259 How scoping works within Murex 260 * [`%(Brace Quote)`](../parser/brace-quote.md): 261 Initiates or terminates a string (variables expanded) 262 * [`??` Null Coalescing Operator](../parser/null-coalescing.md): 263 Returns the right operand if the left operand is empty / undefined (expression) 264 * [`[ Index ]`](../parser/item-index.md): 265 Outputs an element from an array, map or table 266 * [`[[ Element ]]`](../parser/element.md): 267 Outputs an element from a nested structure 268 * [`export`](../commands/export.md): 269 Define an environmental variable and set it's value 270 * [`expr`](../commands/expr.md): 271 Expressions: mathematical, string comparisons, logical operators 272 * [`is-null`](../commands/is-null.md): 273 Checks if a variable is null or undefined 274 * [`set`](../commands/set.md): 275 Define a local variable and set it's value 276 277 <hr/> 278 279 This document was generated from [builtins/core/typemgmt/variables_doc.yaml](https://github.com/lmorg/murex/blob/master/builtins/core/typemgmt/variables_doc.yaml).