echo "less than ten
} else {
echo "something else!"
}
```
## Shortcircuiting conditions
Boolean operators `&&` and `||` now will properly shortcircuit, only evaluating the right hand side if necessary.
## New built-in values
We're introducing `true` and `false` as builtin values. These represent their boolean values true and false respectively.
## Better binary data support
You can now use `get`, `skip`, and `first` on binary data to reach the bytes you'd like to work with. We're exploring extending this further so that it becomes easier to explore your binary data just like your text data.
## Structured environment
Inside of Nu, the environment can now hold any kind of structured value. For example, opening the `PATH` environment variable now might look like this in macOS:
```
> $env.PATH
╭───┬─────────────────────────────────╮
│ 0 │ /opt/homebrew/opt/openssl@3/bin │
│ 1 │ /opt/homebrew/bin │
│ 2 │ /opt/homebrew/sbin │
│ 3 │ /usr/local/bin │
│ 4 │ /usr/bin │
│ 5 │ /bin │
│ 6 │ /usr/sbin │
│ 7 │ /sbin │
╰───┴─────────────────────────────────╯
```
This allows you to more easily add and update to the environment. For example, we can add a new entry to the PATH:
```
> let-env PATH = ($env.PATH | prepend '/my/path')
```
Environment variables that aren't strings can be converted to strings automatically using the new `ENV_CONVERSIONS` environment variable.
## Scoped `cd`
In this release, we're also moving to keeping the current directory in the environment as `$env.PWD`. This leads to a few interesting twists in the design. For one, this means that `cd` is now scoped to the block you're currently in.
```
> cd ./foo
./foo> do { cd ./bar }
./foo>
```
This allows you to more easily loop over subdirectories without having to do the bookkeeping of remembering to change back to the previous directory:
```
> ls | where type == dir | each { |row| cd $row.name; ls | length }
```
That said, it takes a little getting used to. It does mean that changing a directory in a traditional custom command won't work, as the `PWD` environment variable will reset after the call completes. To help with this, we're also introducing `def-env`, a way to work inside the caller's environment and not lose any environment changes made by the custom command:
```
> def-env my-cd [path] {
cd $path
}
> my-cd ./foo
./foo>
```
## More consistent tables and cell paths
With this release, we've simplified the commands for working with tables. The two fundamental commands are now: `select` and `get`.
### `Select`-ing data
The `select` command allows you to keep the structure of what you're working on and reduce it to only the part you want. For example, just as before you can pass `select` to get a column:
```
> ls | select name
╭────┬───────────────────╮
│ # │ name │
├────┼───────────────────┤
│ 0 │ CNAME │
│ 1 │ CONTRIBUTING.md │
│ 2 │ LICENSE │
│ 3 │ README.md │
│ 4 │ assets │
│ 5 │ blog │
...
```
You can now also use `select` on rows, by passing in a row number:
```
> ls | select 1
╭───┬─────────────────┬──────┬───────┬────────────╮
│ # │ name │ type │ size │ modified │
├───┼─────────────────┼──────┼───────┼────────────┤
│ 0 │ CONTRIBUTING.md │ file │ 389 B │ 2 days ago │
╰───┴─────────────────┴──────┴───────┴────────────╯
```
### `Get`-ing data
The other fundamental command for working with tables is `get`. Like `select`, `get` allows you to work with columns and rows in a table, or fields in a record. Unlike `select`, the `get` command extracts data out of the table and does not try to preserve its original form. This is helpful when you want to get at the cell data itself.
Via a column:
```
> ls | get name
╭────┬───────────────────╮
│ 0 │ CNAME │
│ 1 │ CONTRIBUTING.md │
│ 2 │ LICENSE │