【发布时间】:2019-12-28 12:26:40
【问题描述】:
我无法理解Nix Pill 14。作者提供makeOverridable,然后挑战用户与callPackage集成。提供makeOverridable和default.nix,如下,其中makeOverridable在文件lib.nix中,callPackage在文件default.nix中:
# file: lib.nix
rec {
makeOverridable = f: origArgs:
let
origRes = f origArgs;
in
origRes // { override = newArgs: makeOverridable f (origArgs // newArgs); };
}
# file: default.nix
let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
callPackage = path: overrides:
let f = import path;
in f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
pkgs = with nixpkgs; {
mkDerivation = import ./autotools.nix nixpkgs;
hello = callPackage ./hello.nix { };
graphviz = callPackage ./graphviz.nix { };
graphvizCore = callPackage ./graphviz.nix { gdSupport = false; };
};
in pkgs
这是我想出的:
# file: default.nix (my implementation)
let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
callPackage = path: overrides:
let
f = import path;
origRes = f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
in
origRes // { override = newArgs: callPackage f (overrides // newArgs); };
pkgs = with nixpkgs; {
mkDerivation = import ./autotools.nix nixpkgs;
hello = import ./hello.nix {};
graphviz = import ./graphviz.nix {};
graphvizCore = graphviz.override { gdSupport = false; };
};
in pkgs
我认为我对这里发生的事情有一个根本的误解。您能否提供正确的实现并解释我做错了什么?
编辑:我设法让它工作,但是,它仍然不是递归的。
# file: default.nix
let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
callPackage = path: overrides:
let
f = import path;
origArgs = f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
makeOverridable = { override = newArgs: (origArgs // newArgs); };
in
origArgs // makeOverridable;
pkgs = with nixpkgs; rec {
mkDerivation = import ./autotools.nix nixpkgs;
hello = callPackage ./hello.nix { };
graphviz = callPackage ./graphviz.nix { };
graphvizCore = graphviz.override { gdSupport = false; };
};
in pkgs
编辑 2:
# file: default.nix
let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
makeOverridable = f: origArgs:
let origRes = f origArgs;
in origRes // { override = newArgs: makeOverridable f (origArgs // newArgs); };
callPackage1 = path: overrides:
let f = import path;
in f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
callPackage = makeOverridable callPackage1;
pkgs = with nixpkgs; {
mkDerivation = import ./autotools.nix nixpkgs;
hello = callPackage ./hello.nix { };
graphviz = callPackage ./graphviz.nix { };
graphvizCore = graphviz.override { gdSupport = false; };
};
in pkgs
解决方案:
# file: default.nix
let
nixpkgs = import <nixpkgs> {};
allPkgs = nixpkgs // pkgs;
makeOverridable = f: origArgs:
let origRes = f origArgs;
in origRes // { override = newArgs: makeOverridable f (origArgs // newArgs); };
callPackage1 = path: overrides:
let f = import path;
in f ((builtins.intersectAttrs (builtins.functionArgs f) allPkgs) // overrides);
callPackage = path: makeOverridable (callPackage1 path);
pkgs = with nixpkgs; rec {
mkDerivation = import ./autotools.nix nixpkgs;
hello = callPackage ./hello.nix { };
local_graphviz = callPackage ./graphviz.nix { };
graphvizCore = local_graphviz.override { gdSupport = false; };
graphvizCore2 = graphvizCore.override { gdSupport = false; };
};
in pkgs
【问题讨论】:
-
您对
makeOverridable的定义是错误的。您链接到的文档给出了两个定义,一个递归工作,一个不递归。你也没有使用。
标签: functional-programming nix nixos