Skip to content

Commit

Permalink
Add documentation for select (#747)
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota authored Mar 22, 2024
1 parent 31b3300 commit 590df79
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* [if !](syntax_and_semantics/not.md)
* [unless](syntax_and_semantics/unless.md)
* [case](syntax_and_semantics/case.md)
* [select](syntax_and_semantics/select.md)
* [while](syntax_and_semantics/while.md)
* [break](syntax_and_semantics/break.md)
* [next](syntax_and_semantics/next.md)
Expand Down
53 changes: 53 additions & 0 deletions docs/syntax_and_semantics/select.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# select

The `select` expression chooses from a set of blocking operations and proceeds with the branch that becomes available first.

## Syntax

The expression starts with the keyword `select`, followed by a list of one or more `when` branches.
Each branch has a condition and a body, separated by either
a statement separator or the keyword `then`.
Optionally, the last branch may be `else` (without condition). This denotes the `select` action as non-blocking.
The expression closes with an `end` keyword.

> NOTE:
> `select` is similar to a [`case` expression](./case.md) with all branches referring to potentially blocking operations.
Each condition is either a call to a select action or an assignment whose right-hand side is a call to a select action.

```crystal
select
when foo = foo_channel.receive
puts foo
when bar = bar_channel.receive?
puts bar
when baz_channel.send
exit
when timeout(5.seconds)
puts "Timeout"
end
```

## Select actions

A select action call calls a method with the implicit suffix `_select_action`,
or `_select_action?` for a call with `?` suffix.
This method returns an instance of the select action.

The `select` expression initiates the select action associated with each branch. If either of them immediately returns, it proceeds with that.
Otherwise it waits for completion. As soon as one branch completes, all
others are canceled.
An `else` branch completes immediately so there will not be any waiting.

Execution continues in the completed branch.
If the branch condition is an assignment, the result of the select call is assigned to the target variable.

<!-- markdownlint-disable MD046 -->

!!! info "Select actions in the standard library"
The standard library provides the following select actions:

* `Channel#send_select_action`
* `Channel#receive_select_action`
* `Channel#receive_select_action?`
* [`::timeout_select_action`](https://crystal-lang.org/api/toplevel.html#timeout_select_action(timeout:Time::Span):Channel::TimeoutAction-class-method)

0 comments on commit 590df79

Please sign in to comment.