Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Creating module files from subroutines

by Anonymous Monk
on Apr 17, 2001 at 14:40 UTC ( [id://73092]=perlquestion: print w/replies, xml ) Need Help??

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

Hi there... this is my first post, but I've been dabling with Perl for the last few months. I'd appreciate any help with moving subroutines to module files. I've got a number of perl scripts I use to organise and manipulate data collected by SNMP calls. A lot of the individual subroutines are reused in the different scripts. I'd like to move the subroutines to a .pm file so that adminstration of the subroutines will be centralised. An example subroutine that I'd like moved is below. Could someone provide some direction on what changes I'd need to make so that I could access this subroutine from a pm file. Thanks a million - Gearoid.
sub SendMail { my ($title) = $_[0]; my ($message) = $_[1]; my ($techname); @recipients = ("pat", "paul", "peter"); foreach $techname (@recipients){ system ("echo '$message' | mail \"techname\@company.com\" -s \"$title\ +""); } }

Replies are listed 'Best First'.
Re: Creating module files from subroutines
by Dominus (Parson) on Apr 17, 2001 at 15:54 UTC
    I suggest that you take a look at The Very Very Short Tutorial About Modules. It has an extremely simple example of a module---the complete code, including the module and the program that uses it, is only nine lines long. There are also a set of exercises which you can do or ignore. Probably looking at the example module and running the program will be enough of an example for you to do the same thing to your own functions.

    --
    Mark Dominus
    Perl Paraphernalia

Re: Creating module files from subroutines
by frankus (Priest) on Apr 17, 2001 at 14:57 UTC

    There are a good few conventions for making modules and, perlmod is a bit too condensed to learn it IMHO, although an excellent reference.

    Sadly most of the knowledge I've gleemed on this subject is in the pages of Debugging Perl, The Perl Cookbook and Object Oriented Perl, so I can't readily submit URL's for the salient points, all these books give a well rounded look at modules and their creation and use, from different angles, with little overlap. If I had to point to one book to use, for this and other reasons it'd be the Cook Book. HTH.

    Your code might benefit from indentation and you don't need the brackets around the variables being declared.

    You might lessen your future efforts further by making the functions more generic, maintainable and robust:

    • Passing the list of recipients as a array reference. Try a closure so you can set up the recipients once. If it is static.
    • Consider whether prototypes are useful, in some cases you can use them to enforce correct use of your functions.
    • Add validation as far as possible. Unless this is purely for your own benefit, it is polite to inform users of why things have failed. So to that end consider returning the results from the system call.
    • Add Pod to the functions or perhaps good commenting, examples of usage, and such.

    You were asking for Module specific stuff, and I fear I may be repeating things, you already know. A more precise set of goals to enable you to get `moduled' are:

    1. Learn how to set the module in a remote and common directory. @INC, use lib or -i
    2. Decide which functions are private or public. use Exporter and @Exporter
    3. Ensure your code is legible and well commented. Here is a good place to begin.
    4. Look to CPAN to see if what you're doing has already been done.

    <Hint to="greater Perl Monks" type="pretty big one">It is funny that there is no tutorial for modules in Tutorials</Hint>

    --
    
    Brother Frankus.
Re: Creating module files from subroutines
by Caillte (Friar) on Apr 17, 2001 at 14:58 UTC

    The first thing you must do is read through the perlmod documentation so you understand exactly what it is modules do and how they interact with the calling program. I would also recommend strongly that you read the entry on the @INC variable in perlvar. Understanding this is also important.

    After that, determine the directory structure and name for your module, like Mymods/Thismod.pm, create the file and place your subs within the skeleton below:

    package Mymods::Thismod; ### YOUR CODE GOES HERE ### 1;

    If you have read the documentation recommended then this will all come clear to you.

    Update Make sure you read through frankus' post above too, all the comments he makes about your code are well worth following.

    $japh->{'Caillte'} = $me;

Simpler alternative to modules
by gregw (Beadle) on Apr 17, 2001 at 15:54 UTC
    If you don't want the trouble of converting your scripts to .pm modules, but you can share a bunch of subroutines across multiple scripts by 1) putting them in a separate file (say snmplib.pl) 2) adding a 1; to the end of the snmplib.pl file, and 3) putting a code fragment at the beginning of scripts which would call those subroutines like
    BEGIN { require "/var/www/cgi-bin/snmplib.pl"; }
    . It's not as elegant as modules and it's not particularly mod_perl friendly, but it works and is imho quicker to implement. (It is true that global variables in the two files are accessible to each other with this approach, not encapsulated and filtered through well-defined EXPORT interfaces, but you may or may not care about that depending on how your code works.) Perhaps some more experienced monk will tell you (and me) why not to do it this simple way.
      If you do this you will quickly encounter the following problems:
      1. Tracking down where a routine comes from will become difficult.
      2. Scripts will reuse variables and subroutine names unbeknownst to you, and they will collide.
      3. Because of hardcoded paths it will be very hard for you to test any changes without modifying production.
      4. Without a clear division between executable and non-executable code, people are likely to put actions into scripts where they do not belong.
      In addition the speed difference between doing the above and doing it right with modules is insignificant if you have ever learned to write modules.

      So here is a template for stealing routines from existing code and putting them into a procedural module.

      1. Decide what module the routine belongs in. If the answer is none that you have, start a new module.
      2. To start a new module create a file Foo.pm, and in it type the following template:
        package Foo; use Exporter; @ISA = 'Exporter'; @EXPORT_OK = qw(); use strict; # Your subs will go here. 1;
        The word "Foo" must match the module name (with the usual conversion between the package separator :: and the path /).
      3. Copy the subroutine into the module.
      4. Put the name of the subroutine in the @EXPORT_OK list.
      5. Comment out the original subroutine.
      6. Put use Foo qw(sub_name); back in the original script.
      7. Test. (Often the subroutine will have dependencies that also need to go into the module.)
      8. Roll out.
      As for the location of modules, that is what lib is for. I personally have a custom configuration loader that will (among other things) transparently do the right lib invocations for me. In development pick up my copy of stuff in CVS. In production pick up the production copy of the same. The exact layout and development of that kind of functionality is a site decision. (Having this available has made testing and development much easier...)
Re: (Zigster) Creating module files from subroutines
by zigster (Hermit) on Apr 17, 2001 at 14:47 UTC
    Checkout perldoc perlmod for details of how to create a module it is not too hard. A quick gander at Super Search reveals loads of other nods covering this topic. I dont want to fob you off but I would suggest that you have a look there. If anything is still not clear come back.

    Happy Perling.
    --

    Zigster

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://73092]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (7)
As of 2024-04-23 21:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found