in reply to Perl Tk - propagating events

Forgive me as I trot out an old, tired, and yet still very relevant cliche: KISS.

Yes, pTk (and Perl in general) provide lots of clever ways to do things, esp. for propagating events. And they're very convenient if an app is 100 lines or less in size.

But when dealing with large scale apps, with lots of GUI components and HMI interactions, I've learned the hard way that keeping to simple disciplines is a far better solution than trying to implement every clever bit of minimalist sigilism.

I've developed a large scale IDE for database apps in Perl and pTk. At first, it was very organic: model and view were all tangled up together. That worked OK when there were 4-5 distinct HMI functions. But the logic got very convoluted after that. Ultimately, I took 3 or more big steps back and rewrote the app to completely separate the GUI from the app logic. As in isolating the View code completely, and explicitly routing all the GUI events to the model through an imperative controller interface.

No, its not sexy. And its a bit more code, It even starts looking like Java at times. It makes me cringe a bit every time I think about the overhead of passing events and responses back and forth through a Controller object.

But every time I put it away for 3 months, and then go back to do some maintenance, I can quickly dive back in. Perhaps as importantly, I'm in the process of converting everything to a browser based solution, and its much easier to focus on just the view components, and XHR all the interactions back to the model.

My advice is to avoid the pitfall of trying to be too clever. Perl and pTk provide many opportunities to use short cuts. They're great for golfing quick solutions to simple problems to impress friends and coworkers. But in the arena of large scale GUI apps, its probably best to let the right and left cranial lobes each focus on the things they do well, and implement a simple bridge between them. Within their hemispheres, feel free to minimize as much as you like; but trying to optimize by declaratively leaking GUI event dispatch into the model will eventually become a liability.

Replies are listed 'Best First'.
Re^2: Perl Tk - propagating events
by vkon (Curate) on Jun 15, 2006 at 08:39 UTC
    But in the arena of large scale GUI apps, ...

    Some years ago I also discovered that perl/Tk isn't suitable for large scale GUI apps, because its syntax too verbose and immediately after some widgets are packed, I have a forest of unmaintainable code.

    Things went more smoothly after I started creating apps a bit differently, namely I used to separate GUI and logic, and write GUI with pure Tcl/Tk, after that use Tcl::Tk CPAN module to connect GUI to Perl.

    This approach required some learning of Tcl/Tk, so took some efforts.
    But I never regret that, and the only regret I have is why I did not moved to Tcl::Tk earlier.

    While Tcl is a very different beastie compared to Perl, and may be not suitable for many tasks where Perl is the right choice, Tcl/Tk is very suitable for GUI, much more than perl/Tk do.

      My comments were not specifically about pTk vs. Gtk2 vs. Tcl::Tk vs. whatever (that debate has been repeatedly thrashed out on ptk@lists.Stanford.edu and clp.tk - frankly, if it had usable documentation, I'd use wxPerl), but instead about a design philosophy and the pitfalls of using shortcuts early on (usually in the form of burying Model logic in closures assigned to GUI event dispatches).

      The same pitfalls exist in Web app development in the form of Templating systems and/or languages that encourage burying Model logic inside HTML. That capability is great for quickly cranking out a few pages that slam some forms into a DBMS. But when the application starts expanding, and the page contents and navigation get complicated, that approach also starts to suffer from the forest v. trees problem, as well as the ripple effect when minor changes are made to either the view or the model.

      Some years ago I also discovered that perl/Tk isn't suitable for large scale GUI apps,

      Perl/Tk is perfectly suitable for large scale apps (I know it is; I've seen me do it). Tcl::Tk probably is too. (tho tracking down widgets for it tends to be much more of a chore than just hopping over to CPAN). wxPerl is probably also a capable solution. And now my personal preference is for browser based AJAX/Javascript solutions. But when model logic gets muddled up with view logic, they will all suffer from both tangled complexity, maintenance ripple effects, and probably GUI lock-in.

      So, to reiterate: isolate view logic from the model, and avoid clever code (e.g., pseudo-events, or GUI dispatched closures loaded with model logic, etc.)

        I agree on all points,
        I did not intended to compare pTk vs. Gtk2 vs. Tcl::Tk (this time:), rather I wanted to mention a way of factoring out GUI and separating it from logic.
        but I probably have lost control of myself :):)

        addition WRT pTk vs. Gtk2 vs. Tcl::Tk, usually it goes differently: when pTk vs. Tcl::Tk are compared then people explain that Gtk is even better and finish reasoning :):)
        (although pTk and Tcl/Tk have very much in common and Gtk is very different)
        BR,
        vkon

        I've tried to separate Content from View from Model. I have a pretty firm grip on this approach in a web-app context. The app I am writing about is a desktop app that polls a group of sensors and displays the data collected (among other things).

        I modeled things along the CMV principle by creating a set of libraries that abstract interaction with the sensors. As I split things up, the Content is the raw data from the sensors; the Model is libraries that control the sensors, and the View is my big collection of GUI code. Most of my code (little surprise here) is in the GUI.

        The communications library takes allows the calling program to register a 'monitor' function that is in charge of scheduling polling of my input buffers and passing data back to the rest of the codebase. That's the only place that Model touches View.

        Each element of the GUI code, say for example a display panel, is a vanilla perl object (in this case a blah::blah::blah::Display::Panel object). Each display pannel has some attributes it uses to store it state, GUI elements and references to shared data. I considered building MegaWidgets to handle this type of task, but I decided to keep my options open (which you and zentara) seem to agree was the right idea.

        Right now I could rip out pTk and replace it with another GUI library with minimal pain. Some of my objects might need some new attributes, or others might be removable. Probably the hardest thing would be making sure that all my callbacks are getting called with the right data.

        If I read the various replies correctly, they are an endorsement of my current approach and advise against making any changes.

        I wish I could share more of my code and get a more detailed commentary, alas, it is proprietary (and not legally mine).

        Thank you for your thoughts.

        PS. As to the maintainability of large pTk apps, it can be done. I've been living with the current incarnation of this app for about 8 months and have needed to come back and make changes on several occasions, each time has been painless. However, the first version of this same application was impossible to work on--I wrote the core of it (my first big pTk app) under considerable time pressure. Due to other projects that kept me busy, some changes were handed off to a contractor who bolted on some less than pretty code (although my code was cluttered and ugly to begin with). The poor thing rapidly evolved into the famous big-ball of mud pattern and had to be put down. My current code base is built on the painful lessons learned there.

        PPS. As to pTk vs other libraries, I considered switching very carefully, but the better documentation and widget library has kept me with pTk, warts and all. wxPerl looks very tempting, as does Prima, Gtk2, and Tcl::Tk. When I have some spare time I'll look into these options again.


        TGI says moo