Coding 2023-12-25
Okay. So. I'm in the middle of some kind of big weird rewrite regarding what used to be CommandBuilder and is currently Runner, because that name's not great, but it's better.
The actually important change is that I added a parameter to Runner to replace one of its Optional fields. The upshot of doing that locally is that I get to delete a conditional branch that was really bothering me. However, actually going through with this change incurs a lot of costs, and I figured I'd try to pay those costs before getting too attached to the benefits. Currently, I'm squirreled up in the parametric_command code.
Let's quick lay out what's going on there, because if I just try to touch the code without planning, I'll probably mess it up. So, there are two axes of variation I care about. They're on the ParametricCommand class, which has two fields: a ParametricCommandMeta[...], and a ParametricCommand[...] | SelectionDirectory[...].
Now that the ParametricCommandMeta class has a _runner.T parameter, it's necessary to look at how the actions there interact with the union members. The answer is, that if _runner.T is None, then the union can't be a ParametricCommand[...], because that branch of the union represents something being run as a module.
Now, the interesting question is whether the opposite case should also be disallowed. I'm going to go with a firm maybe: I should go with whatever makes the implementation easier.
And speaking of the implementation, if I'm going to change this union into something that keys off of the _runner.T, I'm going to need to write a parametric protocol to handle that, and to make that work, I'm going to need to write a wrapper class for the SelectionDirectory. Then, if I've got a protocol anyway, I might as well leverage it by rewriting all of the ParametricCommand methods that currently dispatch on the union branch into protocol methods.
Key note for my future self: because the wrapper class is going to basically be the newtype pattern, I don't need to explicitly expose the class to the rest of the code; I can just apply it in the with_directory() function, keeping the calling interface the same.
I think that covers everything I was thinking about. I'd try to do it now, but, as usual when I'm writing these, it's late.
Good night.