[Nix-dev] variable scope / recursion
Shea Levy
shea at shealevy.com
Fri Jul 6 14:23:05 CEST 2012
Hi Mathijs,
I've not fully read the thread, but just so you know overrides are done with a special attribute called __overrides, which has a more confusing semantics than simply a rec. See https://github.com/NixOS/nix/blob/master/src/libexpr/eval.cc#L525 for some documentation, and the surrounding function has all the relevant code I think. Not sure if that particularly applies to your problem.
~Shea
On Jul 6, 2012, at 8:04 AM, Mathijs Kwik <mathijs at bluescreen303.nl> wrote:
> On Fri, Jul 6, 2012 at 1:43 PM, Kirill Elagin <kirelagin at gmail.com> wrote:
>> Yeah, now I get your problem.
>> It think, it's clear from the source of `applyGlobalOverrides` and from
>> comments, that your `packageOverrides` is called with _original,
>> non-overriden_ pkgs. This way you can to refer to _original_ attributes when
>> overriding them.
>
> Yeah I saw those comments too, but I can't see how that would work.
> Because the "original" (pkgsOrig) set is built by passing pkgs (the
> final set) to pkgsFun.
> In other words, the set references itself, which is perfectly normal
> in a lazy setting.
> The notion of "original" makes sense for the attributes that get
> overwritten, but for the rest, I would expect a "shine through".
>
>>
>> I think the only option is to manually simulate overriding process in
>> `packageOverrides` to obtain overriden pkgs.
>
> That would mean a modification to nixpks, and maintaining a separate
> fork forever, which is what I want to avoid.
>
>>
>>
>> --
>> Кирилл Елагин
>>
>>
>> 2012/7/6 Mathijs Kwik <mathijs at bluescreen303.nl>
>>>
>>> Maybe I better explain what I'm trying to achieve.
>>>
>>> I have a bunch of packages and overrides that aren't very useful for
>>> others, so I can't commit them to nixpkgs.
>>> I don't want to constantly maintain my own "fork" that I need to keep
>>> up-to-date, but rather use the current "channels" functionality.
>>>
>>> So I figured it's easiest to just use packageOverrides to apply the
>>> modifications and to add the additional packages.
>>>
>>> This works fine for almost everything, but I want to structure my
>>> additional packages more like nixpkgs itself (use directories and
>>> callPackage). Ideally, I don't want to distinguish between nixpkgs and
>>> my own pkgs, so the scope for callPackage needs to be the composition
>>> of nixpkgs with my own stuff.
>>>
>>> But it seems I can't get a reference to the final nixpkgs attrset
>>> within the overrides function...
>>>
>>> Any hints?
>>>
>>> Thanks,
>>> Mathijs
>>>
>>>
>>>
>>> On Fri, Jul 6, 2012 at 12:10 PM, Mathijs Kwik <mathijs at bluescreen303.nl>
>>> wrote:
>>>> On Fri, Jul 6, 2012 at 12:01 PM, Kirill Elagin <kirelagin at gmail.com>
>>>> wrote:
>>>>> rec is the answer (this is something like let/letrec in Lisp, if you
>>>>> know
>>>>> what I mean ;) ).
>>>>
>>>> I don't see how rec would help here.
>>>> As I understand it, rec helps when an attrset has attributes that
>>>> refer to each other.
>>>> But in this case, bar isn't referring to foo in the same object (the
>>>> overrides object I'm creating, containing just foo and bar), but to
>>>> pkgs.foo.
>>>>
>>>> Anyway, I tried it anyway:
>>>> packageOverrides = pkgs:
>>>> rec { foo = "string";
>>>> bar = pkgs.foo + " concatenation";
>>>> };
>>>>
>>>> But this does not help.
>>>> Still "missing attribute foo".
>>>>
>>>>
>>>>>
>>>>> --
>>>>> Кирилл Елагин
>>>>>
>>>>>
>>>>> 2012/7/6 Mathijs Kwik <mathijs at bluescreen303.nl>
>>>>>>
>>>>>> Hi all,
>>>>>>
>>>>>> I was reading this interesting piece of all-packages.nix
>>>>>> (comments/whitespace removed):
>>>>>>
>>>>>> applyGlobalOverrides = overrider:
>>>>>> let
>>>>>> overrides = overrider pkgsOrig //
>>>>>> (lib.optionalAttrs (pkgsOrig.stdenv ? overrides && crossSystem
>>>>>> == null) (pkgsOrig.stdenv.overrides pkgsOrig));
>>>>>> pkgsOrig = pkgsFun pkgs {};
>>>>>> pkgs = pkgsFun pkgs overrides;
>>>>>> in pkgs;
>>>>>>
>>>>>> I'm familiar with tying-the-knot lazy trickery in haskell.
>>>>>> As pkgsOrig uses pkgs (the final end result including overrides), and
>>>>>> the overrider function gets passed pkgsOrig, I would expect the
>>>>>> following to work:
>>>>>>
>>>>>> packageOverrides = pkgs:
>>>>>> { foo = "string";
>>>>>> bar = pkgs.foo + " concatenation";
>>>>>> };
>>>>>>
>>>>>> However, it complains about foo missing.
>>>>>> What am I missing?
>>>>>>
>>>>>> Thanks,
>>>>>> Mathijs
>>>>>> _______________________________________________
>>>>>> nix-dev mailing list
>>>>>> nix-dev at lists.science.uu.nl
>>>>>> http://lists.science.uu.nl/mailman/listinfo/nix-dev
>>>>>
>>>>>
>>> _______________________________________________
>>> nix-dev mailing list
>>> nix-dev at lists.science.uu.nl
>>> http://lists.science.uu.nl/mailman/listinfo/nix-dev
>>
>>
> _______________________________________________
> nix-dev mailing list
> nix-dev at lists.science.uu.nl
> http://lists.science.uu.nl/mailman/listinfo/nix-dev
More information about the nix-dev
mailing list