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