I'm having a problem with some of the modules I find on CPAN lately, and wondering if others have the same issues.

It seems a lot of authors write one big module that do too much rather than a few modules in distinct useful parts.

Two examples (nothing personal toward any authors of modules below):

  1. CGI::FormBuilder looks like a great package, but I would really like to separate the form (HTML and JavaScript) generation code from the validation code and session management code. I would like to use a completely different take on session management (using cookies and saving state on the server, not in form values), and would like to use specialized functions rather than regular expressions to validate form fields.
  2. DBIx::SearchBuilder also looks useful (as someone pointed out to me in a recent post), but I need to separate the SQL-building function from the query-executing function, and absolutely do not want anything to do with recordsets since I need the database handle to do many other things and don't want the burden of multiple database connections for a script.

I'm sure there are many other examples.

Again, not to single out specific modules or authors. It's just that sometimes a module does so much that it makes more sense to write your own (oft criticized by some as misguided) than to accept severe limitations imposed by a module or to spend the time modifying another's code to work in distinct parts.

I suspect that's why there are a lot of modules that do similar things on CPAN. In a way, the diversity is very good. In another way, it's aggrevating to see that there are 47 modules that do something similar to what you need but never quite right.

I suspect that encouraging authors to break up their modules into distinct and more generalized pieces would help the situation.

So I'd like to open up a discussion on how other programmers deal with this issue...

  • Comment on The temptation to roll your own module than use an existing one....

Replies are listed 'Best First'.
Re: The temptation to roll your own module than use an existing one....
by lachoy (Parson) on Oct 25, 2001 at 07:38 UTC

    Everyone has their own itches to scratch. It would be nice if their scratcher worked on your itches, but it doesn't appear so. And I suspect that most people don't have the time to scratch your itches -- they have too many of their own.

    So the decision then becomes to adapt theirs or create yours. Working with people you've never met can be hard, especially when you're asking them to do more work, so you might as well create your own, right?

    But while your new module might start out focused and with an elegant idea of separating everything into nice neat little compartments, real life and complex problems often force messiness on us. What's insidious is that the messiness is a little bit here, a little bit there. And (being generous) I'd hazard a guess that this accumulation of messiness is one reason why publicly released modules get the way they do.

    IMO, the real flexible, elegant solutions for nontrivial problems have either been out for a while in some form or other (like the Template Toolkit) or have been designed by lots of smart people doing nothing else. There are exceptions of course (look at SOAP::Lite), but they prove my (just made up) rule.

    So what's my conclusion? I suppose if I wrote and supported one of these modules and you came to me with a request to separate some logical piece out, I'd take it with a grain of salt inversely proportional to the amount of work you're willing to put into it. Even if it's a good idea. There are an awful lot of good ideas floating around but no time for most of them.

    Such work doesn't even have to be implementation code -- why not write up some dummy code as to how you want something to work? Frequently it's easier to work backwards from the result than try and create it from thin air. And of course everyone loves people who write documentation...

    Related link: A defense of the NIH syndrome.

    (I've now used up my quota for the words 'itch' and 'scratch' for the rest of the year.)

    Chris
    M-x auto-bs-mode

Re: The temptation to roll your own module than use an existing one....
by hsmyers (Canon) on Oct 25, 2001 at 09:35 UTC

    You are talking about a problem that is as old as programming. In fact I expect that it started just as soon as the second person learned how to cut code. In a nutshell, it comes down to “How do you interface your code with someone else's code?” There are days when I suspect that all code is just one kind of interface or another— the rest of the time I'm sure of it! The examples you site demonstrate what I mean. You look in vain for their tab A to slip into your slot B, only to find out that all they have are round wooden pegs!

    Most times when you hear cubie discussions about interfaces, it is typically about what the user sees when he or she sits down to the application just developed. But that is hardly the only interface we deal with, and the design of every one of them bears directly on the problem you've noticed. We spend vast resources building GUIs but virtually nothing on designing code to be used by other programmers.

    Given the way most libraries, modules or what have you develops, it shouldn't come as a surprise that the only code reuser who gets a custom fit, is the one who wrote the code in the first place— pretty much what you would expect. In fact, one of the great ironies in programmer land is that this problem is usually made worse, the better the programmer who wrote it. The best programmers have a style of coding and if that style doesn't match yours, problems ensue. Whatever, most of the time, someone solves a problem (usually a difficult one, but not always) and the next thing you know its available to all comers. Could be free, could cost money, but by whatever means, you see it and shout hooray, 'cause you just know that it will solve the very problem that has been racking your brains for low these many thirty hour days, etc., etc., etc.

    And of course that is when you run into this little snag! You need low level functions, they only supply high level. You don't have time to build it, but they have only given you a zillion tiny pieces… Yadda, yadda, yadda, bitch, bitch, moan, moan. So— how do you solve this problem? Well you don't really, you just sort of live with it. At best, you can minimize things, at worst, do what you have to do.

    There are some things that help:

    • Treasure any code that you can use as is. In fact seek it out. Like the truth, it's out there, you just have to wade through the 90% that won't do you much good in order to find it.
    • Second, you can increase your chances of successful merger by seeking code that handles an entire problem domain, typically the more you can black box it, the easier the interface.
    • Learn the art of software triage. In this case, the pragmatic analysis of what will cost more, writing new, or rewriting to fit.
    • Moderate your expectations. There is not now, nor will there ever be, any such thing as a free lunch.
    • Don't let them grind you down! If the wheel doesn't fit, don't use it. If no one has something that will work, make your own. It is not re-inventing the wheel, it is just getting the job done.

    Here is one last piece of anecdote, I probably own at least a dozen books on building interfaces, but I've only found one1 on building software tools and libraries!

    hsm

    1“Building Custom Software Tools and Libraries” by Martin Stitt, John Wiley & Sons, New York, New York. 1993.

    Update: ISBN: 0471579149 see http://isbn.nu/0471579149/price

(jeffa) Re: The temptation to roll your own module than use an existing one....
by jeffa (Bishop) on Oct 25, 2001 at 09:09 UTC
    Instead of looking for that ONE module - consider looking for many modules and write some glue code to get the desired result. Sounds easy, right? However, in my frustration to find that ONE module, i wound up rolling my own and submitting it to CPAN - go figure. . .

    Now i am faced with a delima - creature feep. Example, i received an email from a person who modified my module in a rather cool way. Should i add the patch, or dismiss it due to 'loose cohesion'?

    i realize that i am now talking to myself - but i think you just inspired me to decompose my module into smaller ones, that way, i might just be able to incorporate this 'cool idea' presented to me as a specialized subclass.

    Thanks :)

    jeffa

