makeScope
lib.makeScope
Make an attribute set (a "scope") from functions that take arguments from that same attribute set. See for how to use it.
Inputs
-
newScope(AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a)A function that takes an attribute set
attrsand returns what ends up ascallPackagein the output.Typical values are
callPackageWithor the output attributenewScope. -
f(AttrSet -> AttrSet)A function that takes an attribute set as returned by
makeScope newScope f(a "scope") and returns any attribute set.This function is used to compute the fixpoint of the resulting scope using
callPackage. Its argument is the lazily evaluated reference to the value of that fixpoint, and is typically calledselforfinal.See for how to use it. See for details on fixpoint computation.
Output
makeScope returns an attribute set of a form called scope, which also contains the final attributes produced by f:
scope :: {
callPackage :: ((AttrSet -> a) | Path) -> AttrSet -> a
newScope = AttrSet -> scope
overrideScope = (scope -> scope -> AttrSet) -> scope
packages :: AttrSet -> AttrSet
}
-
callPackage(((AttrSet -> a) | Path) -> AttrSet -> a)A function that
- Takes a function
p, or a path to a Nix file that contains a functionp, which takes an attribute set and returns value of arbitrary typea, - Takes an attribute set
argswith explicit attributes to pass top, - Calls
fwith attributes from the original attribute setattrspassed tonewScopeupdated withargs, i.e.attrs // args, if they match the attributes in the argument ofp.
All such functions
pwill be called with the same value forattrs. - Takes a function
-
newScope(AttrSet -> scope)Takes an attribute set
attrsand returns a scope that extends the original scope. -
overrideScope((scope -> scope -> AttrSet) -> scope)Takes a function
gof the formfinal: prev: { # attributes }to act as an overlay onf, and returns a new scope with values determined byextends g f. See for details.This allows subsequent modification of the final attribute set in a consistent way, i.e. all functions
pinvoked withcallPackagewill be called with the modified values. -
packages(AttrSet -> AttrSet)The value of the argument
ftomakeScope. -
final attributes
The final values returned by
f.
Examples
Create an interdependent package set on top of pkgs
The functions in foo.nix and bar.nix can depend on each other, in the sense that foo.nix can contain a function that expects bar as an attribute in its argument.
let
pkgs = import <nixpkgs> { };
in
pkgs.lib.makeScope pkgs.newScope (self: {
foo = self.callPackage ./foo.nix { };
bar = self.callPackage ./bar.nix { };
})
evaluates to
{
callPackage = «lambda»;
newScope = «lambda»;
overrideScope = «lambda»;
packages = «lambda»;
foo = «derivation»;
bar = «derivation»;
}
Using callPackage from a scope
let
pkgs = import <nixpkgs> { };
inherit (pkgs) lib;
scope = lib.makeScope lib.callPackageWith (self: { a = 1; b = 2; });
three = scope.callPackage ({ a, b }: a + b) { };
four = scope.callPackage ({ a, b }: a + b) { a = 2; };
in
[ three four ]
evaluates to
[ 3 4 ]
Type
makeScope :: (AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a) -> (AttrSet -> AttrSet) -> scope
Noogle detected
Implementation
The following is the current implementation of this function.
makeScope =
newScope: f:
let
self = f self // {
newScope = scope: newScope (self // scope);
callPackage = self.newScope { };
overrideScope = g: makeScope newScope (extends g f);
packages = f;
};
in
self;