views:

154

answers:

4

I do a lot of programming in Perl and was wondering if people had a "default" template Perl script that they use and willing to share.

I started copying one of my older scripts which has Getopt functions. I am thinking people would have done something similar?

+1  A: 

Mine is pretty simple.

#!/usr/bin/perl
use Modern::Perl

When it comes to things like getopt, there aren't enough commonalities among the scripts I write to make it worth while having a more verbose template.

David Dorward
Bleh, great suggestion, [but `Modern::Perl` doesn't enough...](https://rt.cpan.org/Public/Bug/Display.html?id=43061)
Evan Carroll
You might want to make that `#!/usr/bin/perl` or even `#!/usr/bin/env perl`.
Chas. Owens
@Evan — that's subjective
David Dorward
@Chas — no, not for the systems I target primarily.
David Dorward
@David Dorward, I don't think so... Read the bug report. Those modules aren't turned on, not because they wouldn't make perl *more* modern, but because they don't ship with Perl. Or, the case of `utf8` for reasons unmentioned. Or, presumably for `unicode_strings`, because the version of Perl that went stable 5 months ago is *too* modern. Is `Modern::Perl` good? Yes. Is it good enough.... probably not to be the end-all perl template.
Evan Carroll
There is no such thing as "the end-all perl template". Just a template that suits a given purpose.
David Dorward
+3  A: 

When I need a basic template for many similar scripts, I just turn the similar parts into a module. The script then reduces to something like:

 use App::Foo;

 App::Foo->run( @ARGV );

The App::Foo would inherit from the template module and override whatever was different:

 package App::Foo;
 use parent qw(App::Template);

 ...

In the App::Template module, you put in whatever you need:

 package App::Template;

 sub run {
    my( $class, @args ) = @_;

    my $self = $class->new( ... );
    $self->init;
    $self->process_command_line( ... );

    ...
    }


 sub process_command_line { ... }

 ...

There are some frameworks on CPAN for this sort of thing, but I think it's just as easy to do it yourself and get exactly what you need without dealing with the parts you don't need.

brian d foy
+2  A: 

In my .vimrc file I have

au BufNewFile *.pl s-^-#!/usr/bin/perl\r\ruse strict;\ruse warnings;\r\r-

which writes

#!/usr/bin/perl

use strict;
use warnings;

to any new Perl script. I also have

au BufNewFile *.pm s-^-package XXX;\r\ruse strict;\ruse warnings;\r\r1;-

for modules, but I tend to use Module::Starter for those anyway.

Chas. Owens
Perhaps an ignorant question, but why `\r` rather than `\n`?
Telemachus
@Telemachus Because that is what works? Vim can be a strange beast sometimes.
Chas. Owens
@Chas That's what I get for not testing. Yet another thing about Vim I never knew (noticed, came across) before. For other visitors, see http://stackoverflow.com/questions/71323/how-to-replace-a-character-for-a-newline-in-vim and http://stackoverflow.com/questions/71417/why-is-r-a-newline-for-vim
Telemachus
In perl 5.11, use strict; is default when use 5.11.0;
mhambra
@mhambra Well, since Perl 5.11 is a dev version, it is probably better to say in Perl 5.12 `strict` is turned on by default if you say `use 5.012;`. Unfortunately, I still write a lot of code for Perl 5.8, so I have not updated my template yet.
Chas. Owens
+1  A: 

As people say before I have my methods templates in a module: use PMG::PMGBase; and for the initial script escafolding, as an emacs user, I have my perl-insert-start and perl-add-getoption templates, but writing things like:

(defun perl-insert-start ()
  "Places #!..perl at the start of the script"
  (interactive)
  (goto-char (point-min))
  (insert "#!/usr/bin/env perl\n\n")
  (insert "=head1 [progam_name]\n\n")
  (insert " description:\n\n")
  (insert "=cut\n\n")
  (insert "use feature ':5.10';\n")
  (insert "use strict;\n")
  (insert "#use warnings;\n")
  (insert "#use Data::Dumper;\n")
)

is a bit tiresome. So at the end is easier for me to have a Perl template script (see below), and call it with run-command-on-region: C-u M-| :~/scripts/perl-start-template.pl from Emacs after selecting one space in a blank buffer:

#!/usr/bin/env perl

=head1 [progam_name]

 description:

=cut

use feature ':5.10';
use strict;
use Getopt::Long;

my $prog = $0;
my $usage = <<EOQ;
Usage for $0:

  >$prog [-test -help -verbose]

EOQ

my $help;
my $test;
my $debug;
my $verbose =1;


my $ok = GetOptions(
                    'test'      => \$test,
                    'debug:i'   => \$debug,
                    'verbose:i' => \$verbose,
                    'help'      => \$help,
                   );

if ($help || !$ok ) {
    print $usage;
    exit;
}


print template();


sub template {
    ##
    ### Here start the template code
    ##
    return <<'EOT';
#!/usr/bin/env perl

=head1 [progam_name]

 description: This script prints a template for new perl scripts

=cut

use feature ':5.10';
use strict;
#use warnings;
#use Data::Dumper;
use Getopt::Long;
# use Template;
# use PMG::PMGBase;  
# use File::Temp qw/ tempfile tempdir /;
# use File::Slurp;
# use File::Copy;
# use File::Path;
# use File::Spec;
# use File::Basename qw(basename dirname);
# use List::Util qw(reduce max min);
# use List::MoreUtils qw(uniq indexes each_arrayref natatime);

# my $PMGbase = PMG::PMGBase->new();
my $prog = $0;
my $usage = <<EOQ;
Usage for $0:

  >$prog [-test -help -verbose]

EOQ

my $date = get_date();

my $help;
my $test;
my $debug;
my $verbose =1;

my $bsub;
my $log;
my $stdout;
my $stdin;
my $run;
my $dry_run;

my $ok = GetOptions(
                    'test'      => \$test,
                    'debug:i'   => \$debug,
                    'verbose:i' => \$verbose,
                    'help'      => \$help,
                    'log'       => \$log,
                    'bsub'      => \$bsub,
                    'stdout'    => \$stdout,
                    'stdin'     => \$stdin,

                    'run'       => \$run,
                    'dry_run'   => \$dry_run,

                   );

if ($help || !$ok ) {
    print $usage;
    exit;
}

sub get_date {

    my ($day, $mon, $year) = (localtime)[3..5] ;

    return my $date= sprintf "%04d-%02d-%02d", $year+1900, $mon+1, $day;
}

sub parse_csv_args {

    my $csv_str =shift;
    return [split ',', $csv_str];
}

EOT


}
Pablo Marin-Garcia