this post was submitted on 07 Sep 2023
9 points (100.0% liked)

nixos

1262 readers
1 users here now

All about NixOS - https://nixos.org/

founded 4 years ago
 

I'm trying to debug a module I'm writing with builtins.trace, but it's being more complicated than I anticipated.

Let's say I have a module:

{ config, lib, pkgs, modulesPath, ... }:

{

  config =
  let
    some-list = lib.attrsets.mapAttrsToList (n: v: {
        some-attr = "${n} ${v}";
    }) { n1 = "v1"; n2 = "v2"; };
  in {
    users.mutableUsers = builtins.trace (some-list) false;
  };

}

This will print

trace: [ <code> <code> ]

because builtins.trace (for whatever reason?) evaluates its first argument only shallowly.

Changing the trace expression to:

builtins.trace (builtins.toJSON some-list) false;

helps a lot, but as soon as one tries to print a long list or a structure with some complexity the output is completely unreadable, and it's not like it can easily be piped into jq (I mean... &amp;| grep ^trace: | sed 's/trace: //' | jq works*, but there must be a "better" way?)

(*) in fish shell, IDK about bash

edit: It's not like I specifically want JSON output: any format will do (ideally, nix would be nice)

top 4 comments
sorted by: hot top controversial new old
[–] [email protected] 3 points 1 year ago

Try builtins.deepSeq: something like builtins.trace (builtins.deepSeq some-list some-list) false

According to the manual, it evaluates its first argument deeply and returns the second.

[–] [email protected] 1 points 1 year ago* (last edited 1 year ago) (1 children)

The nix language is lazy by definition. In your example, the code on your let block is never fully evaluated (executed), because it is never needed. Hence, [ <code> <code> ] is the only possible outcome.

[–] [email protected] 1 points 1 year ago* (last edited 1 year ago) (1 children)

I figured that much :) I was wondering about the "best" (recommended? idiomatic?) way to get some decent/usable output instead of <code> or unformatted JSON (from builtins.toJSON).

[–] [email protected] 1 points 1 year ago

For simple things like this, I usually just use the REPL to prototype the function