Re: The temptation to roll your own module than use an existing one....
by FoxtrotUniform (Prior) on Oct 25, 2001 at 20:42 UTC

    I've been reading a fair bit on this lately, so while I'm certainly no expert, I do have a bunch of ideas fresh in my head.

    Seems to me that one good way to make code more reusable is to make its different elements orthogonal to each other: that is, as uncoupled as possible. So, to take your CGI::FormBuilder example, you'd have one function (or set of functions) for form generation, another for validation, and another for session tracking, but they wouldn't depend on each other: as long as you conformed to the interface, you'd be able to validate input from a form you wrote with a different package; session tracking wouldn't depend on any magic in the form generation code; and so on.

    The problem is, this is hard to achieve! You have to spend a lot of time thinking about the interfaces to your code. Writing orthogonal code often means that communicaton between two parts of the same module is more difficult than it would be if you could only share this one little bit of data... but that way lies madness, tight coupling, and endless hours of frustration for anyone who doesn't want to solve the exact problem you had in mind. I find it's useful to design interfaces from the perspective of a user who only wants to use the function you're writing: "I already have a form generator, I just want to do session tracking".

    (The problem with that approach is that the resulting code can get disjointed and generally inconsistent. Oh well. If I had all the answers, I'd be making tons of money as a software design consultant.)

    An excellent example of solid, orthogonal library design is the ccMath library. (It's ANSI C, not Perl, but the same principles hold.) I haven't worked with every part of it, but what I have worked with has been beautiful. No setup code, no gnarly data types, just call the function you need. And two books you might want to look at (in addition to the others already mentioned) are The Pragmatic Programmer (Hunt & Thomas, Addison Wesley) and The Practice of Programming (Kernighan & Pike, Addison Wesley).

    --
    :wq
Re: The temptation to roll your own module than use an existing one....
by AidanLee (Chaplain) on Oct 25, 2001 at 21:30 UTC