Block
Description: | A syntactic form used by some Nushell keywords (e.g., if and for ) |
Annotation: | N/A |
Literal Syntax: | N/A |
Casts: | N/A |
See also: | Types of Data - Blocks |
Additional Language Notes
Unlike closures, blocks:
Don't close over variables
Don't have parameters
Can't be passed as a value
Can access mutable variable in the parent scope.
Example - Mutate a variable inside the block used in an
if
callmut x = 1 if true { $x += 1000 } print $x
Result:
1001
Language Notes
A block consists of any Nushell code enclosed in curly braces:
{
,}
in certain specific Nushell constructs. In other cases code enclosed between braces is a closure.A block is not a data type like a closure and cannot be used to type a variable, custom command parameter, its input type, or its return type. You will get a type error if you try this.
let b: block = {} Error: × Blocks are not support as first-class values ╭─[entry #9:1:8] 1 │ let p: block = {} · ──┬── · ╰── blocks are not supported as values ╰──── help: Use 'closure' instead of 'block'
A closure that takes no parameters may look like a block but is actually a closure. For example:
> { echo foo } | describe closure # Alternatively > {|| echo foo } | describe closure
A block establishes a new variable scope. Variables defined within the new scope having the same name as a variable in an outer scope will alias (a.k.a. shadow) that name for the lifetime of that block's scope. Example:
# Outer scope: let x: int = 9 if true { # inner scope let x: string = '8' $x | describe # => string } echo $x # => 9
Mutable variables in blocks
Unlike closures, mutable variables are exposed within the inner scope of the block and can be modified. Once modified, the mutable variable is changed to the value to which it was set in the scope of the block.
E.g.
# This won't work
mut x = 9
do { $x += 1 }
# => Error: Capture of mutable variable.
# But this will work:
if true { $x += 1 }
# => 10
Note: Aliasing still occurs within the block:
mut x = 9
if true { mut x = 8; $x += 100; echo $x }
# => 108
echo $x
# => 9
Important
For both the if/else and try expressions, the value of the last expression in the block for whichever clause is executed is returned. This is not true for any of the looping constructs. If you try to assign the result of calling a for or while loop the type of the result will always be nothing
.
To capture the result of a loop, you can define a mutable variable before the loop and mutate it inside the body of the loop. However, the more idiomatic Nushell way to do it is with a command like each
which takes a closure. The last expression evaluated in the closure is returned and available to further items in the pipeline.
Common commands that can be used with a block
if
/else
loop
while
for
try
- But not the body of the catch clause which is always a closure