Skip to content

Commit

Permalink
docs added for elvis and null coalescing operators
Browse files Browse the repository at this point in the history
  • Loading branch information
lmorg committed Oct 8, 2023
1 parent 23a0183 commit ba56e74
Show file tree
Hide file tree
Showing 17 changed files with 196 additions and 32 deletions.
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const (
version = "%d.%d.%d"
Major = 5
Minor = 1
Revision = 2000
Revision = 2100
)

// Copyright is the copyright owner string
Expand Down
4 changes: 3 additions & 1 deletion builtins/docs/summaries.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ func init() {
"parser/equ": "Evaluate a mathematical function (deprecated)",
"parser/greater-than-greater-than": "Writes STDIN to disk - appending contents if file already exists",
"parser/pipe-append": "Redirects STDOUT to a file and append its contents",
"parser/elvis": "Returns the right operand if the left operand is empty",
"parser/elvis": "Returns the right operand if the left operand is falsy",
"parser/null-coalescing": "Returns the right operand if the left operand is empty / undefined",
"parser/pipe-err": "Pipes STDERR from the left hand command to STDIN of the right hand command",
"parser/range": "Outputs a ranged subset of data from STDIN",
"parser/element": "Outputs an element from a nested structure",
Expand Down Expand Up @@ -729,6 +730,7 @@ func init() {
"parser/fappend": "parser/greater-than-greater-than",
"parser/pipe-append": "parser/pipe-append",
"parser/elvis": "parser/elvis",
"parser/null-coalescing": "parser/null-coalescing",
"parser/pipe-err": "parser/pipe-err",
"parser/@[": "parser/range",
"parser/[[": "parser/element",
Expand Down
4 changes: 3 additions & 1 deletion docs/parser/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ files.
* [`>>` Append Pipe](../parser/pipe-append.md):
Redirects STDOUT to a file and append its contents
* [`?:` Elvis Operator](../parser/elvis.md):
Returns the right operand if the left operand is empty
Returns the right operand if the left operand is falsy
* [`??` Null Coalescing Operator](../parser/null-coalescing.md):
Returns the right operand if the left operand is empty / undefined
* [`?` STDERR Pipe](../parser/pipe-err.md):
Pipes STDERR from the left hand command to STDIN of the right hand command
* [`[..range]`](../parser/range.md):
Expand Down
19 changes: 13 additions & 6 deletions docs/parser/elvis.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
# `?:` Elvis Operator

> Returns the right operand if the left operand is empty
> Returns the right operand if the left operand is falsy
## Description

The elvis operator is a little like a conditional where the result of the
operation is the first non-empty value from left to right.
operation is the first non-falsy value from left to right.

An empty value is any of the following:
A falsy value is any of the following:

* An unset / undefined variable
* Any value with a `null` data type
* an unset / undefined variable
* any value with a `null` data type
* a `str` or generic with the value `false`, `null`, `0`, `no`, `off`, `fail`,
`failed`, or `disabled`
* a number (`num`, `float` or `int`) with the value `0`
* an empty object or zero length array
* and, of course, a boolean with the value `false`

Other "falsy" values such as numerical values of `0`, boolean `false`, zero
length strings and strings containing `"null"` are not considered empty by the
Expand All @@ -31,7 +36,7 @@ If `$bar` is unset then the value of `$foo` will be **"baz"**.
**Multiple elvis operators:**

```
» $unset_variable ?: null ?: "foobar"
» $unset_variable ?: null ?: false ?: "foobar"
foobar
```

Expand All @@ -54,6 +59,8 @@ where it says:
Overview of the different schedulers (or 'run modes') in Murex
* [`&&` And Logical Operator](../parser/logical-and.md):
Continues next operation if previous operation passes
* [`??` Null Coalescing Operator](../parser/null-coalescing.md):
Returns the right operand if the left operand is empty / undefined
* [`?` STDERR Pipe](../parser/pipe-err.md):
Pipes STDERR from the left hand command to STDIN of the right hand command
* [`err`](../commands/err.md):
Expand Down
2 changes: 1 addition & 1 deletion docs/parser/logical-and.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ try {
* [Schedulers](../user-guide/schedulers.md):
Overview of the different schedulers (or 'run modes') in Murex
* [`?:` Elvis Operator](../parser/elvis.md):
Returns the right operand if the left operand is empty
Returns the right operand if the left operand is falsy
* [`?` STDERR Pipe](../parser/pipe-err.md):
Pipes STDERR from the left hand command to STDIN of the right hand command
* [`err`](../commands/err.md):
Expand Down
2 changes: 1 addition & 1 deletion docs/parser/logical-or.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ There is no workaround for `trypipe`.
* [`&&` And Logical Operator](../parser/logical-and.md):
Continues next operation if previous operation passes
* [`?:` Elvis Operator](../parser/elvis.md):
Returns the right operand if the left operand is empty
Returns the right operand if the left operand is falsy
* [`?` STDERR Pipe](../parser/pipe-err.md):
Pipes STDERR from the left hand command to STDIN of the right hand command
* [`err`](../commands/err.md):
Expand Down
84 changes: 84 additions & 0 deletions docs/parser/null-coalescing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# `??` Null Coalescing Operator

> Returns the right operand if the left operand is empty / undefined
## Description

The null coalescing operator is a little like a conditional where the result of the
operation is the first non-empty value from left to right.

An empty value is any of the following:

* an unset / undefined variable
* any value with a `null` data type

Other "falsy" values such as numerical values of `0`, boolean `false`, zero
length strings and strings containing `"null"` are not considered empty by the
null coalescing operator.



## Examples

**Assign a variable with a default value:**

```
» $foo = $bar ?? "baz"
```

If `$bar` is unset then the value of `$foo` will be **"baz"**.

**Multiple operators:**

```
» $unset_variable ?? null ?? "foobar"
foobar
```

## Detail

The following extract was taken from [Wikipedia](https://en.wikipedia.org/wiki/Null_coalescing_operator):

> The null coalescing operator (called the Logical Defined-Or operator in Perl)
> is a binary operator that is part of the syntax for a basic conditional
> expression in several programming languages, including C#, PowerShell as of
> version 7.0.0, Perl as of version 5.10, Swift, and PHP 7.0.0. While its
> behavior differs between implementations, the null coalescing operator
> generally returns the result of its left-most operand if it exists and is not
> null, and otherwise returns the right-most operand. This behavior allows a
> default value to be defined for cases where a more specific value is not
> available.
>
> In contrast to the ternary conditional if operator used as `x ? x : y`, but
> like the binary Elvis operator used as `x ?: y`, the null coalescing operator
> is a binary operator and thus evaluates its operands at most once, which is
> significant if the evaluation of `x` has side-effects.
## See Also

* [Pipeline](../user-guide/pipeline.md):
Overview of what a "pipeline" is
* [Schedulers](../user-guide/schedulers.md):
Overview of the different schedulers (or 'run modes') in Murex
* [`&&` And Logical Operator](../parser/logical-and.md):
Continues next operation if previous operation passes
* [`?:` Elvis Operator](../parser/elvis.md):
Returns the right operand if the left operand is falsy
* [`?` STDERR Pipe](../parser/pipe-err.md):
Pipes STDERR from the left hand command to STDIN of the right hand command
* [`err`](../commands/err.md):
Print a line to the STDERR
* [`out`](../commands/out.md):
Print a string to the STDOUT with a trailing new line character
* [`try`](../commands/try.md):
Handles errors inside a block of code
* [`trypipe`](../commands/trypipe.md):
Checks state of each function in a pipeline and exits block on error
* [`||` Or Logical Operator](../parser/logical-or.md):
Continues next operation only if previous operation fails
* [null](../commands/devnull.md):
null function. Similar to /dev/null

<hr/>

This document was generated from [gen/parser/null_coalescing_op_doc.yaml](https://github.com/lmorg/murex/blob/master/gen/parser/null_coalescing_op_doc.yaml).
4 changes: 3 additions & 1 deletion docs/user-guide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ The [Language Tour](/tour.md) is a great introduction into the Murex language.
* [`>>` Append Pipe](parser/pipe-append.md):
Redirects STDOUT to a file and append its contents
* [`?:` Elvis Operator](parser/elvis.md):
Returns the right operand if the left operand is empty
Returns the right operand if the left operand is falsy
* [`??` Null Coalescing Operator](parser/null-coalescing.md):
Returns the right operand if the left operand is empty / undefined
* [`?` STDERR Pipe](parser/pipe-err.md):
Pipes STDERR from the left hand command to STDIN of the right hand command
* [`[..range]`](parser/range.md):
Expand Down
4 changes: 2 additions & 2 deletions docs/user-guide/rosetta-stone.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ if you want to learn more about shell scripting in Murex.
### Variables
| Description | Bash | Murex |
|---------------|---------------|--------|
| [Printing a variable](../parser/string.md) | `echo "$foobar"` | `out $foobar` [[5]](#footnotes)<br/><br/>`$foobar` <br/><br/> (variables don't need to be quoted in Murex) |
| [Printing a variable](../parser/scalar.md) | `echo "$foobar"` | `out $foobar` [[5]](#footnotes)<br/><br/>`$foobar` <br/><br/> (variables don't need to be quoted in Murex) |
| [Assign a local variable](../commands/set.md) | `local foo="bar"` | `$foo = "bar"` [[2]](#footnotes) [[6]](#footnotes)<br/><br/>`out "bar" \| set $foo` |
| [Assign a global variable](../commands/global.md) | `foo="bar"` | `$GLOBAL.foo = "bar"` [[6]](#footnotes)<br/><br/>`out "bar" \| global $foo` |
| [Assign an environmental variable](../commands/export.md) | `export foo="bar"` | `export foo = "bar"` [[1]](#footnotes) [[2]](#footnotes) [[3]](#footnotes)<br/><br/>`$ENV.foo = "bar"` [[6]](#footnotes)<br/><br/>`out "bar" \| export $foo` [[3]](#footnotes) |
| Assign with a default value | `FOOBAR="${VARIABLE:-default}"` | `$foobar = $variable ?: "default"` <br/><br/> (the elvis operator can be used in any part of expressions and just for assignments)
| [Assign with a default value](../parser/null-coalescing.md) | `FOOBAR="${VARIABLE:-default}"` | `$foobar = $variable ?: "default"` <br/><br/> (the elvis operator can be used in any part of expressions and just for assignments)

### Arrays
(eg arrays, lists)
Expand Down
18 changes: 12 additions & 6 deletions gen/parser/elvis_op_doc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@
`?:` Elvis Operator
CategoryID: parser
Summary: >-
Returns the right operand if the left operand is empty
Returns the right operand if the left operand is falsy
Description: |-
The elvis operator is a little like a conditional where the result of the
operation is the first non-empty value from left to right.
operation is the first non-falsy value from left to right.
An empty value is any of the following:
A falsy value is any of the following:
* An unset / undefined variable
* Any value with a `null` data type
* an unset / undefined variable
* any value with a `null` data type
* a `str` or generic with the value `false`, `null`, `0`, `no`, `off`, `fail`,
`failed`, or `disabled`
* a number (`num`, `float` or `int`) with the value `0`
* an empty object or zero length array
* and, of course, a boolean with the value `false`
Other "falsy" values such as numerical values of `0`, boolean `false`, zero
length strings and strings containing `"null"` are not considered empty by the
Expand All @@ -28,7 +33,7 @@
**Multiple elvis operators:**
```
» $unset_variable ?: null ?: "foobar"
» $unset_variable ?: null ?: false ?: "foobar"
foobar
```
Detail: |-
Expand All @@ -41,6 +46,7 @@
> ?:, is viewed sideways, it resembles an emoticon of Elvis Presley with his
> signature hairstyle.
Related:
- null-coalescing
- pipe-err
- pipeline
- schedulers
Expand Down
62 changes: 62 additions & 0 deletions gen/parser/null_coalescing_op_doc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
- DocumentID: null-coalescing
Title: >-
`??` Null Coalescing Operator
CategoryID: parser
Summary: >-
Returns the right operand if the left operand is empty / undefined
Description: |-
The null coalescing operator is a little like a conditional where the result of the
operation is the first non-empty value from left to right.
An empty value is any of the following:
* an unset / undefined variable
* any value with a `null` data type
Other "falsy" values such as numerical values of `0`, boolean `false`, zero
length strings and strings containing `"null"` are not considered empty by the
null coalescing operator.
Examples: |-
**Assign a variable with a default value:**
```
» $foo = $bar ?? "baz"
```
If `$bar` is unset then the value of `$foo` will be **"baz"**.
**Multiple operators:**
```
» $unset_variable ?? null ?? "foobar"
foobar
```
Detail: |-
The following extract was taken from [Wikipedia](https://en.wikipedia.org/wiki/Null_coalescing_operator):
> The null coalescing operator (called the Logical Defined-Or operator in Perl)
> is a binary operator that is part of the syntax for a basic conditional
> expression in several programming languages, including C#, PowerShell as of
> version 7.0.0, Perl as of version 5.10, Swift, and PHP 7.0.0. While its
> behavior differs between implementations, the null coalescing operator
> generally returns the result of its left-most operand if it exists and is not
> null, and otherwise returns the right-most operand. This behavior allows a
> default value to be defined for cases where a more specific value is not
> available.
>
> In contrast to the ternary conditional if operator used as `x ? x : y`, but
> like the binary Elvis operator used as `x ?: y`, the null coalescing operator
> is a binary operator and thus evaluates its operands at most once, which is
> significant if the evaluation of `x` has side-effects.
Related:
- elvis
- pipe-err
- pipeline
- schedulers
- out
- err
- try
- trypipe
- logical-and
- logical-or
- "null"
4 changes: 2 additions & 2 deletions gen/user-guide/rosetta-stone.inc.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ if you want to learn more about shell scripting in Murex.
### Variables
| Description | Bash | Murex |
|---------------|---------------|--------|
| [Printing a variable](../parser/string.md) | `echo "$foobar"` | `out $foobar` [[5]](#footnotes)<br/><br/>`$foobar` <br/><br/> (variables don't need to be quoted in Murex) |
| [Printing a variable](../parser/scalar.md) | `echo "$foobar"` | `out $foobar` [[5]](#footnotes)<br/><br/>`$foobar` <br/><br/> (variables don't need to be quoted in Murex) |
| [Assign a local variable](../commands/set.md) | `local foo="bar"` | `$foo = "bar"` [[2]](#footnotes) [[6]](#footnotes)<br/><br/>`out "bar" \| set $foo` |
| [Assign a global variable](../commands/global.md) | `foo="bar"` | `$GLOBAL.foo = "bar"` [[6]](#footnotes)<br/><br/>`out "bar" \| global $foo` |
| [Assign an environmental variable](../commands/export.md) | `export foo="bar"` | `export foo = "bar"` [[1]](#footnotes) [[2]](#footnotes) [[3]](#footnotes)<br/><br/>`$ENV.foo = "bar"` [[6]](#footnotes)<br/><br/>`out "bar" \| export $foo` [[3]](#footnotes) |
| Assign with a default value | `FOOBAR="${VARIABLE:-default}"` | `$foobar = $variable ?: "default"` <br/><br/> (the elvis operator can be used in any part of expressions and just for assignments)
| [Assign with a default value](../parser/null-coalescing.md) | `FOOBAR="${VARIABLE:-default}"` | `$foobar = $variable ?: "default"` <br/><br/> (the elvis operator can be used in any part of expressions and just for assignments)

### Arrays
(eg arrays, lists)
Expand Down
4 changes: 2 additions & 2 deletions lang/expressions/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ func executeExpression(tree *ParserT, order symbols.Exp) (err error) {
err = expAssignMerge(tree)

// 13. Conditional expression (ternary)
case symbols.Elvis:
err = expElvis(tree)
case symbols.NullCoalescing:
err = expNullCoalescing(tree)
case symbols.Elvis:
err = expElvis(tree)

// 12. Logical OR
case symbols.LogicalOr:
Expand Down
2 changes: 1 addition & 1 deletion lang/expressions/symbols/exp.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ const (
AssignAndMerge

// 13. Conditional expression (ternary)
NullCoalescing
Elvis
NullCoalescing

// 12. Logical OR
LogicalOr
Expand Down
8 changes: 4 additions & 4 deletions lang/expressions/symbols/exp_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions utils/readline/unicode.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ func (u *UnicodeT) SetCellPos(cPos int) {
i := u._offByOne(u.rPos)
if i != u.rPos {
u.rPos--
// TODO: this isn't wide character compliant
u.cPos--
u.cPos -= runewidth.RuneWidth(u.value[u.rPos])
}
}

Expand Down
2 changes: 1 addition & 1 deletion version.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ba56e74

Please sign in to comment.