forked from lix-project/lix
Merge pull request #8317 from fricklerhandwerk/doc-identifier
document identifier syntax for attribute sets
This commit is contained in:
commit
527eb4a99a
|
@ -2,8 +2,11 @@
|
||||||
|
|
||||||
## Recursive sets
|
## Recursive sets
|
||||||
|
|
||||||
Recursive sets are just normal sets, but the attributes can refer to
|
Recursive sets are like normal [attribute sets](./values.md#attribute-set), but the attributes can refer to each other.
|
||||||
each other. For example,
|
|
||||||
|
> *rec-attrset* = `rec {` [ *name* `=` *expr* `;` `]`... `}`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
rec {
|
rec {
|
||||||
|
@ -12,7 +15,9 @@ rec {
|
||||||
}.x
|
}.x
|
||||||
```
|
```
|
||||||
|
|
||||||
evaluates to `123`. Note that without `rec` the binding `x = y;` would
|
This evaluates to `123`.
|
||||||
|
|
||||||
|
Note that without `rec` the binding `x = y;` would
|
||||||
refer to the variable `y` in the surrounding scope, if one exists, and
|
refer to the variable `y` in the surrounding scope, if one exists, and
|
||||||
would be invalid if no such variable exists. That is, in a normal
|
would be invalid if no such variable exists. That is, in a normal
|
||||||
(non-recursive) set, attributes are not added to the lexical scope; in a
|
(non-recursive) set, attributes are not added to the lexical scope; in a
|
||||||
|
@ -33,7 +38,10 @@ will crash with an `infinite recursion encountered` error message.
|
||||||
## Let-expressions
|
## Let-expressions
|
||||||
|
|
||||||
A let-expression allows you to define local variables for an expression.
|
A let-expression allows you to define local variables for an expression.
|
||||||
For instance,
|
|
||||||
|
> *let-in* = `let` [ *identifier* = *expr* ]... `in` *expr*
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
let
|
let
|
||||||
|
@ -42,18 +50,19 @@ let
|
||||||
in x + y
|
in x + y
|
||||||
```
|
```
|
||||||
|
|
||||||
evaluates to `"foobar"`.
|
This evaluates to `"foobar"`.
|
||||||
|
|
||||||
## Inheriting attributes
|
## Inheriting attributes
|
||||||
|
|
||||||
When defining a set or in a let-expression it is often convenient to
|
When defining an [attribute set](./values.md#attribute-set) or in a [let-expression](#let-expressions) it is often convenient to copy variables from the surrounding lexical scope (e.g., when you want to propagate attributes).
|
||||||
copy variables from the surrounding lexical scope (e.g., when you want
|
This can be shortened using the `inherit` keyword.
|
||||||
to propagate attributes). This can be shortened using the `inherit`
|
|
||||||
keyword. For instance,
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
let x = 123; in
|
let x = 123; in
|
||||||
{ inherit x;
|
{
|
||||||
|
inherit x;
|
||||||
y = 456;
|
y = 456;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -62,15 +71,23 @@ is equivalent to
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
let x = 123; in
|
let x = 123; in
|
||||||
{ x = x;
|
{
|
||||||
|
x = x;
|
||||||
y = 456;
|
y = 456;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
and both evaluate to `{ x = 123; y = 456; }`. (Note that this works
|
and both evaluate to `{ x = 123; y = 456; }`.
|
||||||
because `x` is added to the lexical scope by the `let` construct.) It is
|
|
||||||
also possible to inherit attributes from another set. For instance, in
|
> **Note**
|
||||||
this fragment from `all-packages.nix`,
|
>
|
||||||
|
> This works because `x` is added to the lexical scope by the `let` construct.
|
||||||
|
|
||||||
|
It is also possible to inherit attributes from another attribute set.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
In this fragment from `all-packages.nix`,
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
graphviz = (import ../tools/graphics/graphviz) {
|
graphviz = (import ../tools/graphics/graphviz) {
|
||||||
|
|
|
@ -35,17 +35,14 @@
|
||||||
|
|
||||||
## Attribute selection
|
## Attribute selection
|
||||||
|
|
||||||
|
> *attrset* `.` *attrpath* \[ `or` *expr* \]
|
||||||
|
|
||||||
Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*.
|
Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*.
|
||||||
If the attribute doesn’t exist, return the *expr* after `or` if provided, otherwise abort evaluation.
|
If the attribute doesn’t exist, return the *expr* after `or` if provided, otherwise abort evaluation.
|
||||||
|
|
||||||
<!-- FIXME: the following should to into its own language syntax section, but that needs more work to fit in well -->
|
An attribute path is a dot-separated list of [attribute names](./values.md#attribute-set).
|
||||||
|
|
||||||
An attribute path is a dot-separated list of attribute names.
|
> *attrpath* = *name* [ `.` *name* ]...
|
||||||
An attribute name can be an identifier or a string.
|
|
||||||
|
|
||||||
> *attrpath* = *name* [ `.` *name* ]... \
|
|
||||||
> *name* = *identifier* | *string* \
|
|
||||||
> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*`
|
|
||||||
|
|
||||||
[Attribute selection]: #attribute-selection
|
[Attribute selection]: #attribute-selection
|
||||||
|
|
||||||
|
|
|
@ -164,9 +164,17 @@ Note that lists are only lazy in values, and they are strict in length.
|
||||||
|
|
||||||
An attribute set is a collection of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`).
|
An attribute set is a collection of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`).
|
||||||
|
|
||||||
|
An attribute name can be an identifier or a [string](#string).
|
||||||
|
An identifier must start with a letter (`a-z`, `A-Z`) or underscore (`_`), and can otherwise contain letters (`a-z`, `A-Z`), numbers (`0-9`), underscores (`_`), apostrophes (`'`), or dashes (`-`).
|
||||||
|
|
||||||
|
> *name* = *identifier* | *string* \
|
||||||
|
> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*`
|
||||||
|
|
||||||
Names and values are separated by an equal sign (`=`).
|
Names and values are separated by an equal sign (`=`).
|
||||||
Each value is an arbitrary expression terminated by a semicolon (`;`).
|
Each value is an arbitrary expression terminated by a semicolon (`;`).
|
||||||
|
|
||||||
|
> *attrset* = `{` [ *name* `=` *expr* `;` `]`... `}`
|
||||||
|
|
||||||
Attributes can appear in any order.
|
Attributes can appear in any order.
|
||||||
An attribute name may only occur once.
|
An attribute name may only occur once.
|
||||||
|
|
||||||
|
@ -182,15 +190,19 @@ Example:
|
||||||
|
|
||||||
This defines a set with attributes named `x`, `text`, `y`.
|
This defines a set with attributes named `x`, `text`, `y`.
|
||||||
|
|
||||||
Attributes can be selected from a set using the `.` operator. For
|
Attributes can be accessed with the [`.` operator](./operators.md#attribute-selection).
|
||||||
instance,
|
|
||||||
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ a = "Foo"; b = "Bar"; }.a
|
{ a = "Foo"; b = "Bar"; }.a
|
||||||
```
|
```
|
||||||
|
|
||||||
evaluates to `"Foo"`. It is possible to provide a default value in an
|
This evaluates to `"Foo"`.
|
||||||
attribute selection using the `or` keyword:
|
|
||||||
|
It is possible to provide a default value in an attribute selection using the `or` keyword.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"
|
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"
|
||||||
|
|
Loading…
Reference in a new issue