This thread will contain notes to myself. Topics will include Leo's code design its implication for program checking. Feel free to ignore.
It is becoming clear that the settings-related code in leoConfig.py and leoKeys.py urgently needs a significant revision. As I said just now in another thread, I plan to consider such a revision only after fixing the present serious key-related bug. Part 1: Refactoring the config code Leo's design is robust because Leo's modules (source files) are almost completely independent of each other. Classes and methods in one file typically do not know significant details about the internals of any other file. Continuing this design principle, classes (of whatever file) rarely need to know the details of other classes. The leoConfig module follows this general principle, but the module itself needs has become way too complex. It's time to create helper class to encapsulated these details. I am considering the following refactoring: 1. GlobalSettingsManager This class would control the creation of per-commander SettingsManager classes (see point 2). It would also contain all per-application data, such as the new immutable_x_settings_shortcuts_dict class vars. BTW, I usually consider class vars to be a symptom of a missing class. g.app.config might already be considered to be this class, but an explicit class will help, imo. By convention, the (singleton) object of this class will be denoted by gsm. 2. SettingsManager One per commander. c.config might already considered to be this class, but again a separate class will clarify what is going on. By convention, objects of this class will be denoted by sm. In particular, the various key dictionaries in leoKeys.py should be ivars of the SettingsManager class, and the various (complex) operations on those dictionaries should migrate into the SettingsManager class. The present code is "polluted" to a great degree by knowledge of the implementation details of those dict. This is another example of a pernicious catch-all class. Those details must be encapsulated in.... 3. KeyBindingsSet This class hides the representation of *all* of the various per- commander key-related dictionaries in leoKeys.py. Rather than being polluted with knowledge of these dictionaries, client code will know only about getters and setters of this class. kbs objects will compute the internal dictionaries (and their various inversions and other helper dictionaries) automatically, without external code having to become involved. This should simplify the init and update processes, which are at present way too infected with implementation knowledge. 4. KeyBinding and ModeBinding kbs objects manage collections of KeyBinding and ModeBinding objects, not just a random collection of dictionaries. 5. KeyName As discussed in another thread, a KeyName is a wrapper for all the various variants of strings that represent keystroke names. This is a surprisingly important class. The kbs object will probably provide getters that deliver various formatted versions of KeyName objects. Part 2: Implications for code checking One of my favorite saying "The essence of freedom is restraint". I thought Carl von Clausewitz said this, but apparently I was mistaken :-) Anyway, this is not some inscrutable koan. I take it to mean, "The essence of freedom is *self* restraint", which means that we become *more* free in our actions when we exercise significant self control. As a parent, I have delivered this message to both of my children :-) We parents grant more freedom to our offspring as they demonstrate that they have the self control to use the freedom wisely. As I have often said, we programmers act is if we *do* know the types of the objects we create. Recent experience with g.Bunch and string objects shows that this can be a dubious assumption. Imo, this should be a spur to *more* self restraint, not less. We want to create classes that facilitate significant analysis. This analysis may take several forms: - pylint deductions. - analysis scripts, including leoInspect scripts. - unit tests. In other words, the impossibility of analyzing *arbitrary* Python scripts and programs should spur us to us a *restricted* design and implementation vocabulary, so that we *can* say significant things about our programs. The challenge is to devise a fruitful interaction between our classes and our unit tests. Edward -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/leo-editor?hl=en.
