Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

To module or not?

by bradcathey (Prior)
on Apr 26, 2005 at 13:58 UTC ( #451574=perlquestion: print w/ replies, xml ) Need Help??
bradcathey has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monasterians,

I need a little help to understand the importance of using a module in it's official form or not. Thanks to tachyon's tutorial I've successfully coded my first working module.

package MyModule2; #line 1 use strict; use Exporter; our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = (); @EXPORT_OK = qw(add_it); %EXPORT_TAGS = ( All => [qw(&add_it)]); # line 11 sub add_it { my $amount = shift; my $total = 12+ $amount; return ($total); } 1;

Which is called by:

#!/usr/bin/perl -w print "Content-type: text/html\n\n"; #use lib "/home/jdsakroc/public_html/admin/cgi-bin"; use strict; use warnings; use CGI::Carp qw(fatalsToBrowser); use MyModule2 qw(:All); my $amount = 12; print add_it($amount),"\n";

But, the following works as well (minus the first 11 lines of orig.)

sub add_it { my $amount = shift; my $total = 12+ $amount; return ($total); } 1;

Which is called by:

use MyModule; my $amount = 12; print add_it($amount),"\n";

Question is: What is the point of creating the module with all the header stuff, when I can just save the function in a ______.pm file and use it like that? How clueless is this? Thanks!

Update: Thanks all, I'm getting it now ;-) In one word: "namespace." I can see how similiarly named functions would collide if the namespace was the same.


—Brad
"The important work of moving the world forward does not wait to be done by perfect men." George Eliot

Comment on To module or not?
Select or Download Code
Re: To module or not?
by tlm (Prior) on Apr 26, 2005 at 14:06 UTC

    Good question++. Your second pared-down version of the module just adds one more sub to the main package. Try adding the line

    package MyModule;
    at the top of the second version, and see what happens.

    the lowliest monk

      Just to comment a little further...

      The whole purpose of a module is to give you your own namespace, so you don't have to compete with the main program or other modules for subroutine names. So that's why you put "package MyModule;" at the top... to get your own namespace.

      The Exporter stuff allows users of your module to selectively import your subs into their namespace, so they don't have to type "MyModule::addit" if they don't want to.

        I wouldn't say that is the whole purpose of a module... the purpose of package is to give you a namespace, the purpose of modules is reusable code :)

                        - Ant
                        - Some of my best work - (1 2 3)

Re: To module or not?
by Fletch (Chancellor) on Apr 26, 2005 at 14:11 UTC

    The point of all the extra Exporter gunk as well as the package declaration is to put the code into its own separate namespace. Sure for your simple one sub it's overkill, but when you get more and more subs it'll make your life much easier.

    • You'll be able to selectively import specific subs (or sets of subs via tags) into your namespace rather than getting everything from the file unconditionally
    • You can specifically refer to different subs which may have the same name (not an issue here, but what if you had something with a more common name, e.g. both MyModule::send and MyOther::send)
    • You'll already have started establishing good habits of compartmentalizing your code
    • The maintenence programmer who follows in your footsteps n months from now won't curse your name and invest in a voodoo doll.

      A follow up question might be: is there a way to have global variable shared between the main::space and the module::space so I don't have to keep passing the same values over and over? (I know, not a good idea, but just for the sake of discussion)

      So, instead of:

      #MAIN: my $foo = "aaaaaaa"; my $bar = "bbbbbb"; print add_strings ($foo, $bar);

      Be able to just have:

      #MAIN: my $foo = "aaaaaaa"; my $bar = "bbbbbb"; print add_strings (); #MODULE: our ($foo, $bar); #this might be make-believe add_strings { my $newstring = $foo . $bar; return ($newstring); }

      —Brad
      "The important work of moving the world forward does not wait to be done by perfect men." George Eliot

        You could always reference $main::foo et al, but you'd have to use our $foo in main rather than my (lexicals not living in the symbol table and all).

        But yeah, not a good idea. Action at a distance, and what not.

Re: To module or not?
by japhy (Canon) on Apr 26, 2005 at 14:17 UTC
    In your case, there's not much of a problem. The reason modules (and namespaces) exist is becuse related functions belong packaged together, and you should have ability to use a function from another namespace that might end up conflicting with a function in your namespace.

    If you had an add_it() function that you didn't want overwritten, you could use your module as

    use MyModule; print MyModule::add_it($amount);
    And when multiple modules have the same function names (this is most common with classes -- objects, I mean), they need to be able to keep their own functions separate to themselves.

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: To module or not?
by kiat (Vicar) on Apr 26, 2005 at 15:17 UTC
    Hi Brad,

    I'm not answering your question directly but just wanted to reply and add that modules have helped me in the following ways:

    (1) code reuse

    - subs in ModuleA used by other modules

    (2) better code organisation

    (3) fixed one, fixed all

    - a bug can be traced to a particular module and when it's fixed, it's solved for all modules that use it.

    (4) easier code maintenance

    Added

    If you've done some Flash, putting subs in modules is like placing images in the library. You can recycle the images any number of times. And when you make a change to an image in the library, the change is effected in all the raw flash files that use it.

Re: To module or not?
by Forsaken (Friar) on Apr 26, 2005 at 21:20 UTC
    Aside from namespace there's also other concerns, like kiat before me mentioned, such as code reusability, maintainability etc.

    To give a practical example from my own experience, a while ago I asked the esteemed monks for help on a problem concerning unbuffered socket reading. Some really good advice was given there(as always), and I decided to set out to create my own way of reading unbuffered socket data into an artificial buffer so as to process it on a line by line basis. But, the solution I was going to create for this might very well be something I'd want to use elsewhere as well, hey, someone else might even have use for it, so it made sense to give the solution its own package.(reusability) Besides, the entire solution was probably going to be a rather sizable chunk o' code which I really didn't want to have half way my main project when I could have it conveniently tucked away in its own little corner.(maintainability). An additional advantage to it being its own module is that if for some reason I were in a crunch for time(which I am not, considering Perl is a project of love, not work-related for me) I'd be able to deploy what I have now and set out to improve the underlying code later on without having to change the calling script.

    As a side note to your own example, note that quite often it is completely unnecessary to use Exporter at all. It can be convenient, often even appropriate, but hardly ever necessary.

    Anyway, after this rather sizable rant *grin* here's the actual module just to give you an idea. It's mostly untested and still under development, so don't hold it against me ;-)

    Remember rule one...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://451574]
Approved by dorko
Front-paged by tlm
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2014-08-31 08:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (294 votes), past polls