Advanced
    Modulinos
★        brian d foy
      The Perl Review
    Houston Perl Mongers
Files that work as
programs and modules
   at the same time
Unit testing

Code reüse

Distribution
# hello.pl
use v5.10;

say 'Hello World!';
% perl hello.pl
Hello World!
use v5.10;

run();

sub run {
 say 'Hello World!';
 }
% perl hello.pl
Hello World!
# Hello.pm
use v5.10;

run() unless caller;

sub run {
 say 'Hello World!';
 }
% perl hello.pl
Hello World!
% perl -MHello -e 1
%
package Hello;
use v5.10;

__PACKAGE__->run
   unless caller;

sub run {
 say 'Hello World!';
 }
use Test::More;
use Test::Output;

use_ok( 'Hello' );

stdout_ok(
   sub { Hello->run() },
   'Hello World!', ...
   );
package Hello;
use v5.10;

__PACKAGE__->run
   unless caller;

sub run {
 my( $self ) = @_;
 say { $self->fh }
   'Hello World!';
 }
package Hello;
use v5.10;
...;
sub fh { *STDOUT }
use Test::More;

use_ok( 'Hello' );

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

Hello->run;
is($string, 'Hello World!');
package Hello;
use v5.10;
...;
BEGIN {
my $fh = *STDOUT;
sub fh { $fh }
sub set_fh {
  $fh = ...;
}
use Test::More;

use_ok( 'Hello' );

open my $fh, '>', my $string;
Hello->set_fh( $fh );
Hello->run;
is($string, 'Hello World!');
% perl hello.pl
Hello World!
% perl hello.pl Houston
Hello World!
% perl hello.pl -m Texas
Hello World!
% perl hello.pl < partiers
Hello World!
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;
sub run {
  my( $class, @args ) = @_;
  my %args =
    $class->process_args(@args);
  my $self = $class->new(%args);
  say { $self->fh }
    $self->message;
  }
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;
  }
$app->new(
  input_fh => $in,
  output_fh => $out,
  message   => 'Hello World!'
  );
sub new {
  my( $class, %args ) = @_;
  my $self = bless {}, $class;

  foreach ( keys %args ) {
    # maybe more complicated
    $self->set( $_, $args{$_} );
    }

  return $self;
  }

Advanced modulinos trial