Hacker News new | ask | show | jobs
by eigenvalue 998 days ago
Thanks for the feedback. I do use Paramiko for some things. I tried to use it for everything in the project but ran into some weird stuff that wouldn't work reliably for me, which is why I switched some of it over to using SSH directly via subprocess (it was a few months ago so I don't even remember now what it was; I believe it was also performance related, since I'm trying to SSH to tons of machines at the same time concurrently).

I guess I did forget to use the execute_network_commands_func. I'm using the ruff linter extension in VSCode now which would have flagged that to me, but back when I made this I wasn't.

I don't think globals are so awful for certain things. I prefer a more functional approach where you have simple composable standalone functions instead of classes. Obviously classes have a role, but I find they sometimes overly complicate things and make the logic harder to follow and debug.

Anyway, I do appreciate that someone took the time to actually read through the code!

1 comments

> I don't think globals are so awful for certain things. I prefer a more functional approach where you have simple composable standalone functions instead of classes. Obviously classes have a role, but I find they sometimes overly complicate things and make the logic harder to follow and debug.

But "globals" and "composable standalone functions" are contradictory, if you're mutating global state your function is neither composable nor standalone.

What you've got is a poor mans class instance using global instead of self.

It's a single script. Globals are fine--they're even marked as such.
> It's a single script

It's over 1200 lines of code, it's not like it's 100 lines of code and can fit on a single screen

> Globals are fine--they're even marked as such

I would argue that globals in this context are not fine from a code maintainability point of view.

By using globals here it's hard to know from a function call if it's going to mutate global state or not. If all the functions were methods of the same class instance, and other functions were just functions or part of some other class, then it gives you a clear grouping of calls which are related to mutating that state.

In general I would argue if you are ever in the situation of "I have more than two or three functions that are related to each other and they all need to mutate the same state so I use a mutable global" or "I pass around the mutable state via arguments" then make a class! It creates an obvious semantic grouping of callables.