From: Jonathan Swartz Date: Sat, 8 Jan 2011 00:32:38 +0000 (-0800) Subject: move most of new_with_options logic into separate publically accessible process_argv... X-Git-Tag: 0.34~7 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMooseX-Getopt.git;a=commitdiff_plain;h=f361569330f174ac07999ef69bf4f58df85be084 move most of new_with_options logic into separate publically accessible process_argv method, so that arg processing can be done without actually creating object --- diff --git a/lib/MooseX/Getopt.pm b/lib/MooseX/Getopt.pm index fdd4263..038d141 100644 --- a/lib/MooseX/Getopt.pm +++ b/lib/MooseX/Getopt.pm @@ -232,4 +232,12 @@ options (true if any of these options were passed on the command line). This returns the role meta object. +=method B + +This does most of the work of C, analyzing the parameters +and argv, except for actually calling the constructor. It returns a +L object. C uses this +method internally, so modifying this method via subclasses/roles will affect +C. + =cut diff --git a/lib/MooseX/Getopt/Basic.pm b/lib/MooseX/Getopt/Basic.pm index 44d683c..906ba39 100644 --- a/lib/MooseX/Getopt/Basic.pm +++ b/lib/MooseX/Getopt/Basic.pm @@ -6,6 +6,7 @@ use Moose::Role; use MooseX::Getopt::OptionTypeMap; use MooseX::Getopt::Meta::Attribute; use MooseX::Getopt::Meta::Attribute::NoGetopt; +use MooseX::Getopt::ProcessedArgv; use Carp (); use Getopt::Long 2.37 (); @@ -13,7 +14,7 @@ use Getopt::Long 2.37 (); has ARGV => (is => 'rw', isa => 'ArrayRef', metaclass => "NoGetopt"); has extra_argv => (is => 'rw', isa => 'ArrayRef', metaclass => "NoGetopt"); -sub new_with_options { +sub process_argv { my ($class, @params) = @_; my $config_from_file; @@ -68,13 +69,28 @@ sub new_with_options { $class->_getopt_full_usage($processed{usage}); } + return MooseX::Getopt::ProcessedArgv->new + ( + argv_copy => $processed{argv_copy}, + extra_argv => $processed{argv}, + usage => $processed{usage}, + constructor_params => $constructor_params, # explicit params to ->new + cli_params => $params, # params from CLI + ); +} + +sub new_with_options { + my ($class, @params) = @_; + + my $pa = $class->process_argv(@params); + $class->new( - ARGV => $processed{argv_copy}, - extra_argv => $processed{argv}, - ( $processed{usage} ? ( usage => $processed{usage} ) : () ), - %$constructor_params, # explicit params to ->new - %$params, # params from CLI - ); + ARGV => $pa->argv_copy, + extra_argv => $pa->extra_argv, + ( $pa->usage ? ( usage => $pa->usage ) : () ), + %{ $pa->constructor_params }, # explicit params to ->new + %{ $pa->cli_params }, # params from CLI + ); } sub _getopt_spec { shift->_traditional_spec(@_); } diff --git a/lib/MooseX/Getopt/ProcessedArgv.pm b/lib/MooseX/Getopt/ProcessedArgv.pm new file mode 100644 index 0000000..310ede7 --- /dev/null +++ b/lib/MooseX/Getopt/ProcessedArgv.pm @@ -0,0 +1,90 @@ +package MooseX::Getopt::ProcessedArgv; +use Moose; + +has 'argv_copy' => (is => 'ro', isa => 'ArrayRef'); +has 'extra_argv' => (is => 'ro', isa => 'ArrayRef'); +has 'usage' => (is => 'ro', isa => 'Maybe[Object]'); +has 'constructor_params' => (is => 'ro', isa => 'HashRef'); +has 'cli_params' => (is => 'ro', isa => 'HashRef'); + +__PACKAGE__->meta->make_immutable(); + +1; + +=pod + +=encoding utf-8 + +=head1 NAME + +MooseX::Getopt::ProcessedArgv - contains result of process_argv + +=head1 SYNOPSIS + + use My::App; + + my $pa = My::App->process_argv(@params); + my $argv_copy = $pa->argv_copy(); + my $extra_argv = $pa->extra_argv(); + my $usage = $pa->usage(); + my $constructor_params = $pa->constructor_params(); + my $cli_params = $pa->cli_params(); + +=head1 DESCRIPTION + +This object contains the result of a L call. It +contains all the information that L uses +when calling new. + +=head1 METHODS + +=over + +=item argv_copy + +Reference to a copy of the original C<@ARGV> array as it originally existed +at the time of C. + +=item extra_arg + +Arrayref of leftover C<@ARGV> elements that L did not parse. + +=item usage + +Contains the L object (if +L is used). + +=item constructor_params + +Parameters passed to process_argv. + +=item cli_param + +Command-line parameters parsed out of C<@ARGV>. + +=back + +=head1 AUTHOR + +Stevan Little Estevan@iinteractive.comE + +Brandon L. Black, Eblblack@gmail.comE + +Yuval Kogman, Enothingmuch@woobling.orgE + +=head1 CONTRIBUTORS + +Ryan D Johnson, Eryan@innerfence.comE + +Drew Taylor, Edrew@drewtaylor.comE + +Tomas Doran, (t0m) C<< >> + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2010 by Infinity Interactive, Inc. + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +=cut diff --git a/t/011_process_argv.t b/t/011_process_argv.t new file mode 100644 index 0000000..c56b1fb --- /dev/null +++ b/t/011_process_argv.t @@ -0,0 +1,59 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More; +use Test::Exception; + +if ( !eval { require Test::Deep } ) +{ + plan skip_all => 'Test requires Test::Deep'; + exit; +} +else +{ + plan tests => 6; +} + +{ + package Testing::Foo; + use Moose; + + with 'MooseX::Getopt'; + + has 'bar' => ( + is => 'ro', + isa => 'Int', + required => 1, + ); + + has 'baz' => ( + is => 'ro', + isa => 'Int', + required => 1, + ); +} + +@ARGV = qw(--bar 10 file.dat); + +my $pa; +lives_ok { + $pa = Testing::Foo->process_argv(baz => 100); +} '... this should work'; +isa_ok($pa, 'MooseX::Getopt::ProcessedArgv'); + +Test::Deep::cmp_deeply($pa->argv_copy, [ + '--bar', + '10', + 'file.dat' +], 'argv_copy'); +Test::Deep::cmp_deeply($pa->cli_params, { + 'bar' => 10 +}, 'cli_params'); +Test::Deep::cmp_deeply($pa->constructor_params, { + 'baz' => 100 +}, 'constructor_params'); +Test::Deep::cmp_deeply($pa->extra_argv, [ + 'file.dat' +], 'extra_argv');