aboutsummaryrefslogtreecommitdiff
path: root/lib/attrsets.nix
diff options
context:
space:
mode:
authorzimbatm <zimbatm@zimbatm.com>2016-02-28 21:49:42 +0000
committerzimbatm <zimbatm@zimbatm.com>2016-03-09 19:59:57 +0000
commit523e3283189710a9a58bd2828f45a7413f3ede3e (patch)
tree4e6ee82c6def26146c53b0cd7d162356d56529a6 /lib/attrsets.nix
parenta086858ef51eb564a378424b21f677428a34fc9e (diff)
lib/attrsets: document all the functions
Diffstat (limited to 'lib/attrsets.nix')
-rw-r--r--lib/attrsets.nix137
1 files changed, 109 insertions, 28 deletions
diff --git a/lib/attrsets.nix b/lib/attrsets.nix
index f5184af42309..4161fa546c8f 100644
--- a/lib/attrsets.nix
+++ b/lib/attrsets.nix
@@ -12,9 +12,15 @@ rec {
inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr;
- /* Return an attribute from nested attribute sets. For instance
- ["x" "y"] applied to some set e returns e.x.y, if it exists. The
- default value is returned otherwise. */
+ /* Return an attribute from nested attribute sets.
+
+ Example:
+ x = { a = { b = 3; }; }
+ attrByPath ["a" "b"] 6 x
+ => 3
+ attrByPath ["z" "z"] 6 x
+ => 6
+ */
attrByPath = attrPath: default: e:
let attr = head attrPath;
in
@@ -24,8 +30,15 @@ rec {
else default;
/* Return if an attribute from nested attribute set exists.
- For instance ["x" "y"] applied to some set e returns true, if e.x.y exists. False
- is returned otherwise. */
+
+ Example:
+ x = { a = { b = 3; }; }
+ hasAttrByPath ["a" "b"] x
+ => true
+ hasAttrByPath ["z" "z"] x
+ => false
+
+ */
hasAttrByPath = attrPath: e:
let attr = head attrPath;
in
@@ -35,14 +48,28 @@ rec {
else false;
- /* Return nested attribute set in which an attribute is set. For instance
- ["x" "y"] applied with some value v returns `x.y = v;' */
+ /* Return nested attribute set in which an attribute is set.
+
+ Example:
+ setAttrByPath ["a" "b"] 3
+ => { a = { b = 3; }; }
+ */
setAttrByPath = attrPath: value:
if attrPath == [] then value
else listToAttrs
[ { name = head attrPath; value = setAttrByPath (tail attrPath) value; } ];
+ /* Like `getAttrPath' without a default value. If it doesn't find the
+ path it will throw.
+
+ Example:
+ x = { a = { b = 3; }; }
+ getAttrFromPath ["a" "b"] x
+ => 3
+ getAttrFromPath ["z" "z"] x
+ => error: cannot find attribute `z.z'
+ */
getAttrFromPath = attrPath: set:
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
in attrByPath attrPath (abort errorMsg) set;
@@ -109,9 +136,11 @@ rec {
) (attrNames set)
);
- /* foldAttrs: apply fold functions to values grouped by key. Eg accumulate values as list:
- foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
- => { a = [ 2 3 ]; }
+ /* Apply fold functions to values grouped by key.
+
+ Example:
+ foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
+ => { a = [ 2 3 ]; }
*/
foldAttrs = op: nul: list_of_attrs:
fold (n: a:
@@ -147,7 +176,12 @@ rec {
/* Utility function that creates a {name, value} pair as expected by
- builtins.listToAttrs. */
+ builtins.listToAttrs.
+
+ Example:
+ nameValuePair "some" 6
+ => { name = "some"; value = 6; }
+ */
nameValuePair = name: value: { inherit name value; };
@@ -248,11 +282,19 @@ rec {
listToAttrs (map (n: nameValuePair n (f n)) names);
- /* Check whether the argument is a derivation. */
- isDerivation = x: isAttrs x && x ? type && x.type == "derivation";
+ /* Check whether the argument is a derivation. Any set with
+ { type = "derivation"; } counts as a derivation.
+ Example:
+ nixpkgs = import <nixpkgs> {}
+ isDerivation nixpkgs.ruby
+ => true
+ isDerivation "foobar"
+ => false
+ */
+ isDerivation = x: isAttrs x && x ? type && x.type == "derivation";
- /* Convert a store path to a fake derivation. */
+ /* Converts a store path to a fake derivation. */
toDerivation = path:
let path' = builtins.storePath path; in
{ type = "derivation";
@@ -262,32 +304,49 @@ rec {
};
- /* If the Boolean `cond' is true, return the attribute set `as',
- otherwise an empty attribute set. */
+ /* If `cond' is true, return the attribute set `as',
+ otherwise an empty attribute set.
+
+ Example:
+ optionalAttrs (true) { my = "set"; }
+ => { my = "set"; }
+ optionalAttrs (false) { my = "set"; }
+ => { }
+ */
optionalAttrs = cond: as: if cond then as else {};
/* Merge sets of attributes and use the function f to merge attributes
- values. */
+ values.
+
+ Example:
+ zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}]
+ => { a = ["x" "y"]; }
+ */
zipAttrsWithNames = names: f: sets:
listToAttrs (map (name: {
inherit name;
value = f name (catAttrs name sets);
}) names);
- # implentation note: Common names appear multiple times in the list of
- # names, hopefully this does not affect the system because the maximal
- # laziness avoid computing twice the same expression and listToAttrs does
- # not care about duplicated attribute names.
+ /* Implentation note: Common names appear multiple times in the list of
+ names, hopefully this does not affect the system because the maximal
+ laziness avoid computing twice the same expression and listToAttrs does
+ not care about duplicated attribute names.
+
+ Example:
+ zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
+ => { a = ["x" "y"]; b = ["z"] }
+ */
zipAttrsWith = f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets;
+ /* Like `zipAttrsWith' with `(name: values: value)' as the function.
+ Example:
+ zipAttrs [{a = "x";} {a = "y"; b = "z";}]
+ => { a = ["x" "y"]; b = ["z"] }
+ */
zipAttrs = zipAttrsWith (name: values: values);
- /* backward compatibility */
- zipWithNames = zipAttrsWithNames;
- zip = builtins.trace "lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
-
-
/* Does the same as the update operator '//' except that attributes are
merged until the given pedicate is verified. The predicate should
accept 3 arguments which are the path to reach the attribute, a part of
@@ -351,6 +410,15 @@ rec {
!(isAttrs lhs && isAttrs rhs)
) lhs rhs;
+ /* Returns true if the pattern is contained in the set. False otherwise.
+
+ FIXME(zimbatm): this example doesn't work !!!
+
+ Example:
+ sys = mkSystem { }
+ matchAttrs { cpu = { bits = 64; }; } sys
+ => true
+ */
matchAttrs = pattern: attrs:
fold or false (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
let pat = head values; val = head (tail values); in
@@ -359,10 +427,23 @@ rec {
else pat == val
) [pattern attrs]));
- # override only the attributes that are already present in the old set
- # useful for deep-overriding
+ /* Override only the attributes that are already present in the old set
+ useful for deep-overriding.
+
+ Example:
+ x = { a = { b = 4; c = 3; }; }
+ overrideExisting x { a = { b = 6; d = 2; }; }
+ => { a = { b = 6; d = 2; }; }
+ */
overrideExisting = old: new:
old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] old.${attr} new)) (attrNames old));
+
+ /*** deprecated stuff ***/
+
deepSeqAttrs = throw "removed 2016-02-29 because unused and broken";
+ zipWithNames = zipAttrsWithNames;
+ zip = builtins.trace
+ "lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
+
}