3 ms·
Side note: - I don't understand why classes are needed here. instead of procedure = [ CreateSSHKeypairStep(), GitCommitStep(), Wai
by sullyj3 5y ago
Side note: - I don't understand why classes are needed here.
instead of
procedure = [
CreateSSHKeypairStep(),
GitCommitStep(),
WaitForBuildStep(),
RetrieveUserEmailStep(),
SendPrivateKeyStep(),
]
for step in procedure:
step.run(context)
Why not make them functions instead of classes. The URLs can be locals instead of class variables and the context argument becomes an argument to the function rather than a run method.
procedure = [
createSSHKeypairStep,
gitCommitStep,
waitForBuildStep,
retrieveUserEmailStep,
sendPrivateKeyStep,
]
for step in procedure:
step(context)
The OO is just gratuitous. Personally I probably wouldn't even bother with the for loop/context and would just pass the data that's actually needed by each function into it manually.
createSSHKeypairStep(username)
gitCommitStep(username)
waitForBuildStep()
email = retrieveUserEmailStep(username)
sendPrivateKeyStep(email)
I get that it feels more modular - "oh all I need to do to add a step is add it to the list!" But like, all you need to do to add a step is add a line of code. There's no difference.
Much easier to see how the data is actually flowing that way. I found the fact that the context was mutated in a function it was passed into kind of gross. It's just globals with extra steps. Besides, this is less LOC anyway.
- dullcrisp 5y agoI assume the point is to let any one of the steps turn into something more complex and automated, as they say, without affecting the rest of the script. If each step is its own class, that gives you a place to go in and expand any one of them without worrying about conflicting with unrelated changes. If the idea were to leave the script as it is, then of course your way is simpler.
- geysersam 5y agoI see what you mean. But in Python a function can be turned into a full fledged callable class at a later point without any change to the rest of the script. Not that it matters much either way.
- sullyj3 5y agoSeems like premature abstraction to me. It's not difficult to make that change if you need it. In any case, I'm really struggling to envisage a scenario where you would need them to be classes - why couldn't a more automatic version still be a function? In my opinion, in order to justify instantiating an object, it should actually contain data, and that data should actually be accessed by code other than methods internal to that class. This rules out using an object to represent a procedure - regular functions subsume that functionality. Before first class functions became commonplace, it did make sense to use objects as procedures in some OO languages, to allow you to pass them around as values. Since most languages these days do have first class functions, this has become less necessary. If you want a class in order to to split the procedure into multiple methods with access to shared mutable state, that's totally fine - you can just use nested functions to do the same thing.
- Juliate 5y agoYou might want/need to decompose each step in a set of contained smaller behaviors. This is a pattern easier to represent/embed within objects. But you might as well use a library of prefixed functions too.
- deleted 5y ago[deleted]
- gitgud 5y agoDevil's advocate; each class in the array has a consistent interface, making it easier to do common things every step like measurements and logging during iteration etc. But I agree with you, it's simpler to just call the functions only giving them what they need. This prevents them from implicitly depending on context and makes reasoning about the code much easier....
- deleted 5y ago[deleted]
- snthpy 5y agoI agree with you. I currently have a similar process where I jot down the steps in README.md or INSTRUCTIONS.md files. The script is a bit better in that it forces you to do the steps in order and you're less likely to skip a step by accident. However if I'm going to start creating scripts like this then I think all the OO/Class boilerplate overhead would make me reluctant to do it. For me using functions with docstrings keeps more of the simplicity of the markdown approach while still allowing for gradual automation. Here's a simple example: https://gist.github.com/snth/c5c5a1236dd8ddf91973aed77d66cd9a https://gist.github.com/snth/c5c5a1236dd8ddf91973aed77d66cd9...
- makapuf 5y agoLike someone said very wisely in a python talk*, a class with two functions,one of which is init, is a function. * https://pyvideo.org/pycon-us-2012/stop-writing-classes.html https://pyvideo.org/pycon-us-2012/stop-writing-classes.html
- xhevahir 5y agoFWIW the author of the post apparently uses Go for this: https://github.com/danslimmon/donothing https://github.com/danslimmon/donothing