github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/gen/includes/variables.inc.md (about) 1 ### Type Annotations 2 3 When `set` or `global` are used as a function, the parameters are passed as a 4 string which means the variables are defined as a `str`. If you wish to define 5 them as an alternate data type then you should add type annotations: 6 7 ``` 8 » set int age = 30 9 ``` 10 11 (`$age` is an integer, `int`) 12 13 ``` 14 » global bool dark_theme = true 15 ``` 16 17 (`$dark_theme` is a boolean, `bool`) 18 19 When using `set` or `global` as a method, by default they will define the 20 variable as the data type of the pipe: 21 22 ``` 23 » open example.json -> set: file 24 ``` 25 26 (`$file` is defined a `json` type because `open` wrote to `set`'s pipe with a 27 `json` type) 28 29 You can also annotate `set` and `global` when used as a method too: 30 31 ``` 32 out 30 -> set: int age 33 ``` 34 35 (`$age` is an integer, `int`, despite `out` writing a string, `str, to the pipe) 36 37 > `export` does not support type annotations because environmental variables 38 > must always be strings. This is a limitation of the current operating systems. 39 40 ### Scoping 41 42 Variable scoping is simplified to three layers: 43 44 1. Local variables (`set`, `!set`, `let`) 45 2. Global variables (`global`, `!global`) 46 3. Environmental variables (`export`, `!export`, `unset`) 47 48 Variables are looked up in that order of too. For example a the following 49 code where `set` overrides both the global and environmental variable: 50 51 ``` 52 » set foobar=1 53 » global foobar=2 54 » export foobar=3 55 » out $foobar 56 1 57 ``` 58 59 #### Local variables 60 61 These are defined via `set` and `let`. They're variables that are persistent 62 across any blocks within a function. Functions will typically be blocks 63 encapsulated like so: 64 65 ``` 66 function example { 67 # variables scoped inside here 68 } 69 ``` 70 71 ...or... 72 73 ``` 74 private example { 75 # variables scoped inside here 76 } 77 78 ``` 79 80 ...however dynamic autocompletes, events, unit tests and any blocks defined in 81 `config` will also be triggered as functions. 82 83 Code running inside any control flow or error handing structures will be 84 treated as part of the same part of the same scope as the parent function: 85 86 ``` 87 » function example { 88 » try { 89 » # set 'foobar' inside a `try` block 90 » set foobar=example 91 » } 92 » # 'foobar' exists outside of `try` because it is scoped to `function` 93 » out $foobar 94 » } 95 example 96 ``` 97 98 Where this behavior might catch you out is with iteration blocks which create 99 variables, eg `for`, `foreach` and `formap`. Any variables created inside them 100 are still shared with any code outside of those structures but still inside the 101 function block. 102 103 Any local variables are only available to that function. If a variable is 104 defined in a parent function that goes on to call child functions, then those 105 local variables are not inherited but the child functions: 106 107 ``` 108 » function parent { 109 » # set a local variable 110 » set foobar=example 111 » child 112 » } 113 » 114 » function child { 115 » # returns the `global` value, "not set", because the local `set` isn't inherited 116 » out $foobar 117 » } 118 » 119 » global $foobar="not set" 120 » parent 121 not set 122 ``` 123 124 It's also worth remembering that any variable defined using `set` in the shells 125 FID (ie in the interactive shell) is localised to structures running in the 126 interactive, REPL, shell and are not inherited by any called functions. 127 128 #### Global variables 129 130 Where `global` differs from `set` is that the variables defined with `global` 131 will be scoped at the global shell level (please note this is not the same as 132 environmental variables!) so will cascade down through all scoped code-blocks 133 including those running in other threads. 134 135 #### Environmental variables 136 137 Exported variables (defined via `export`) are system environmental variables. 138 Inside Murex environmental variables behave much like `global` variables 139 however their real purpose is passing data to external processes. For example 140 `env` is an external process on Linux (eg `/usr/bin/env` on ArchLinux): 141 142 ``` 143 » export foo=bar 144 » env -> grep foo 145 foo=bar 146 ``` 147 148 ### Function Names 149 150 As a security feature function names cannot include variables. This is done to 151 reduce the risk of code executing by mistake due to executables being hidden 152 behind variable names. 153 154 Instead Murex will assume you want the output of the variable printed: 155 156 ``` 157 » out "Hello, world!" -> set hw 158 » $hw 159 Hello, world! 160 ``` 161 162 On the rare occasions you want to force variables to be expanded inside a 163 function name, then call that function via `exec`: 164 165 ``` 166 » set cmd=grep 167 » ls -> exec $cmd main.go 168 main.go 169 ``` 170 171 This only works for external executables. There is currently no way to call 172 aliases, functions nor builtins from a variable and even the above `exec` trick 173 is considered bad form because it reduces the readability of your shell scripts. 174 175 ### Usage Inside Quotation Marks 176 177 Like with Bash, Perl and PHP: Murex will expand the variable when it is used 178 inside a double quotes but will escape the variable name when used inside single 179 quotes: 180 181 ``` 182 » out "$foo" 183 bar 184 185 » out '$foo' 186 $foo 187 188 » out %($foo) 189 bar 190 ```