Professional Documents
Culture Documents
Tom Legrady
24 October, 2013
When Is it Useful?
For a big project, youre using Moose, et. al. For a quick little script, probably just plain-old-Perl. perl5i turns Perl into a modern language, with modern conveniences. Lots of modules required, but you have them already. When people go looking for examples of Perl code online, they nd short snippets without documentation, poor style. I decided to write samples code using perl5i, showing good style.
Whatdja Get?
Which would you rather type? use perl5i::2; or use warnings; use strict; use feature say state switch; use English; use autodie; use Try::Tiny;
100 Doors
use perl5i::2; package doors { ... } # -------------------------------------------# Main Thread # my $doors = doors->new(100); $doors->toggle_all(); $doors->print_open();
Package doors:
package doors { use perl5i::2; use Const::Fast; const my $OPEN => 1; const my $CLOSED => 0; # -----------------------# Constructor: door->new(@args); # input: N - how many doors? # returns: door object # method new($class: @args ) { my $self = bless {}, $class; $self->_init( @args ); return $self; }
Package doors::_init()
# ----------------------# class initializer. # input: how many doors? # set N, create N+1 doors # ( door zero is unused ). # method _init( $N ) { $self->{N} = $N; $self->{doors} = [($CLOSED) x ($N+1)]; }
Package doors::toggle()
# ---------------------------------------# $self->toggle_all(); # Toggle every door, then every other door, # every third door, ... # method toggle_all() { $self->toggle_n( $_ ) for ( 1 .. $self->{N} ); }
Package doors::toggle()
# ---------------------------------------# $self->toggle_n( $cycle ); # input: number. # Toggle doors 0, $cycle, 2*$cycle, 3*$cycle,..$self->{N} # method toggle_n( $n ) { $self->toggle($_) for map { $n * $_ } ( 1 .. int( $self->{N} / $n) ); }
Package doors::toggle()
# # # # #
---------------------------------------$self->toggle( $door_number ); input: number of door to toggle. OPEN a CLOSED door; CLOSE an OPEN door.
Package doors::print_open()
# ---------------------------------------# $self->print_open(); # Print list of which doors are open. # method print_open() { say join ', ', grep { $self->{doors}[$_] == $OPEN } ( 1 ... $self->{N} ); }
my @doors; for my $pass (1 .. 100) { for (1 .. 100) { if (0 == $_ % $pass) { $doors[$_] = not $doors[$_]; }; }; };
Combinations
func combine($len, @chars) { return unless @chars; return map { [ $_ ] } @chars if $len == 1; my ($head) = shift @chars; my @result = combine( $len-1, @chars ); for my $subarray ( @result ) { $subarray->unshift( $head ); } return ( @result, combine( $len, @chars ) );
Combinations - the UI
func parse_options() { my %options = ( length => 3, set => 5, ); GetOptions( \%options, 'length=s', 'set=s', 'man', 'help' ) or pod2usage(2); pod2usage(1) if $options{help}; pod2usage(-verbose => 2) if $options{man}; $options{alphabet} = [ ('a'..'z')[0..$options{set}-1] ]; return \%options;
The Mainline
POD
__END__ =pod =head1 NAME combinations.pli - determine possible combinations of M elements from a set of N =head1 VERSION This documentation applies to combinations.pli version 0.0.1
PODer
=head1 SYNOPSYS combinations.pli [--length M] [--set N] \ [-man] [-help] =head1 OPTIONS =over 4 =item length M Create strings of this length =item set N Use an alphabet of this many characters =item help Display a brief summary of information about the program. =item man Display the full documentation. =back
PODest
=head1 DESCRIPTION Generate combinations of length C<length> consisting of characters from the sorted set C<alphabet>, using each character once in a combination, with sorted strings in sorted order. =cut
Test Wrapper
# ------------------------------------# Tests # func runtests() { eval { use Test::More }; # only include if testing test_no_set(); test_length_zero(); test_length_one(); test_longer(); } done_testing();
func test_length_zero() { is( combine( 0, 'a' ), undef, 'zero length returns empty array' ); }
func test_length_one() { my ( @results ) = combine( 1, 'a' ); is_deeply( \@results, [['a']], 'length 1 returns unary set as array element'); @results = combine( 1, 'a', 'b', 'c' ); is_deeply( \@results, [['a'], ['b'], ['c']], 'length 1 returns larger set as array elements');
} # ----------------------------------------------# Run tests if invoked as a program, rather than # included as a module. # runtests() unless caller(); 1; # Package return
Resources
http://which-dwarf-are-you.blogspot.ca/ 2013_03_01_archive.html http://rosettacode.org/wiki/Category:Perl5i https://metacpan.org/module/perl5i Thanks to Ingy for a shout-out to the Rosetta Code perl5i examples, at YAPC::2013