问题
To call a Nix function that uses set destructuring, you need to pass it a set with exactly the keys it requires, no more and no less:
nix-repl> ({ a }: a) { a = 4; b = 5; }
error: anonymous function at (string):1:2 called with unexpected argument ‘b’, at (string):1:1
The exception to this is if the function's argument list contains an ellipsis at the end:
nix-repl> ({ a, ... }: a) { a = 4; b = 5; }
4
However, most of the packages in nixpkgs consist of a default.nix
file containing a function which is not defined with this ellipsis. Yet, somehow when you use callPackage
, it manages to call these functions and pass them only the arguments that they need. How is this implemented?
回答1:
There is a reflection primop, that can deconstruct function argument:
nix-repl> __functionArgs ( { x ? 1, y }: x )
{ x = true; y = false; }
callPackage
then iterates over those attribute names, fetches required packages and constucts the attrset of packages, that is fed later to called function.
Here's a simple example:
nix-repl> callWithExtraArgs = f: args:
let
args' = __intersectAttrs (__functionArgs f) args;
in
f args'
nix-repl> callWithExtraArgs ({ x }: x + 1) { x = 4; y = 7; }
5
来源:https://stackoverflow.com/questions/46083266/how-does-nixs-callpackage-call-functions-defined-without-an-ellipsis