BUU has asked for the wisdom of the Perl Monks concerning the following question:

Simple question, partially inspired by Command line tool coding style?. In a simple decision hash tree thingy
my %hash=( opt1=>\&opt1, opt2=>\&opt2, opt3=>\&opt3,); &{$hash{$value}};
What about replacing the subs (sub opt1 {}, etc) with perl files? And your end answer would be do $hash{$value} ? Is this a bad idea? The reasoning for this would it would help to seperate implementation from logic (i hope), in that you would have a series of files for each option, as opposed to having to modify one file, as well as being able to swap in different files very easily. But, as far as i know, do is generally regarded as bad?

Replies are listed 'Best First'.
Re: Do file.pl (replacing subs?)
by BrowserUk (Patriarch) on Sep 23, 2002 at 05:54 UTC

    Interesting idea.

    I see two problems with it. The first is that while do 'file.pl'; looks neat and tidy, by the time you add the required error checking around each one it is less so and you'll find yourself wanting to wrap the error checking into a subroutine, which sort of defeats the purpose.

    The second is that the code will be reinterpreted and compiled each time you need to use it, which would dramatically slow your script down.

    You could avoid this by including the contents of the files using require 'file.pl'; but then you'd need to wrap the contents of the file in a subroutine so that you could call it more than once, or you have the same problems of reinterpreting it each time. Once you've wrapped it in a sub, your almost back to where you started, though it would achieve your aims of seperating "implementation from logic", but unless the routines in the files are going to be re-used in multiple programs, I would find it easier to maintain them all in a single file. And if they where to be re-used in multiple files, better to make it a module and use it.


    Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
      You have a point for your first two .. points. However, on your last point, the reason i stuck with do vs use was that it seemed visually clearer, so the reader would know that i'm attempting to execute code in a seperate file, as opposed to the common interpretation of use, which is that i'm attempting to import a module. However, use 'file.pl' would have the exact same effect with the benefit of error checking and so forth. Of course, a problem there is if you want to call a 'file' multiple times, i dont think multiple uses would execute the code multiple times.

      You have a point about just wrapping the file in a sub, but that seems to kind of defeat the purpose =/. You're right about the maintence of a whole folder full of subs, but that mostly holds true for local. If you were trying to remotely maintain something, and you improved one sub, you could just send out a new sub-file, and say 'replace file blah in your sub folder with this new file', as opposed to 'look in blah.pl, find line 952-1060 and replace them with this block of code..'

        I wouldn't trust anyone who doesn't know that use loads and imports a module to maintain code.

        I don't see a big distinction between executing code in a separate file and using a module.

        I have no problem sending the whole of an updated module, if necessary.

        Your situation doesn't seem appreciably different from what modules are intended to accomplish.

        you could just send out a new sub-file, and say 'replace file blah in your sub folder with this new file', as opposed to 'look in blah.pl, find line 952-1060 and replace them with this block of code..'
        diff / patch or rsync anyone? :-)

        Makeshifts last the longest.

Re: Do file.pl (replacing subs?)
by perrin (Chancellor) on Sep 23, 2002 at 16:34 UTC
    Putting every function in a separate file is not usually the way to go, since it tends to make maintenance harder, not easier. However, it is sometimes used to save memory and time by not compiling a bunch of code that doesn't usually get run. This is generally accomplished with the AutoLoader module, which automates the job of splitting the subs out into files.

    If you do decide to use a multi-file approach, I strongly recommend using "require" instead of "do" (for reasons already listed in this thread), and making the individual files separate packages with subs and nothing in their main:: space. This is a much cleaner way to do it, and avoids many problems with scoping and potential conflicts. Otherwise you'll have to keep track of which subs you have in each file and make sure you don't accidentally name two of the same, and ditto for global variables.