Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Advanced modulinos

2,461 views

Published on

Published in: Technology
  • Be the first to comment

Advanced modulinos

  1. 1. ★ Advanced Modulinos brian d foy The Perl Review YAPC::NA 2012
  2. 2. Files that work asprograms and modules at the same time
  3. 3. Unit testingCode reüseDistribution
  4. 4. # hello.pluse v5.10;say Hello World!;
  5. 5. % perl hello.plHello World!
  6. 6. STDIN $0 STDOUT@ARGV %ENV exit code
  7. 7. Starting
  8. 8. use v5.10;run();sub run { say Hello World!; }
  9. 9. % perl hello.plHello World!% perl -e require q(hello.pl)Hello World!
  10. 10. # Hello.pmuse v5.10;run() unless caller;sub run { say Hello World!; }_ _PACKAGE_ _
  11. 11. % perl Hello.pmHello World!% perl -MHello -e 1%
  12. 12. package Hello;use v5.10;__PACKAGE__->run unless caller;sub run { say Hello World!; }_ _PACKAGE_ _
  13. 13. use Test::More;use Test::Output;use_ok( Hello );stdout_ok( sub { Hello->run() }, "Hello World!n", ... );
  14. 14. package Hello;use v5.10;_ _PACKAGE_ _->run unless caller;sub run { my( $self ) = @_; say { $self->fh } Hello World!; }
  15. 15. package Hello;use v5.10;...;sub fh { *STDOUT }
  16. 16. use Test::More;use_ok( Hello );our $string;{open my $fh, >, $string;*Hello::fh = sub { $fh };}Hello->run;is($string, "Hello World!n");
  17. 17. package Hello;use v5.10;...;BEGIN {my $fh = *STDOUT;sub fh { $fh }sub set_fh { $fh = ...;}}
  18. 18. use Test::More;use_ok( Hello );open my $fh, >, my $string;Hello->set_fh( $fh );Hello->run;is($string, "Hello World!n");
  19. 19. % perl hello.plHello World!% perl hello.pl ChicagoHello World!% perl hello.pl -m RahmHello World!% perl hello.pl < aldermenHello World!
  20. 20. Connect the command line to new()% hello.pl -s Houston ? use Hello; new() my $app->new( input => $in_fh, output => $out_fh, message => $message, ); $app->greet;
  21. 21. sub run { my( $class, @args ) = @_; my %args = $class->process_args(@args); my $self = $class->new(%args); say { $self->fh } $self->message; }
  22. 22. 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; }
  23. 23. $app->new( input_fh => $in, output_fh => $out, message => Hello World! );
  24. 24. sub new { my( $class, %args ) = @_; my $self = bless {}, $class; foreach ( keys %args ) { # maybe more complicated $self->set( $_, $args{$_} ); } return $self; }
  25. 25. Stopping
  26. 26. #!perl...;...;...;exit(0);
  27. 27. sub run { my( $class, @args ) = @_; my $object = eval { ...; Result->new( code => 0 ); } or $@; exit( $object->code ); }
  28. 28. sub some_sub { ...; die Result->new( code => 15 ); ...; }
  29. 29. sub run { my( $class, @args ) = @_; my $object = eval { ...; Result->new( code => 0 ); }; exit( $error_object->code ); }
  30. 30. Testing
  31. 31. run() unless caller;
  32. 32. UNITCHECK { if($ENV{TEST_HARNESS}){ __PACKAGE__->run_tests; } elsif( ! caller ) { __PACKAGE__->run; } }
  33. 33. Docs
  34. 34. UNITCHECK { if($ENV{TEST_HARNESS}){ __PACKAGE__->run_tests; } elsif($ENV{PERLDOC}){ __PACKAGE__->show_docs; } elsif( ! caller ) { __PACKAGE__->run; } }

×