2017-09-06 17 views
6

Aby wywołać funkcję Nix, który wykorzystuje zestaw destructuring, należy przekazać go do zestawu z dokładnie klucze Wymaga ona, nie więcej i nie mniej:Jak zdefiniowane są funkcje wywoływania "callPackage" Nixa bez elipsy?

nix-repl> ({ a }: a) { a = 4; b = 5; } 
error: anonymous function at (string):1:2 called with unexpected argument ‘b’, at (string):1:1 

Wyjątkiem od tej zasady jest sytuacja, gdy argumentu funkcyjnego wykaz zawiera elipsę w końcu:

nix-repl> ({ a, ... }: a) { a = 4; b = 5; } 
4 

jednak większość z pakietów w nixpkgs składać pliku default.nix zawierającego funkcję, która nie jest zdefiniowane w tej elipsy. Jednak, kiedy używasz callPackage, udaje się wywoływać te funkcje i przekazywać im tylko te argumenty, których potrzebują. W jaki sposób jest to realizowane?

Odpowiedz

5

Jest primop odbicie, które mogą dekonstrukcji argumentu funkcji:

nix-repl> __functionArgs ({ x ? 1, y }: x) 
{ x = true; y = false; } 

callPackage następnie iteruje tych nazw atrybutów, pobiera wymagane pakiety i konstruktów dla nadania do attrset pakietów, który jest podawany później do wywołanej funkcji.

Oto prosty przykład:

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