summaryrefslogblamecommitdiff
path: root/posts/2009-06-22-modules-i-like-getopt-long-and-moosex-getopt.org
blob: 02b090367bd4d9853a2cceac1dc7ca66e6755493 (plain) (tree)








































































































































                                                                        
** Getopt::Long

[[http://search.cpan.org/perldoc?Getopt::Long][Getopt::long]] is a
useful module to parse command line arguements.

A basic usage is something like this:

#+BEGIN_SRC perl
    #!/usr/bin/perl -w
    use strict;
    use YAML::Syck;
    use Getopt::Long;

    GetOptions('config=s' => \my $cfg_file,);

    my $config = LoadFile $cfg_file
#+END_SRC

In *GetOptions*, we require a value for config with *config=s*. If we
wante an integer, we replace 's' with 'i', and for a floating point,
with 'f'.

Call your script :

#+BEGIN_EXAMPLE
    % script.pl --config=file.yml #this one works
    % script.pl --config file.yml #this one too!
    % script.pl -c file.yml       #and this one too
#+END_EXAMPLE

The three syntaxes are understood.

A good practices is to combine this module with
[[http://search.cpan.org/perldoc?Pod::Usage][Pod::Usage]]. Let's do some
modifications on the example:

#+BEGIN_SRC perl
    #!/usr/bin/perl -w
    use strict;
    use YAML::Syck;
    use Getopt::Long;
    use Pod::Usage;

    GetOptions('config=s' => \my $cfg_file,) or pod2usage(2);
    pod2usage(2) unless @ARGV > 0;

    my $config = LoadFile $cfg_file

    __END__
    =head1 NAME

    uberscript

    =head1 SYNOPSIS

    uberscript [options]

    Options:

        --config  config file

    =head1 Options

    =over 4

    =item B<config>

    Path to the config file
#+END_SRC

then

#+BEGIN_EXAMPLE
    % perl uberscript

    Usage:
        uberscript [options]

        Options:
            --config  config file
#+END_EXAMPLE

From now if we call our script without argument, the POD will be printed
on STDIN.

** MooseX::Getopt

[[http://search.cpan.org/perldoc?MooseX::Getopt][MooseX::Getopt]] is a
Role that add a =new_with_options= to your object. We create a basic
Object :

#+BEGIN_SRC perl
    package OurShinyObject;

    use Moose;
    with qw/MooseX::Getopt/;

    has 'config' => (isa => 'Str', is => 'ro', required => 1);
    has 'context' => (
        isa     => 'HashRef',
        is      => 'rw',
        lazy    => 1,
        traits  => ['NoGetopt'],
        default => sub { LoadFile shift->config }
    );

    ...
#+END_SRC

create a script to call this object

#+BEGIN_SRC perl
    #!/usr/bin/perl -w
    use strict;
    use OurShinyObject;

    my $obj = OurShinyObject->new_from_options();
#+END_SRC

#+BEGIN_SRC sh
    % script.pl --config file.yml
#+END_SRC

The role will set our attribute *context* using the value from the
argument set on the command line.

The =traits => ['NoGetopt']= indicate that this attributes will be not
be read from the command line. An alternate way to do this is to prefix
the attributes with **\_**.

** conclusion (?)

When you write a script, even if you're sure you will never need to have
more than one argument, or that you never will have to update the code,
/please/ consider to use of *Getopt::Long* instead of a =shift @ARGV=,
because we all know that you will at a certain point update this script
and you will more than one argument :).