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

O venerable Monks,
I often have perl subroutines which I would like to call from other perl routines as well as use on the command line and I'm not quite sure what the best way to do this is.

As an example say that I have a sub called "avg3" which takes as input an 3 element array and returns the average. Writing the sub is trivial of course and I could call is from other perl scripts using the call $avg = avg3(@some_array). What I usually do is pool several perl subroutines in the same file say "avg_routines.pl".

However I would also like to use "avg3()" from the command line like so
cat some_file_holding3numbers.txt |  avg_routines.pl (+some way of specifying avg3())> avg.txt

Any help or comments welcome. Thanks

Malcolm

Replies are listed 'Best First'.
Re: routine as subroutine and on command line
by little (Curate) on Jan 18, 2002 at 16:01 UTC
    Command line tool coding style? might be an interesting read.
    And further you might use search for "command line" or in that way.

    Have a nice day
    All decision is left to your taste
Re: routine as subroutine and on command line
by count0 (Friar) on Jan 18, 2002 at 19:39 UTC
    It sounds like you're crying out for modules (or better, object classes ;)

    If you need to be calling only certain subroutines from the command line, this is the ideal (imo) way to go.
    Instead of avg_routines.pl, make it AvgRoutines.pm. This will also require changing parts of it (adding a 'package' line to the top, at least) to turn it into its own package.

    Here's a simple example:
    package AvgRoutines; sub avg3 { # ... code ... } 1;
    See Simple Module Tutorial for a simple introduction to modules, if you need it. For a more technical primer, see perlmod.

    Now, with it being its own module you can call just the sub you need from the command line *or* from other scripts (by use'ing it).

    cat some_file_holding3numbers.txt | perl -I'.' -MAvgRoutines -pe 'AvgRoutines::avg3($_)' > avg.txt
    See perlrun for any help with those command line switches.
Re: routine as subroutine and on command line
by Zaxo (Archbishop) on Jan 18, 2002 at 16:04 UTC
    $ perl -e '$n++, $sum += $_ while <>; print $sum/$n,$/' some_file_holding3numbers.txt

    That assumes the numbers are one to a line in the file

    After Compline,
    Zaxo

      fore!
      % perl -ple'$;+=$_}{$_=$;/$.' 3numbers.txt

      -Blake

Re: routine as subroutine and on command line
by talexb (Chancellor) on Jan 18, 2002 at 19:49 UTC
    Your original command line was
    cat some_file_holding3numbers.txt | avg_routines.pl (+some way of spe +cifying avg3())> avg.txt
    The more usual way of forming that is
    perl -w avg_routines.pl (+some way of specifying avg3()) <some_file_ho +lding3numbers.txt >avg.txt
    That aside, if the routine you wanted to use was inside the existing script, you could name the routine on the command line then use
    my $Routine = shift; # Get routine name from cmd line &{ $Routine }; # Call named routine
    to actually run it (I haven't tried this code -- this is just something to get you pointed in the right direction). This routine would then read input from the command line via the diamond operator while (<>), average the three numbers and output the average using print.

    If the code's in another module, you'll have to include the module name with the routine name, and either use it within your script or bring it in using the -M command line argument for Perl.

    This sounds like an awfully complicated way to do something fairly simple. What problem are you really trying to solve?

    --t. alex

    "Of course, you realize that this means war." -- Bugs Bunny.

      I'd just like to shout out my strong reccomendation against using symbolic references (or typeglobs in this fashion)! =)

      It has been my experience that code like this quickly becomes less than maintainable.
      If one were to take this approach (as opposed to modules), a dispatch table would be much more desirable.