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  ```