│ 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 │
│ 3 │ README.md │
│ 4 │ assets │
│ 5 │ blog │
...
```
Via a row:
```
> ls | get 1
╭──────────┬─────────────────╮
│ name │ CONTRIBUTING.md │
│ type │ file │
│ size │ 389 B │
│ modified │ 2 days ago │
╰──────────┴─────────────────╯
```
You'll notice that getting rows out of a table with columns gives you back a record. You can think of a table as a list of records.
You can combine working with rows and columns together into a "cell path", a way of reaching the data you want. If we only wanted to get the cell's data in row 1, column "size", we can do:
```
> ls | get size.1
```
## New pipeline syntax form
When writing scripts in Nushell, often folks want to be able to build up a pipeline and line up all the pipes on the left. This is now supported in scripts:
```
ls
| where size > 10kb
| length
```
## Default params
A common request as more people tried Nushell was "can we have default values for parameters". Thanks to the work on the new parser, we can!
Now, you're able to set a default value for any optional parameter in your command:
```
def add-maybe-hundred [x:int, y = 100] {
$x + $y
}
let twelve_squared = add-maybe-hundred 44
```
Default values also work for flag parameters.
## Stdout, stderr, and exit codes
In previous versions of Nushell, you generally had easy access to the stdout of an external command. You could run it, and then create a pipe and work with its output. If you wanted to work with stderr or get its exit code, you didn't have an easy way to do it.
With 0.60, we've introduced the `complete` command. Running an external command and then pipeline it to `complete` runs the external to completion and then gives you the stdout, stderr, and exit code of that external.
```
> cat CNAME | complete
╭───────────┬────────────────╮
│ stdout │ www.nushell.sh │
│ stderr │ │
│ exit_code │ 0 │
╰───────────┴────────────────╯
```
To redirect stderr, you can call through `do -i`. For example, let's say we're calling `cat` again, this time with a file that doesn't exist:
```
> do -i { cat unknown.txt } | complete
╭───────────┬─────────────────────────────────────────────╮
│ stdout │ │
│ stderr │ cat: unknown.txt: No such file or directory │
│ exit_code │ 1 │
╰───────────┴─────────────────────────────────────────────╯
```
You can also access the last exit code via `$env.LAST_EXIT_CODE`.
## Modules
With 0.60, you're now able to create your own modules, allowing you to grow to larger projects with clean interfaces between files. A module can be written either using the `module` keyword:
```
module greetings {
export def greet [] {
print "hello!"
}
}
use greetings greet
greet
```
You can also make modules from whole files. We can rewrite the above using a separate file:
```
# greetings.nu
export def greet [] {