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

Hey-lo Monks,

Today I began the journey of Subroutines and I got this very weird thought in my head. I began comparing subroutines with modules. I first did a bit of research via PerlMonks and came across Simple Module Tutorial to try and understand the inner workings of modules. I could only skim over because I am not yet on that level of comprehension.

So in this, I was wondering if subroutines and modules generally work the same way within a program. I read that a subroutine can be recycled as much as you would like within a program. Is a module not used as a recyled block of code as well? So, then I looked around for a simple definition of a Module and came across this one:

"A portion of a program that carries out a specific function and may be used alone or combined with other modules of the same program." (answers.com)

I am still reading up on both as I write this, but I was hoping a few could clarify and help me see the line between subroutines and modules. Article and tutorials are greatly appreciated.
Thanks

Es gibt mehr im Leben als Bücher, weißt du. Aber nicht viel mehr. - (Die Smiths)"

Replies are listed 'Best First'.
Re: Subroutines vs Modules
by Ovid (Cardinal) on Dec 30, 2005 at 02:43 UTC

    One useful way to think of a module is as a collection of related subroutines. They should be designed to be easy to use by any programmer without regards to the internals. Now think about a script which looks like this:

    #!/usr/bin/perl use warnings; use strict; my @files = find_files(shift); foreach my $file (@files) { eval { process_file($file) }; die "Could not process $file: $@" if $@; } sub find_files { .... } sub process_file { .... }

    With that, you have reused whatever code you have in &process_file. That's good. But what if another program needs the same functionality?

    package My::FileProcessor; use strict; use warnings; use base 'Exporter'; our @EXPORT_OK = qw(find_files process_file); sub find_files { .... } sub process_file { .... } 1;

    And your original code becomes this:

    #!/usr/bin/perl use warnings; use strict; use My::FileProcessor qw(find_files process_file); my @files = find_files(shift); foreach my $file (@files) { eval { process_file($file) }; die "Could not process $file: $@" if $@; }

    That code is now shorter, but more importantly, other programs can more easily share the functionality provided by My::FileProcessor.

    Does that help?

    Cheers,
    Ovid

    Ich verstehe nur ein bisschen Deutsch. -- Ovid.

    New address of my CGI Course.

      Ah, I see. If I am understanding this correctly, a module can be easily transported between programs of somewhat similar context and can be thought of as "universal" code. Whereas, subroutines are moreso used by the creator himself and is made for that program alone and not really thought to be exported to other programs. Am I getting warmer? :)


      Es gibt mehr im Leben als Bücher, weißt du. Aber nicht viel mehr. - (Die Smiths)"
        Slightly warmer, but you're still missing some pretty basic stuff.

        In Perl "subroutine" is just another name for a function. A function is a part of your program that you pass some arguments to, it does something, and it returns something. You might care about either the return or the action. For instance a logging function might write data to a file so you care what it does. Another function might perform a complex calculation, so you care what it returns.

        In Perl you declare a subroutine with the "sub" keyword, like this:

        # Declare it sub this_is_a_subroutine { # Your arguments are in @_. # Normally you'd do something more useful here. print "I'm doing something!\n"; return "This is a return value!\n"; } # Call it print this_is_a_subroutine(); # And here I'm going to terminate this program and # show you what output it would produce. __END__ I'm doing something! This is a return value!
        In this simple case the subroutine prints something and returns something else. Then the caller chose to print the other thing. So you see both values printed, with the returned value printed second.

        So you see, a subroutine has a very specific technical definition. Now a given subroutine might be very specific or general. It might be useful only in one program, or it might do something that lots of programs would like to take advantage of. Which will bring us to modules in a second.

        Subroutines are great. They allow you to structure your thoughts. In particular instead of writing 5-50 lines of code to do something you can write a function with a descriptive name, then call that function. A common problem in programming is that you can't see the forest for the trees - you see every detail about what is being done but have no idea what the point of any of it is. By organizing code into functions that have good names you manage to move things around so a high level view of what you're doing becomes more apparent.

        The alternative is that you cut and paste chunks of code. But now what happens if you correct a bug. Now you have to find everywhere that chunk got pasted and correct the bug in each place. Ugh. (In reality this doesn't happen and the same bug keeps on surfacing...)

        But for all of their strengths, subroutines could be better than what I've described. I've mentioned that some subroutines are useful in many different programs. But if you write them as part of the program, then you have to rewrite them for every program. That's where modules come in. Modules provide a place to put functions that can then be made available in many different programs without having to copy them to those programs. That's all a module is.

        Now nothing says that you have to organize your modules. You could just have a module called "my_functions", stick a ton of functions in there, and load it from everywhere. This works, but is a bad idea for the same reason that it is a bad idea for libraries to randomly put books on shelves wherever they happen to fit first.

        Instead it makes more sense when you put related functions together into a module so that there is some conceptual coherency. Now you know that all of your date manipulation routines are in Date::Time, your web download code is available from LWP::Simple, and your probability distributions are calculated by Statistics::Distributions. And more importantly if you're looking for a specific function, you know where to look so that you can find it, remember what the bloody thing was called, and figure out what you need to pass it!

        So in summary, a function is a piece of code that you can easily call from within your program. A module is a way to make a collection of functions available in many programs without having to rewrite the functions within each program. And it is a very good idea to give your functions names saying what they do, make them do that, and organize them into modules. (A great deal of becoming a good programmer is becoming good at organizing functions and modules.)

        ...a module can be easily transported between programs of somewhat similar context and can be thought of as "universal" code. Whereas, subroutines are moreso used by the creator himself and is made for that program alone and not really thought to be exported to other programs.

        you are looking at the consequences of modules vs. subroutines, and your observations are correct, but only because there are technical reasons that make them so

        Fundamentally speaking, a subroutine and the subroutines IN a module are identical (note that your "subroutine to module" comparison is not quite apples to apples)*, they differ by being subroutines that exist in different namespaces (aka., in perl, packages)

        it's because you can segregate your subroutines by namespace in this way that makes it easy to move the code between programs (and programmers) - it also helps that modules typically exist in separate files too (of course).

        *footnote: it's an easy mixup to make, because most modules present themselves as offering a single object, sometimes a single subroutine even

Re: Subroutines vs Modules
by rinceWind (Monsignor) on Dec 30, 2005 at 12:04 UTC

    One point that needs clarifying, that is not touched on in Ovid's or tilly's reply, is the definition of the term "module". A loose definition of a module, as a collection of related subroutines is useful for resolving the question, but may lead to confusion if you get deeper into the subject.

    The loose definition includes modules (*.pm), libraries, packages and distributions.

    libraries

    Putting your common reusable subroutines in a .pl file, a Perl library, is the traditional perl 4 way of doing things. Such libraries are loaded in at run time, using require 'foo.pl'.

    packages

    Suppose you are coding a Perl script that defines a subroutine called load_data. You are using the library common.pl which is a collective effort, and you don't know everything that it has inside. In particular, you don't know that your colleague Fred already has a sub called load_data.

    Packages avoid this problem by providing separate namespaces. Hence we might have Application::load_data and Reference::load_data as distinct, separate subroutines. So, this involves more typing, but provides a software development model which works better (the extra typing may be avoided by importing, see below).

    modules

    Perl 5 introduced the concept of Perl module (.pm) files, which may be "require"d at run time, but are more often "use"d at compile time (BEGIN time). Modules usually declare their own package namespace, but sometimes .pm files may populate more than one namespace.

    Importing of subroutine names is also available with "use".

    use MyModule::Clever qw(foo bar) ... my $wangle = foo('fleeg') . bar('dingle');

    In tbe "use" declaration, we have told MyModule::Clever that we want to import the subroutines foo and bar into our namespace.

    Modules can also provide an object orientated interface, but this is beyond the scope of this reply.

    distributions

    The tar ball kit that one downloads from CPAN is sometimes referred to as a module, but the correct term for this is a distribution. Distributions contain one or more modules, and also unit tests, documentation, example scripts, etc.

    --

    Oh Lord, won’t you burn me a Knoppix CD ?
    My friends all rate Windows, I must disagree.
    Your powers of persuasion will set them all free,
    So oh Lord, won’t you burn me a Knoppix CD ?
    (Missquoting Janis Joplin)

Re: Subroutines vs Modules
by pileofrogs (Priest) on Dec 30, 2005 at 17:02 UTC

    I'll weigh in with my really simple and largely inaccurate definitions:

    subrutine - a bit of code you can use over again

    module - a file containing subrutines

    I'm sure most monks are recoiling in horror at my definitions because they are basically wrong, BUT they do give the very basic point. Once you've digested these simple definitions, go back over the longer, more complex, more accurate definitions given earlier by others.

Re: Subroutines vs Modules
by sub_chick (Hermit) on Dec 30, 2005 at 19:23 UTC
    After reading all of these helpful replies, I decided to try out a subroutine and attempt to better understand the syntax by adding comment:
    #! /usr/bin/perl -w sub of_all_things { print "You called me!\n"; #will print this when called $one*$two; #Here are the workings that will return value } $one = 12; $two = 10; $three=&of_all_things; #return value $four=2*$three; #using the return value print "2 x 120 = $four\n";

    OUTPUT:
    You called me! 2 x 120 = 240

    This seems to work out on my box, but I am most concerned as to whether my comments are aiming at in the right direction?


    Es gibt mehr im Leben als Bücher, weißt du. Aber nicht viel mehr. - (Die Smiths)"
      That works but better practice (i.e. coding style, etc.) would be:
      #! /usr/bin/perl use strict; use warnings; #//////////////////////////////////////// sub whoami { print "Just entered subroutine ", (caller(1))[3], "\n"; return; } #//////////////////////////////////////// sub one_times_two { whoami(); my( $one, $two ) = @_; return $one * $two; } #//////////////////////////////////////// my $one = 12; my $two = 10; my $three = one_times_two( $one, $two ); my $four = 2 * $three; print "2 x $three = $four\n"; exit 0;
      With output:
      Just entered subroutine main::one_times_two 2 x 120 = 240
      Note: I beleive you need Perl 5.6 or greater for "use warnings".

      -- Argel

Re: Subroutines vs Modules
by bradcathey (Prior) on Dec 30, 2005 at 19:49 UTC

    I just asked a similar question a few days ago. I think you will find the thread informative.


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