How does Nix's “callPackage” call functions defined without an ellipsis?

这一生的挚爱 提交于 2020-01-03 08:48:33

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!