Advanced modulinos

34
Advanced Modulinos brian d foy The Perl Review YAPC::NA 2012

Transcript of Advanced modulinos

Page 1: Advanced modulinos

★AdvancedModulinos

brian d foyThe Perl ReviewYAPC::NA 2012

Page 2: Advanced modulinos

Files that work as programs and modules

at the same time

Page 3: Advanced modulinos

Unit testing

Code reüse

Distribution

Page 4: Advanced modulinos

# hello.pluse v5.10;

say 'Hello World!';

Page 5: Advanced modulinos

% perl hello.plHello World!

Page 6: Advanced modulinos

STDOUT

exit code

STDIN@ARGV

%ENV

$0

Page 7: Advanced modulinos

Starting

Page 8: Advanced modulinos

use v5.10;

run();

sub run {say 'Hello World!';}

Page 9: Advanced modulinos

% perl hello.plHello World!% perl -e 'require q(hello.pl)'Hello World!

Page 10: Advanced modulinos

# Hello.pmuse v5.10;

run() unless caller;

sub run {say 'Hello World!';}

_ _PACKAGE_ _

Page 11: Advanced modulinos

% perl Hello.pmHello World!% perl -MHello -e 1%

Page 12: Advanced modulinos

package Hello;use v5.10;

__PACKAGE__->run unless caller;

sub run {say 'Hello World!';}

_ _PACKAGE_ _

Page 13: Advanced modulinos

use Test::More;use Test::Output;

use_ok( 'Hello' );

stdout_ok( sub { Hello->run() }, "Hello World!\n", ... );

Page 14: Advanced modulinos

package Hello;use v5.10;

_ _PACKAGE_ _->run unless caller;

sub run { my( $self ) = @_; say { $self->fh } 'Hello World!';}

Page 15: Advanced modulinos

package Hello;use v5.10;...;sub fh { *STDOUT }

Page 16: Advanced modulinos

use Test::More;

use_ok( 'Hello' );

our $string;{open my $fh, '>', \$string;*Hello::fh = sub { $fh };}

Hello->run;is($string, "Hello World!\n");

Page 17: Advanced modulinos

package Hello;use v5.10;...;BEGIN {my $fh = \*STDOUT;sub fh { $fh }sub set_fh { $fh = ...;}}

Page 18: Advanced modulinos

use Test::More;

use_ok( 'Hello' );

open my $fh, '>', \my $string;Hello->set_fh( $fh );Hello->run;is($string, "Hello World!\n");

Page 19: Advanced modulinos

% perl hello.plHello World!% perl hello.pl ChicagoHello World!% perl hello.pl -m RahmHello World!% perl hello.pl < aldermenHello World!

Page 20: Advanced modulinos

Connect the command line to new()

% hello.pl -s Houston

use Hello;

my $app->new( input => $in_fh, output => $out_fh, message => $message, );

$app->greet;

?new()

Page 21: Advanced modulinos

sub run { my( $class, @args ) = @_; my %args = $class->process_args(@args); my $self = $class->new(%args); say { $self->fh } $self->message; }

Page 22: Advanced modulinos

sub process_args { require Getopt::Std; local @ARGV = @_; getopts('oim:', \my %opts);

$opts{'o'} //= \*STDOUT; $opts{'i'} //= \*STDIN; $opts{'m'} //= 'Hello World!'; # left over @_? my %args = map { $opts_map{$_} => $opts{$_} } keys %opts; }

Page 23: Advanced modulinos

$app->new( input_fh => $in, output_fh => $out, message => 'Hello World!' );

Page 24: Advanced modulinos

sub new { my( $class, %args ) = @_; my $self = bless {}, $class; foreach ( keys %args ) { # maybe more complicated $self->set( $_, $args{$_} ); }

return $self; }

Page 25: Advanced modulinos

Stopping

Page 26: Advanced modulinos

#!perl...;...;...;

exit(0);

Page 27: Advanced modulinos

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

...;Result->new( code => 0 );} or $@;exit( $object->code );}

Page 28: Advanced modulinos

sub some_sub {...;die Result->new( code => 15 );...;}

Page 29: Advanced modulinos

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

...;Result->new( code => 0 );};exit( $error_object->code );

}

Page 30: Advanced modulinos

Testing

Page 31: Advanced modulinos

run() unless caller;

Page 32: Advanced modulinos

UNITCHECK { if($ENV{TEST_HARNESS}){ __PACKAGE__->run_tests; } elsif( ! caller ) { __PACKAGE__->run; } }

Page 33: Advanced modulinos

Docs

Page 34: Advanced modulinos

UNITCHECK { if($ENV{TEST_HARNESS}){ __PACKAGE__->run_tests; } elsif($ENV{PERLDOC}){ __PACKAGE__->show_docs; } elsif( ! caller ) { __PACKAGE__->run; } }