* Lets, inheritance, assertions.
This commit is contained in:
parent
0b1ee4802b
commit
55b35d6d77
1 changed files with 171 additions and 10 deletions
|
@ -639,6 +639,10 @@ language.</para>
|
||||||
<filename>../xyzzy/fnord.nix</filename>, the absolutised path is
|
<filename>../xyzzy/fnord.nix</filename>, the absolutised path is
|
||||||
<filename>/foo/xyzzy/fnord.nix</filename>.</para></listitem>
|
<filename>/foo/xyzzy/fnord.nix</filename>.</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para><emphasis>Booleans</emphasis> with values
|
||||||
|
<literal>true</literal> and
|
||||||
|
<literal>false</literal>.</para></listitem>
|
||||||
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
@ -733,23 +737,85 @@ encountered</quote>).</para></footnote>.</para>
|
||||||
|
|
||||||
</simplesect>
|
</simplesect>
|
||||||
|
|
||||||
<!--
|
|
||||||
<para>It is often convenient to copy variables from the surrounding
|
|
||||||
scope (e.g., when you want to propagate attributes). This can be
|
|
||||||
shortened using the <literal>inherit</literal> keyword. For instance,
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<simplesect><title>Let expressions</title>
|
<simplesect><title>Let expressions</title>
|
||||||
|
|
||||||
<para>TODO</para>
|
<para>A <literal>let</literal> expression is a simple short-hand for a
|
||||||
|
<literal>rec</literal> expression followed by an attribute selection:
|
||||||
|
<literal>let { <replaceable>attrs</replaceable> }</literal> translates
|
||||||
|
to <literal>rec { <replaceable>attrs</replaceable>
|
||||||
|
}.body</literal>.</para>
|
||||||
|
|
||||||
|
<para>For instance,
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
let {
|
||||||
|
x = "foo";
|
||||||
|
y = "bar";
|
||||||
|
body = x + y;
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
is equivalent to
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
rec {
|
||||||
|
x = "foo";
|
||||||
|
y = "bar";
|
||||||
|
body = x + y;
|
||||||
|
}.body</programlisting>
|
||||||
|
|
||||||
|
and evaluates to <literal>"foobar"</literal>.
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
</simplesect>
|
</simplesect>
|
||||||
|
|
||||||
|
|
||||||
<simplesect><title>Inheriting attributes</title>
|
<simplesect><title>Inheriting attributes</title>
|
||||||
|
|
||||||
<para>TODO</para>
|
<para>When defining an attribute set itt is often convenient to copy
|
||||||
|
variables from the surrounding lexical scope (e.g., when you want to
|
||||||
|
propagate attributes). This can be shortened using the
|
||||||
|
<literal>inherit</literal> keyword. For instance,
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
let {
|
||||||
|
x = 123;
|
||||||
|
body = {
|
||||||
|
inherit x;
|
||||||
|
y = 456;
|
||||||
|
};
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
evaluates to <literal>{x = 123; y = 456;}</literal>. (Note that this
|
||||||
|
works because <varname>x</varname> is added to the lexical scope by
|
||||||
|
the <literal>let</literal> construct.) It is also possible to inherit
|
||||||
|
attributes from another attribute set. For instance, in this fragment
|
||||||
|
from <filename>all-packages-generic.nix</filename>,
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
graphviz = (import ../tools/graphics/graphviz) {
|
||||||
|
inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
|
||||||
|
inherit (xlibs) libXaw;
|
||||||
|
};
|
||||||
|
|
||||||
|
xlibs = {
|
||||||
|
libX11 = ...;
|
||||||
|
libXaw = ...;
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
libpng = ...;
|
||||||
|
libjpg = ...;
|
||||||
|
...</programlisting>
|
||||||
|
|
||||||
|
the attribute set used in the function call to the function defined in
|
||||||
|
<filename>../tools/graphics/graphviz</filename> inherits a number of
|
||||||
|
variables from the surrounding scope (<varname>fetchurl</varname>
|
||||||
|
... <varname>yacc</varname>), but also inherits
|
||||||
|
<varname>libXaw</varname> (the X Athena Widgets) from the
|
||||||
|
<varname>xlibs</varname> (X11 client-side libraries) attribute
|
||||||
|
set.</para>
|
||||||
|
|
||||||
</simplesect>
|
</simplesect>
|
||||||
|
|
||||||
|
@ -765,11 +831,106 @@ shortened using the <literal>inherit</literal> keyword. For instance,
|
||||||
|
|
||||||
<simplesect><title>Conditionals</title>
|
<simplesect><title>Conditionals</title>
|
||||||
|
|
||||||
<para>TODO</para>
|
<para>Conditionals look like this:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
if <replaceable>e1</replaceable> then <replaceable>e2</replaceable> else <replaceable>e3</replaceable></programlisting>
|
||||||
|
|
||||||
|
where <replaceable>e1</replaceable> is an expression that should
|
||||||
|
evaluate to a boolean value (<literal>true</literal> or
|
||||||
|
<literal>false</literal>).</para>
|
||||||
|
|
||||||
</simplesect>
|
</simplesect>
|
||||||
|
|
||||||
|
|
||||||
|
<simplesect><title>Assertions</title>
|
||||||
|
|
||||||
|
<para>Assertions are generally used to check that certain requirements
|
||||||
|
on or between features and dependencies hold. They look like this:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
assert <replaceable>e1</replaceable>; <replaceable>e2</replaceable></programlisting>
|
||||||
|
|
||||||
|
where <replaceable>e1</replaceable> is an expression that should
|
||||||
|
evaluate to a boolean value. If it evaluates to
|
||||||
|
<literal>true</literal>, <replaceable>e2</replaceable> is returned;
|
||||||
|
otherwise expression evaluation is aborted and a backtrace is printed.</para>
|
||||||
|
|
||||||
|
<example id='ex-subversion-nix'><title>Nix expression for Subversion</title>
|
||||||
|
<programlisting>
|
||||||
|
{ localServer ? false
|
||||||
|
, httpServer ? false
|
||||||
|
, sslSupport ? false
|
||||||
|
, pythonBindings ? false
|
||||||
|
, javaSwigBindings ? false
|
||||||
|
, javahlBindings ? false
|
||||||
|
, stdenv, fetchurl
|
||||||
|
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
|
||||||
|
}:
|
||||||
|
|
||||||
|
assert localServer -> db4 != null; <co id='ex-subversion-nix-co-1' />
|
||||||
|
assert httpServer -> httpd != null && httpd.expat == expat; <co id='ex-subversion-nix-co-2' />
|
||||||
|
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl); <co id='ex-subversion-nix-co-3' />
|
||||||
|
assert pythonBindings -> swig != null && swig.pythonSupport;
|
||||||
|
assert javaSwigBindings -> swig != null && swig.javaSupport;
|
||||||
|
assert javahlBindings -> j2sdk != null;
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "subversion-1.1.1";
|
||||||
|
...
|
||||||
|
openssl = if sslSupport then openssl else null; <co id='ex-subversion-nix-co-4' />
|
||||||
|
...
|
||||||
|
}</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<para><xref linkend='ex-subversion-nix' /> show how assertions are
|
||||||
|
used in the Nix expression for Subversion.</para>
|
||||||
|
|
||||||
|
<calloutlist>
|
||||||
|
|
||||||
|
<callout arearefs='ex-subversion-nix-co-1'>
|
||||||
|
<para>This assertion states that if Subversion is to have support
|
||||||
|
for local repositories, then Berkeley DB is needed. So if the
|
||||||
|
Subversion function is called with the
|
||||||
|
<varname>localServer</varname> argument set to
|
||||||
|
<literal>true</literal> but the <varname>db4</varname> argument
|
||||||
|
set to <literal>null</literal>, then the evaluation fails.</para>
|
||||||
|
</callout>
|
||||||
|
|
||||||
|
<callout arearefs='ex-subversion-nix-co-2'>
|
||||||
|
<para>This is a more subtle condition: if Subversion is built with
|
||||||
|
Apache (<literal>httpServer</literal>) support, then the Expat
|
||||||
|
library (an XML library) used by Subversion should be same as the
|
||||||
|
one used by Apache. This is because in this configuration
|
||||||
|
Subversion code ends up being linked with Apache code, and if the
|
||||||
|
Expat libraries do not match, a build- or runtime link error or
|
||||||
|
incompatibility might occur.</para>
|
||||||
|
</callout>
|
||||||
|
|
||||||
|
<callout arearefs='ex-subversion-nix-co-2'>
|
||||||
|
<para>This assertion says that in order for Subversion to have SSL
|
||||||
|
support (so that it can access <literal>https</literal> URLs), an
|
||||||
|
OpenSSL library must be passed. Additionally, it says
|
||||||
|
<emphasis>if</emphasis> Apache support is enabled, then Apache's
|
||||||
|
OpenSSL should much Subversion's. (Note that if Apache support is
|
||||||
|
not enabled, we don't care about Apache's OpenSSL.)</para>
|
||||||
|
</callout>
|
||||||
|
|
||||||
|
<callout arearefs='ex-subversion-nix-co-4'>
|
||||||
|
<para>The conditional here is not really related to assertions,
|
||||||
|
but is worth pointing out: it ensures that if SSL support is
|
||||||
|
disabled, then the Subversion derivation is not dependent on
|
||||||
|
OpenSSL, even if a non-<literal>null</literal> value was passed.
|
||||||
|
This prevents an unnecessary rebuild of Subversion if OpenSSL
|
||||||
|
changes.</para>
|
||||||
|
</callout>
|
||||||
|
|
||||||
|
</calloutlist>
|
||||||
|
|
||||||
|
</simplesect>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<simplesect><title>With expressions</title>
|
<simplesect><title>With expressions</title>
|
||||||
|
|
||||||
<para>TODO</para>
|
<para>TODO</para>
|
||||||
|
@ -791,7 +952,7 @@ shortened using the <literal>inherit</literal> keyword. For instance,
|
||||||
</simplesect>
|
</simplesect>
|
||||||
|
|
||||||
|
|
||||||
<simplesect><title>Miscelleneous built-in functions</title>
|
<simplesect><title>Other built-in functions</title>
|
||||||
|
|
||||||
<para>TODO</para>
|
<para>TODO</para>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue