Okay @Tim DeHerrera I might have the next newbie question here :smile: In any other language I write that would be no problem for me, but in Nix it is somewhat weird to me.
This is related to me finally doing the network config setting to have them permanently fixed. I have my list of attrsets:
networkInterfaces = [
{ name = "enp4s0f0np0";
metric = 200; }
{ name = "enp4s0f1np1";
metric = 100; }
{ name = "enp6s0";
metric = 300; }
{ name = "enp7s0";
metric = 350; }
];
and I want to create this string
networking.dhcpcd.extraConfig = ''
interface enp4s0f0np0
metric 200
interface enp4s0f1np1
metric 100
interface enp6s0
metric 300
interface enp7s0
metric 350
'';
I think I got a bit lost in the plethora of string concatenation functions that are available ...
You want concatStringsSep
. ChatGPT solution (untested):
{
networkInterfaces = [
{ name = "enp4s0f0np0"; metric = 200; }
{ name = "enp4s0f1np1"; metric = 100; }
{ name = "enp6s0"; metric = 300; }
{ name = "enp7s0"; metric = 350; }
];
networking.dhcpcd.extraConfig = let
# Function to transform a single attribute set to a string
formatInterface = interface: ''
interface ${interface.name}
metric ${toString interface.metric}
'';
# Transform each attribute set and join them with newlines
formattedInterfaces = builtins.concatStringsSep "\n" (builtins.map formatInterface networkInterfaces);
in ''
${formattedInterfaces}
'';
}
yeah that looks plausible, I'll test it :smile:
Yeah, might be able to do it more "manually" with a fold. Can sometimes end up being quite elegant depending on the situation
you have an example?
On my phone arm, but I'll see if I can grab one
because elegance might help here, I feel that a good old c-style for-loop is easier to read
sure but for loops don't exist in the purely functional realm :grinning:
Here is a basic fold:
let
networkInterfaces = [
{
name = "enp4s0f0np0";
metric = 200;
}
{
name = "enp4s0f1np1";
metric = 100;
}
{
name = "enp6s0";
metric = 300;
}
{
name = "enp7s0";
metric = 350;
}
];
in
builtins.foldl' (acc: x:
''
interface ${x.name}
metric ${toString x.metric}
''
+ acc)
""
networkInterfaces
ends up being fairly similar to srids version
okay so what does networkInterfaces
in the very last line do?
But that looks a bit more concise
That is just the list of interfaces bound to a variable name. Are you generally familiar with how folds work? Essentially its a convenient mechanism in the purely functional style of accumulating values from a list into some other kind of data structure, in this case a string.
so foldl'
takes 3 args, the first is a function to show how to append each value to the accumulation of values, the second is the starting data structure, in this case an empty string, and the final argument is the list to fold
yeah now that starts making a bit more sense.
I guess I am just not purely functional enough (yet)
gonna try this later
Well understand maps and folds will get you pretty far on their own, so you are off to a good start
yeah, I mean maps I am fairly familiar with in other languages. But for some reason I find Nix always a bit more obscure to use.
Going back to my original problem, I figured I most likely have to go through networkmanager
to set the metric value, using dhcpd won't do the trick.
Last updated: Nov 13 2024 at 11:14 UTC