nix/doc/manual/source/language/string-interpolation.md
John Ericson eb7d7780b1 Rename doc/manual{src -> source}
This is needed to avoid this
https://github.com/mesonbuild/meson/issues/13774 when we go back to
making our subproject directory `src`.
2024-10-14 11:21:24 -04:00

5.0 KiB

String interpolation

String interpolation is a language feature where a string, path, or attribute name can contain expressions enclosed in ${ } (dollar-sign with curly brackets).

Such a construct is called interpolated string, and the expression inside is an interpolated expression.

Syntax

interpolation_element${ expression }

Examples

String

Rather than writing

"--with-freetype2-library=" + freetype + "/lib"

(where freetype is a derivation), you can instead write

"--with-freetype2-library=${freetype}/lib"

The latter is automatically translated to the former.

A more complicated example (from the Nix expression for Qt):

configureFlags = "
  -system-zlib -system-libpng -system-libjpeg
  ${if openglSupport then "-dlopen-opengl
    -L${mesa}/lib -I${mesa}/include
    -L${libXmu}/lib -I${libXmu}/include" else ""}
  ${if threadSupport then "-thread" else "-no-thread"}
";

Note that Nix expressions and strings can be arbitrarily nested; in this case the outer string contains various interpolated expressions that themselves contain strings (e.g., "-thread"), some of which in turn contain interpolated expressions (e.g., ${mesa}).

To write a literal ${ in an regular string, escape it with a backslash (\).

Example

"echo \${PATH}"
"echo ${PATH}"

To write a literal ${ in an indented string, escape it with two single quotes ('').

Example

''
  echo ''${PATH}
''
"echo ${PATH}\n"

$${ can be written literally in any string.

Example

In Make, $ in file names or recipes is represented as $$, see GNU make: Basics of Variable Reference. This can be expressed directly in the Nix language strings:

''
  MAKEVAR = Hello
  all:
  	@export BASHVAR=world; echo $(MAKEVAR) $${BASHVAR}
''
"MAKEVAR = Hello\nall:\n\t@export BASHVAR=world; echo $(MAKEVAR) $\${BASHVAR}\n"

See the documentation on strings for details.

Path

Rather than writing

./. + "/" + foo + "-" + bar + ".nix"

or

./. + "/${foo}-${bar}.nix"

you can instead write

./${foo}-${bar}.nix

Attribute name

Attribute names can be interpolated strings.

Example

let name = "foo"; in
{ ${name} = 123; }
{ foo = 123; }

Attributes can be selected with interpolated strings.

Example

let name = "foo"; in
{ foo = 123; }.${name}
123

Interpolated expression

An expression that is interpolated must evaluate to one of the following:

  • a string

  • a path

  • an attribute set that has a __toString attribute or an outPath attribute

    • __toString must be a function that takes the attribute set itself and returns a string
    • outPath must be a string

    This includes derivations or flake inputs (experimental).

A string interpolates to itself.

A path in an interpolated expression is first copied into the Nix store, and the resulting string is the store path of the newly created store object.

Example

$ mkdir foo

Reference the empty directory in an interpolated expression:

"${./foo}"
"/nix/store/2hhl2nz5v0khbn06ys82nrk99aa1xxdw-foo"

A derivation interpolates to the store path of its first output.

Example

let
  pkgs = import <nixpkgs> {};
in
"${pkgs.hello}"
"/nix/store/4xpfqf29z4m8vbhrqcz064wfmb46w5r7-hello-2.12.1"

An attribute set interpolates to the return value of the function in the __toString applied to the attribute set itself.

Example

let
  a = {
    value = 1;
    __toString = self: toString (self.value + 1);
  };
in
"${a}"
"2"

An attribute set also interpolates to the value of its outPath attribute.

Example

let
  a = { outPath = "foo"; };
in
"${a}"
"foo"

If both __toString and outPath are present in an attribute set, __toString takes precedence.

Example

let
  a = { __toString = _: "yes"; outPath = throw "no"; };
in
"${a}"
"yes"

If neither is present, an error is thrown.

Example

let
  a = {};
in
"${a}"
error: cannot coerce a set to a string: { }

       at «string»:4:2:

            3| in
            4| "${a}"
             |  ^