Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl function/sub best practice

Tags:

perl

I have a really quick question. I have a program with a lot of functions that are run from main. Is it best practice to have the functions first and then the call from main, or the other way around?

For example:

sub myFunction {
    #Do something
}

my $stuff = myFunction();

Or:

my $stuff = myFunction();

sub myFunction {
    #Do something
}

Sorry for any ignorance, I do not have any formal training and I have seen it done both ways online. Thanks

like image 825
CircuitB0T Avatar asked Mar 11 '15 19:03

CircuitB0T


2 Answers

I recommend placing your code at the bottom.

Issue 1

The latter snippet poor because myFunction is in scope of $stuff, but it shouldn't be. That's easy to fix though.

{
    my $stuff = myFunction();
}

sub myFunction {
    #Do something
}

Ok, so that's not a big issue since I place all top-level code in a block, even if it comes at the end. It looks cleaner to me that way, and it makes it easier to transform into a sub from which I can return.

sub myFunction {
    #Do something
}

sub main {
    return 0 if is_nothing_to_do();

    my $stuff = myFunction();
    ...

    return 0;
}

exit(main(parse_args));

Issue 2

Many languages require that you declare your subs before you call them. That's rarely needed in Perl, though there are a couple of scenarios where it is required. Subs with prototypes is one of those. If you wanted to place your code at the top, you would need to add declarations even before that.

sub myFunction(&@);

{
    my $stuff = myFunction { ... } ...;
}

sub myFunction(&@) {
    #Do something
}

You probably never have to do that since all but some rare uses of prototypes is discouraged, and the other scenarios are even rarer.

Issue 3

You might accidentally skip initialization code by placing your top-level code before your subroutines.

Compare:

print my_counter(), "\n";  # Warns, then prints a blank line

...

{
   my $counter = 1;
   sub my_counter {
      return $counter++;
   }
}

...

and

...

{
   my $counter = 1;
   sub my_counter {
      return $counter++;
   }
}

...

print my_counter(), "\n";  # Prints 1

Issue 4

Many languages require that you declare your subs before you call them, so more people will be more familiar with having the top-level code at the bottom.

like image 76
ikegami Avatar answered Nov 13 '22 01:11

ikegami


It doesn't matter, so long as you're able to find the code that you need to find. I typically like to set up my code like this:

use strict;
use warnings;

exit main();

sub main {
    do_this();
    dont_do_that();
    cant_you_read_the_signs();

    return 0;
}

sub do_this {
    ....
}

...

Putting your main code in an actual function or block called "main" helps keep you from polluting the program with globals.

like image 30
Andy Lester Avatar answered Nov 13 '22 00:11

Andy Lester