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).