Data is data. Code is logic. So the the thought process goes...
...what if I could store my configuration (data! right?!) in a way that is nicely separated from the logic?! No more scripting for me!
Oh wait. Some of the configuration can't be generalized about universally. Configurations fundamentally contain logic, I guess.
Oh, well then why don't I just represent the logic in the data?! That will be much better than representing the data in the logic!
....but now, you are back where you started, only instead of using something nice, standard, and powerful like Python, you have to use this... language... thing. This YAML convention you cooked up.
Separate the data from logic. Read the data into the logic. Make a nice organized place to call custom logic from... like, you know, a file directory full of scripts, which are called according to some scheme. It could be another data file. Stop there.
Like this:
$ ls -Ra
./config/do_something.yaml
./config/do_something_else.yaml
./config/config.yaml
./logs/ping.log
./scripts/do_something.py
./scripts/do_something_else.py
$ cat ./scripts/do_something.py
from stupid.library.task import Task, subscribe
class DoSomething(Task):
@subscribe
def ping(self, target):
return super().ping(target)
Then you code the program that runs collects all of the task methods, put them in an ordered list, and run them if the conditions in the config.yaml is met.
Every other thing is done in a task method in python, or something like it. I don't think we need more abstraction than that.
The whole idea being that you don't want the story to be turing complete (there are no loops or conditionals with a story), but the code that executes it needs to be turing complete.
Right, and it's not like it's ground breaking thinking here. It's just a matter of some personal restraint on your part to say, "No, I will not turn python into an interpreter for some disgusting yaml-based language."
Everyone agrees we hate this, until one day it's us who is dreaming it up, and we just can't resist! There should be no concept of "flow of execution", except for maybe expansion of previously declared variables just so you can do something like concatenating two lines together. Otherwise, the lack of logical operations will make even that unnecessary.
Well, knowing when the flexibility of turing complete language is required and when the simplicity of non-turing complete declarative language is required and where to draw the line between them is often pretty hard.
This is why we get YAML based languages that edge towards turing completeness with conditionals and loops and ugly templating hacks. Mostly people get it wrong. I got it wrong several times when creating two earlier versions of that framework.
...what if I could store my configuration (data! right?!) in a way that is nicely separated from the logic?! No more scripting for me!
Oh wait. Some of the configuration can't be generalized about universally. Configurations fundamentally contain logic, I guess.
Oh, well then why don't I just represent the logic in the data?! That will be much better than representing the data in the logic!
....but now, you are back where you started, only instead of using something nice, standard, and powerful like Python, you have to use this... language... thing. This YAML convention you cooked up.
Separate the data from logic. Read the data into the logic. Make a nice organized place to call custom logic from... like, you know, a file directory full of scripts, which are called according to some scheme. It could be another data file. Stop there.
Like this:
--- --- --- --- Then you code the program that runs collects all of the task methods, put them in an ordered list, and run them if the conditions in the config.yaml is met.Every other thing is done in a task method in python, or something like it. I don't think we need more abstraction than that.