├── .gitignore ├── CREDITS ├── README ├── activestate.yaml ├── book.conf ├── build ├── css │ └── style.css ├── epub │ └── .gitignore ├── html │ └── style.css ├── latex │ ├── copyright.tex │ └── modern_perl_commands.sty ├── pdf │ └── .gitignore ├── tools │ ├── build_chapters.pl │ ├── build_epub.pl │ ├── build_html.pl │ ├── build_html_book.pl │ ├── build_pdf.pl │ └── open_browser.pl └── xhtml │ └── .gitignore ├── images ├── mp_cover_full.png ├── mp_cover_med.png └── mp_cover_thumb.png ├── outline.pod └── sections ├── advanced_oo.pod ├── anonymous_functions.pod ├── arrays.pod ├── attributes.pod ├── autoload.pod ├── automatic_dereferencing.pod ├── barewords.pod ├── blessed_references.pod ├── builtins.pod ├── chapter_00.pod ├── chapter_01.pod ├── chapter_02.pod ├── chapter_03.pod ├── chapter_04.pod ├── chapter_05.pod ├── chapter_06.pod ├── chapter_07.pod ├── chapter_08.pod ├── chapter_09.pod ├── chapter_10.pod ├── chapter_11.pod ├── chapter_12.pod ├── closures.pod ├── code_generation.pod ├── coercion.pod ├── context_philosophy.pod ├── control_flow.pod ├── cpan.pod ├── credits.pod ├── distributions.pod ├── exceptions.pod ├── expressivity.pod ├── files.pod ├── functions.pod ├── globals.pod ├── handling_warnings.pod ├── hashes.pod ├── idioms.pod ├── implicit_ideas.pod ├── indirect_objects.pod ├── method_sub_equivalence.pod ├── missing_defaults.pod ├── modules.pod ├── moose.pod ├── names.pod ├── nested_data_structures.pod ├── next_steps.pod ├── operator_characteristics.pod ├── operator_types.pod ├── overloading.pod ├── packages.pod ├── perl_community.pod ├── perldoc.pod ├── pragmas.pod ├── prototypes.pod ├── references.pod ├── reflection.pod ├── regular_expressions.pod ├── scalars.pod ├── scope.pod ├── smart_match.pod ├── state.pod ├── style.pod ├── taint.pod ├── testing.pod ├── tie.pod ├── universal.pod ├── values.pod └── variables.pod /.gitignore: -------------------------------------------------------------------------------- 1 | build/chapters 2 | build/html/*.html 3 | build/pdf/*.pdf 4 | examples/ 5 | !build/pdf/.gitignore 6 | !build/epub/.gitignore 7 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | Please add yourself to this file. 2 | 3 | N: chromatic 4 | E: chromatic@wgz.org 5 | 6 | N: Felipe 7 | E: fegolac@gmail.com 8 | 9 | N: Jeremiah Foster 10 | E: jeremiah@jeremiahfoster.com 11 | 12 | N: Alex Muntada 13 | E: alexm@cpan.org 14 | 15 | N: Bruce Gray 16 | E: bruce.gray@acm.org 17 | 18 | N: John McNamara 19 | E: jmcnamara@cpan.org 20 | 21 | N: Josh McAdams 22 | E: joshua.mcadams@gmail.com 23 | 24 | N: Nelo Onyiah 25 | E: nelo.onyiah@gmail.com 26 | 27 | N: sunnavy 28 | E: sunnavy@gmail.com 29 | 30 | N: Doug Wilson 31 | E: doug@somethingdoug.com 32 | 33 | N: John SJ Anderson 34 | E: genehack@genehack.org 35 | 36 | N: Moritz Lenz 37 | E: moritz@faui2k3.org 38 | 39 | N: Carl Mäsak 40 | E: cmasak@gmail.com 41 | 42 | N: Bryan Summersett 43 | E: bsummersett@gmail.com 44 | 45 | N: Alex Balhatchet 46 | E: kaoru@slackwise.net 47 | 48 | N: Vasily Chekalkin 49 | E: bacek@bacek.com 50 | 51 | N: Tim Heaney 52 | E: oylenshpeegul@gmail.com 53 | 54 | N: Sam Vilain 55 | E: sam@vilain.net 56 | 57 | N: Colin Wetherbee 58 | E: cww@cpan.org 59 | 60 | N: Dan Scott 61 | E: dan@coffeecode.net 62 | 63 | N: Shlomi Fish 64 | E: shlomif@iglu.org.il 65 | 66 | N: Scott Thomson 67 | E: scott@dearie.me.uk 68 | 69 | N: Michael Hind 70 | E: mike.hind@gmail.com 71 | 72 | N: Frank Wiegand 73 | E: fwie@cpan.org 74 | 75 | N: Shawn M Moore 76 | E: sartak@bestpractical.com 77 | 78 | N: Mark A. Stratman 79 | E: mark@sporkstorms.org 80 | 81 | N: Jan Krynicky 82 | E: Jenda@Krynicky.cz 83 | 84 | N: Curtis Jewell 85 | E: csjewell@cpan.org 86 | 87 | N: James E Keenan 88 | E: jkeenan@cpan.org 89 | 90 | N: Yary Hluchan 91 | E: not.com@gmail.com 92 | 93 | N: Yuval Kogman 94 | E: nothingmuch@woobling.org 95 | 96 | N: Chas. Owens 97 | E: chas.owens@gmail.com 98 | 99 | N: John Gabriele 100 | E: jmg3000@gmail.com 101 | 102 | N: Jeff Lavallee 103 | E: jeff@zeroclue.com 104 | 105 | N: Phillip Smith 106 | E: phillip@communitybandwidth.ca 107 | 108 | N: Sawyer X 109 | E: xsawyerx@cpan.org 110 | 111 | N: Paulo Custodio 112 | E: pscust@cpan.org 113 | 114 | N: Jean-Baptiste Mazon 115 | E: ? 116 | 117 | N: ww from PerlMonks 118 | E: ? 119 | 120 | N: Andrew Savige 121 | E: asavige@cpan.org 122 | 123 | N: Matthias Bloch 124 | E: matthias.bloch@puffin.ch 125 | 126 | N: Peter Aronoff 127 | E: telemachus@arpinum.org 128 | 129 | N: Audrey Tang 130 | E: cpan@audreyt.org 131 | 132 | N: Lee Aylward 133 | E: lee@laylward.com 134 | 135 | N: Mark Fowler 136 | E: mark@twoshortplanks.com 137 | 138 | N: Dmitry Chestnykh 139 | E: dmitry@codingrobots.com 140 | 141 | N: harleypig 142 | E: harleypig@gmail.com 143 | 144 | N: Jess Robinson 145 | E: castaway@desert-island.me.uk 146 | 147 | N: David Yingling 148 | E: deeelwy@yahoo.com 149 | 150 | N: Marko Zagozen 151 | E: ? 152 | 153 | N: Alex-ander Scott-Johns 154 | E: alexander.scott.johns@googlemail.com 155 | 156 | N: Larry Wall 157 | E: larry@wall.org 158 | 159 | N: Gabrielle Roth 160 | E: gorthx@gmail.com> 161 | 162 | N: Mohammed Arafat Kamaal 163 | E: makamaal.linux@gmail.com 164 | 165 | N: Christopher E. Stith 166 | E: cstith@gmail.com 167 | 168 | N: Mike Huffman 169 | E: mhuffman@aracnet.com 170 | 171 | N: E. Choroba 172 | E: choroba on PerlMonks 173 | 174 | N: hbm 175 | E: hbm on PerlMonks 176 | 177 | N: Ask Bjørn Hansen 178 | E: ask@develooper.com 179 | 180 | N: Ævar Arnfjörð Bjarmason 181 | E: avar@cpan.org 182 | 183 | N: Gareth McCaughan 184 | E: gareth.mccaughan@pobox.com 185 | 186 | N: Robert Hicks 187 | E: rlhicks@wehicks.com 188 | 189 | N: Chris Niswander 190 | E: cnp1@chrisniswander.com 191 | 192 | N: Andrew Grangaard 193 | E: spazm@cpan.org 194 | 195 | N: Mark Hindess 196 | E: soft-cpan@temporalanomaly.com 197 | 198 | N: John Bokma 199 | E: contact@johnbokma.com 200 | 201 | N: Lorne Schachter 202 | E: lorne.schachter@citi.com 203 | 204 | N: Dave Rolsky 205 | E: autarch@urth.org 206 | 207 | N: Ben Tilly 208 | E: btilly@gmail.com 209 | 210 | N: Michael Lang 211 | E: michi@jackal-net.at 212 | 213 | N: Graeme Hewson 214 | E: ghewson@wormhole.me.uk 215 | 216 | N: Steve Schulze 217 | E: thundergnat@gmail.com 218 | 219 | N: Anneli Cuss 220 | E: celtic@sairyx.org 221 | 222 | N: Eduardo Santiago 223 | E: esm@cpan.org 224 | 225 | N: Andy Lester 226 | E: andy@petdance.com 227 | 228 | N: Steve Dickinson 229 | E: dsdickinson@gmail.com 230 | 231 | N: Kurt Edmiston 232 | E: hurdlecrew@gmail.com 233 | 234 | N: Lewis Wall 235 | E: qufanat@gmail.com 236 | 237 | N: Gary H. Jones II 238 | E: gary@pointblanksecurity.com 239 | 240 | N: Kirk Kimmel 241 | E: kimmel.k.programmer@gmail.com 242 | 243 | N: Ruud H. G. van Tol 244 | E: rvtol@isolution.nl 245 | 246 | N: Jean-Pierre Rupp 247 | E: jpierre@xeno-genesis.com 248 | 249 | N: Tom Christiansen 250 | E: tchrist@perl.com 251 | 252 | N: Daniel Holz 253 | E: dgholz@gmail.com 254 | 255 | N: Kevin Granade 256 | E: kevingranade@linuxwrangling.com 257 | 258 | N: Ahmad M. Zawawi 259 | E: ahmad.zawawi@gmail.com 260 | 261 | N: Michael Hicks 262 | E: nooneofconsequence@gmail.com 263 | 264 | N: Paul Waring 265 | E: paul@xk7.net 266 | 267 | N: Grzegorz Rożniecki 268 | E: xaerxess@gmail.com 269 | 270 | N: Graham Knop 271 | E: haarg@haarg.org 272 | 273 | N: Nitesh Bezzala 274 | E: nbezzala@yahoo.com 275 | 276 | N: Nathan Glenn 277 | E: garfieldnate@gmail.com 278 | 279 | N: Matt Pettis 280 | E: matthew.pettis@gmail.com 281 | 282 | N: Géraud CONTINSOUZAS 283 | E: gcs@cpan.org 284 | 285 | N: Alex Schroeder 286 | E: alex@gnu.org 287 | 288 | N: David Farrell 289 | E: editor@perltricks.com 290 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | What is Modern Perl? 2 | -------------------- 3 | 4 | Perl is a popular, powerful, and widely used programming language. Over its 5 | twenty year lifespan, it's powered millions of systems worldwide, moving 6 | trillions of dollars. More importantly, it's helped countless people get their 7 | work done effectively. 8 | 9 | The Perl community has a reputation for clever solutions -- and a reputation 10 | for institutional knowledge that isn't always clear to novices and neophytes. 11 | Modern Perl, written with this knowledge, can be very clean, very maintainable, 12 | and very effective. 13 | 14 | That knowledge should be available to everyone. This book will teach you how 15 | to program Perl well by teaching you how to understand Perl's design, its 16 | syntax, and its semantics. 17 | 18 | http://www.modernperlbooks.com/mt/2009/01/why-modern-perl.html 19 | 20 | 21 | Intended Audience 22 | ----------------- 23 | 24 | I assume readers have some familiarity with Perl. They should have it 25 | installed and should know how to write, edit, save, and run Perl programs. 26 | They don't necessarily have to have finished reading a tutorial such as 27 | Learning Perl or Beginning Perl, but they should be sufficiently familiar with 28 | programming to be able to follow along with examples. 29 | 30 | I try not to assume complete knowledge of even basic constructs; I try to 31 | explain them in detail, as understanding subtleties of design and 32 | implementation are important to mastering the subject of Perl. 33 | 34 | 35 | Reviewer Guidelines 36 | ------------------- 37 | 38 | I appreciate all suggestions and critiques, especially: 39 | 40 | * is the work accurate? 41 | * is the work complete? 42 | * is the work coherent? 43 | * are there missing sections and subjects? 44 | * are the examples effective? 45 | * is the flow of information appropriate? 46 | 47 | 48 | Building this Book 49 | ------------------ 50 | 51 | You need a modern version of Perl installed. I recommend Perl 5.10.1, but 52 | anything newer than 5.8.6 should work. 53 | 54 | You should also have Pod::PseudoPod 0.16 or newer installed with its 55 | dependencies. 56 | 57 | From the top level directory of a checkout, build the individual chapters with: 58 | 59 | $ perl build/tools/build_chapters.pl 60 | 61 | The chapter sources are in the sections/ directory. Each chapter has a 62 | corresponding chapter_nn.pod file. Each file contains multiple POD links which 63 | refer to other files in the sections/ directory. Each of those files contains 64 | a PseudoPOD Z<> anchor. 65 | 66 | The build_chapters.pl program weaves these sections into chapters and writes 67 | them to POD files in build/chapters. 68 | 69 | (This process makes it easy to rearrange sections within and between chapters 70 | without generating huge diffs.) 71 | 72 | To build HTML from these woven chapters: 73 | 74 | $ perl build/tools/build_html.pl 75 | 76 | This will produce nicely-formatted HTML in the build/html/ directory. If 77 | anything looks wrong, it's a mistake on my part (or a CSS problem) and patches 78 | are very welcome. 79 | 80 | To build an ePub eBook from the woven chapters: 81 | 82 | $ perl build/tools/build_epub.pl 83 | 84 | This will produce an ePub eBook in the build/epub/ directory. 85 | 86 | To build PDFs from the chapters: 87 | 88 | $ perl build/tools/build_pdf.pl 89 | 90 | This will build PDFs in the build/pdf directory. You must have App::pod2pdf 91 | installed from the CPAN. 92 | 93 | 94 | Contributing to Modern Perl 95 | --------------------------- 96 | 97 | This work is licensed under a Creative Commons Attribution-Noncommercial-Share 98 | Alike 3.0 United States License. For more details, see: 99 | 100 | http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 101 | 102 | Please feel free to point people to this repository. Suggestions and 103 | contributions are welcome. You have the right to redistribute modified 104 | versions, but I ask (though do not require) you to file bugs or submit pull 105 | requests against this repository. 106 | 107 | This book is available in print and in formatted electronic formats 108 | from Onyx Neon Press: 109 | 110 | http://www.onyxneon.com/books/modern_perl/index.html 111 | 112 | The electronic versions are available for free, with no restrictions on free 113 | redistribution. 114 | -------------------------------------------------------------------------------- /activestate.yaml: -------------------------------------------------------------------------------- 1 | project: https://platform.activestate.com/chromatic/ModernPerl4e-5.34-Linux?branch=main&commitID=aff573b8-824b-4844-a29e-7b0f0fc979e3 2 | 3 | scripts: 4 | - name: activationMessage 5 | language: perl 6 | value: | 7 | print <<~EOT; 8 | You are now in an activated state, which is like a virtual environment to work 9 | in that doesn't affect the rest of your system. To leave, run `exit`. 10 | 11 | What's next? 12 | - To learn more about what you can do, run → `state run modern-perl-book [chapter-number]` 13 | EOT 14 | exec( $^X, $ENV{ACTIVESTATE_ACTIVATED} . '/build/tools/build_html_book.pl' ); 15 | - name: modern-perl-book 16 | description: Open the Modern Perl book in your web browser. With no arguments provided, opens the table of contents. Otherwise pass the chapter number (0, 1, ... 15) to read that chapter. 17 | language: perl 18 | value: | 19 | exec( $^X, $ENV{ACTIVESTATE_ACTIVATED} . '/build/tools/open_browser.pl', @ARGV ); 20 | events: 21 | - name: ACTIVATE 22 | value: activationMessage 23 | -------------------------------------------------------------------------------- /book.conf: -------------------------------------------------------------------------------- 1 | [book] 2 | author_name=chromatic 3 | copyright_year=2021 4 | cover_image= 5 | language=en 6 | title=Modern Perl 7 | subtitle=development edition 8 | filename_template=modern_perl 9 | build_index=1 10 | build_credits=1 11 | build_chapters=1 12 | ISBN10= 13 | ISBN13= 14 | 15 | [layout] 16 | chapter_name_prefix=chapter 17 | subchapter_directory=sections 18 | chapter_build_directory=chapters 19 | -------------------------------------------------------------------------------- /build/epub/.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | * 3 | -------------------------------------------------------------------------------- /build/html/style.css: -------------------------------------------------------------------------------- 1 | 179 | -------------------------------------------------------------------------------- /build/latex/copyright.tex: -------------------------------------------------------------------------------- 1 | \thispagestyle{empty} 2 | 3 | \huge{\booktitle} 4 | \newline 5 | \large{\booksubtitle} 6 | \newline 7 | \newline 8 | \normalsize 9 | 10 | Copyright \copyright~2010-2014 \bookauthor 11 | 12 | \vfill 13 | \textbf{Editor:} Shane Warden\newline 14 | \textbf{Logo design:} Devin Muldoon\newline 15 | \textbf{Cover design:} Allison Randal, chromatic, and Jeffrey Martin 16 | 17 | \textbf{ISBN-10:} \bookisbnten\newline 18 | \textbf{ISBN-13:} \bookisbnthirteen 19 | 20 | Published by Onyx Neon Press, \url{http://www.onyxneon.com/}. 21 | The Onyx Neon logo is a trademark of Onyx Neon, Inc. 22 | 23 | Onyx Neon typesets books with free software, especially Ubuntu GNU/Linux, Perl, 24 | PseudoPod, and \LaTeX. Many thanks to the contributors who make these and other 25 | projects possible. 26 | 27 | 2010 - 2011 Edition October 2010\newline 28 | 2011 - 2012 Edition January 2012\newline 29 | 2014 - 2015 Edition January 2014 30 | 31 | Electronic versions of this book are available from 32 | \url{http://onyxneon.com/books/modern_perl/}, and the companion website is 33 | \url{http://modernperlbooks.com/}. Please share with your friends and 34 | colleagues. 35 | 36 | Thanks for reading! 37 | -------------------------------------------------------------------------------- /build/latex/modern_perl_commands.sty: -------------------------------------------------------------------------------- 1 | \newcommand{\booktitle}{Modern Perl} 2 | \newcommand{\booksubtitle}{2014 edition} 3 | \newcommand{\bookauthor}{chromatic} 4 | \newcommand{\bookisbnten}{0-9779201-7-8} 5 | \newcommand{\bookisbnthirteen}{978-0-9779201-7-4} 6 | -------------------------------------------------------------------------------- /build/pdf/.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | * 3 | -------------------------------------------------------------------------------- /build/tools/build_chapters.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use File::Path 'mkpath'; 7 | use File::Spec::Functions qw( catfile catdir splitpath ); 8 | 9 | my $sections_href = get_section_list(); 10 | 11 | for my $chapter (get_chapter_list()) 12 | { 13 | my $text = process_chapter( $chapter, $sections_href ); 14 | write_chapter( $chapter, $text ); 15 | } 16 | 17 | die( "Scenes missing from chapters:", join "\n\t", '', keys %$sections_href ) 18 | if keys %$sections_href; 19 | 20 | exit; 21 | 22 | sub get_chapter_list 23 | { 24 | my $glob_path = catfile( 'sections', 'chapter_??.pod' ); 25 | return glob( $glob_path ); 26 | } 27 | 28 | sub get_section_list 29 | { 30 | my %sections; 31 | my $sections_path = catfile( 'sections', '*.pod' ); 32 | 33 | for my $section (glob( $sections_path )) 34 | { 35 | next if $section =~ /\bchapter_??/; 36 | my $anchor = get_anchor( $section ); 37 | $sections{ $anchor } = $section; 38 | } 39 | 40 | return \%sections; 41 | } 42 | 43 | sub get_anchor 44 | { 45 | my $path = shift; 46 | 47 | open my $fh, '<:utf8', $path or die "Can't read '$path': $!\n"; 48 | while (<$fh>) { 49 | next unless /Z<(\w*)>/; 50 | return $1; 51 | } 52 | 53 | die "No anchor for file '$path'\n"; 54 | } 55 | 56 | sub process_chapter 57 | { 58 | my ($path, $sections_href) = @_; 59 | my $text = read_file( $path ); 60 | 61 | $text =~ s/^L<(\w+)>/insert_section( $sections_href, $1, $path )/emg; 62 | 63 | $text =~ s/(=head1 .*)\n\n=head2 \*{3}/$1/g; 64 | return $text; 65 | } 66 | 67 | sub read_file 68 | { 69 | my $path = shift; 70 | open my $fh, '<:utf8', $path or die "Can't read '$path': $!\n"; 71 | return scalar do { local $/; <$fh>; }; 72 | } 73 | 74 | sub insert_section 75 | { 76 | my ($sections_href, $name, $chapter) = @_; 77 | 78 | die "Unknown section '$name' in '$chapter'\n" 79 | unless exists $sections_href->{ $1 }; 80 | 81 | my $text = read_file( $sections_href->{ $1 } ); 82 | delete $sections_href->{ $1 }; 83 | return $text; 84 | } 85 | 86 | sub write_chapter 87 | { 88 | my ($path, $text) = @_; 89 | my $name = ( splitpath $path )[-1]; 90 | my $chapter_dir = catdir( 'build', 'chapters' ); 91 | my $chapter_path = catfile( $chapter_dir, $name ); 92 | 93 | mkpath( $chapter_dir ) unless -e $chapter_dir; 94 | 95 | open my $fh, '>:utf8', $chapter_path 96 | or die "Cannot write '$chapter_path': $!\n"; 97 | 98 | print {$fh} $text; 99 | 100 | warn "Writing '$chapter_path'\n"; 101 | } 102 | -------------------------------------------------------------------------------- /build/tools/build_html.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Pod::PseudoPod::HTML; 7 | use File::Spec::Functions qw( catfile catdir splitpath ); 8 | 9 | # P::PP::H uses Text::Wrap which breaks HTML tags 10 | local *Text::Wrap::wrap; 11 | *Text::Wrap::wrap = sub { $_[2] }; 12 | 13 | my @chapters = get_chapter_list(); 14 | my $anchors = get_anchors(@chapters); 15 | 16 | sub Pod::PseudoPod::HTML::end_L 17 | { 18 | my $self = shift; 19 | if ($self->{scratch} =~ s/\b(\w+)$//) 20 | { 21 | my $link = $1; 22 | die "Unknown link $link\n" unless exists $anchors->{$link}; 23 | $self->{scratch} .= '" 24 | . $anchors->{$link}[1] . ''; 25 | } 26 | } 27 | 28 | for my $chapter (@chapters) 29 | { 30 | my $out_fh = get_output_fh($chapter); 31 | my $parser = Pod::PseudoPod::HTML->new(); 32 | 33 | $parser->output_fh($out_fh); 34 | 35 | # output a complete html document 36 | $parser->add_body_tags(1); 37 | 38 | # add css tags for cleaner display 39 | $parser->add_css_tags(1); 40 | 41 | $parser->no_errata_section(1); 42 | $parser->complain_stderr(1); 43 | 44 | $parser->parse_file($chapter); 45 | } 46 | 47 | exit; 48 | 49 | sub get_anchors 50 | { 51 | my %anchors; 52 | 53 | for my $chapter (@_) 54 | { 55 | my ($file) = $chapter =~ /(chapter_\d+)./; 56 | my $contents = slurp( $chapter ); 57 | 58 | while ($contents =~ /^=head\d (.*?)\n\nZ<(.*?)>/mg) 59 | { 60 | $anchors{$2} = [ $file . '.html', $1 ]; 61 | } 62 | } 63 | 64 | return \%anchors; 65 | } 66 | 67 | sub slurp 68 | { 69 | return do { local @ARGV = @_; local $/ = <>; }; 70 | } 71 | 72 | sub get_chapter_list 73 | { 74 | my $glob_path = catfile( qw( build chapters chapter_??.pod ) ); 75 | return glob $glob_path; 76 | } 77 | 78 | sub get_output_fh 79 | { 80 | my $chapter = shift; 81 | my $name = ( splitpath $chapter )[-1]; 82 | my $htmldir = catdir( qw( build html ) ); 83 | 84 | $name =~ s/\.pod/\.html/; 85 | $name = catfile( $htmldir, $name ); 86 | 87 | open my $fh, '>:utf8', $name 88 | or die "Cannot write to '$name': $!\n"; 89 | 90 | return $fh; 91 | } 92 | -------------------------------------------------------------------------------- /build/tools/build_html_book.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use Modern::Perl '2019'; 4 | use Pod::PseudoPod::Book; 5 | use Path::Tiny; 6 | 7 | exit main( @ARGV ); 8 | 9 | sub main { 10 | my $app = Pod::PseudoPod::Book->new; 11 | 12 | my ($cmd, $opt, @args) = $app->get_command( 'buildhtml' ); 13 | 14 | for my $build_path ( 'build/chapters', 'build/html' ) { 15 | path($build_path)->mkpath; 16 | } 17 | 18 | for my $command (qw( buildcredits buildchapters ), $cmd ) { 19 | $app->execute_command( $app->plugin_for( $command ), $opt, @args ); 20 | } 21 | 22 | fixup_html_chapters( 'build/html' ); 23 | 24 | return 0; 25 | } 26 | 27 | sub fixup_html_chapters { 28 | my $output_dir = path(shift); 29 | 30 | for my $child_file ($output_dir->children( qr/\.html$/ ) ) { 31 | $child_file->edit( sub { 32 | s//
/; 33 | s/<\/body>/<\/div><\/body>/; 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /build/tools/build_pdf.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use File::Spec::Functions qw( catfile catdir splitpath ); 7 | 8 | # getting chapter list 9 | my @chapters = get_chapter_list(); 10 | 11 | # Check if pod2pdf is available 12 | require App::pod2pdf 13 | or die "pod2pdf is not present in your PATH; please install App::pod2pdf\n"; 14 | 15 | my $outpath = catdir( qw( build pdf ) ); 16 | 17 | for my $chapter ( @chapters ){ 18 | my @filename = split( /\./ , $chapter ); 19 | print "Converting $chapter to pdf\n"; 20 | system( 'pod2pdf', '--noheader', $chapter, '--output-file', 21 | catfile(qw( build pdf ), (splitpath($filename[0]))[-1] . '.pdf' ) ); 22 | } 23 | 24 | print "PDFs have been generated in build/pdf\n"; 25 | 26 | sub get_chapter_list 27 | { 28 | my $glob_path = catfile( qw( build chapters chapter_??.pod ) ); 29 | return glob $glob_path; 30 | } 31 | -------------------------------------------------------------------------------- /build/tools/open_browser.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use Modern::Perl '2019'; 4 | use Browser::Open; 5 | use Path::Tiny; 6 | use feature 'signatures'; 7 | no warnings 'experimental::signatures'; 8 | 9 | exit main( @ARGV ); 10 | 11 | sub main($chapter = undef) { 12 | return Browser::Open::open_browser('file://' . get_chapter($chapter), 1 ); 13 | } 14 | 15 | sub get_chapter($chapter_number) { 16 | return get_file(shift)->absolute; 17 | } 18 | 19 | sub get_file($chapter_number) { 20 | my $index = path('build/html/index.html'); 21 | return $index unless $chapter_number; 22 | return $index unless $chapter_number =~ /\A\d+\Z/; 23 | 24 | for my $num ($chapter_number, '0' . $chapter_number) { 25 | my $chapter_path = path('build/html/chapter_' . $num . '.html'); 26 | return $chapter_path if $chapter_path->exists; 27 | } 28 | 29 | return $index; 30 | } 31 | -------------------------------------------------------------------------------- /build/xhtml/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /images/mp_cover_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chromatic/modern_perl_book/bb03cb0404422853060b8493f7992cf39343e658/images/mp_cover_full.png -------------------------------------------------------------------------------- /images/mp_cover_med.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chromatic/modern_perl_book/bb03cb0404422853060b8493f7992cf39343e658/images/mp_cover_med.png -------------------------------------------------------------------------------- /images/mp_cover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chromatic/modern_perl_book/bb03cb0404422853060b8493f7992cf39343e658/images/mp_cover_thumb.png -------------------------------------------------------------------------------- /sections/advanced_oo.pod: -------------------------------------------------------------------------------- 1 | =head1 Advanced OO Perl 2 | 3 | Z 4 | 5 | Creating and using objects in Perl with Moose (L) is easy. I 6 | good programs is not. It's as easy to overdesign a program as it is to 7 | underdesign it. Only practical experience can help you understand the most 8 | important design techniques, but several principles can guide you. 9 | 10 | =head2 Favor Composition Over Inheritance 11 | 12 | X 13 | X 14 | 15 | Novice OO designs often overuse inheritance to reuse code and to exploit 16 | polymorphism. The result is a deep class hierarchy with responsibilities 17 | scattered all over the place. Maintaining this code is difficult--who knows 18 | where to add or edit behavior? What happens when code in one place conflicts 19 | with code declared elsewhere? 20 | 21 | X 22 | X 23 | 24 | Inheritance is only one of many tools for OO programmers. It's not always the 25 | right tool. It's often the wrong tool. A C may extend C 26 | (an I), but C may better I several C 27 | objects as instance attributes (a I). 28 | 29 | Decomposing complex classes into smaller, focused entities improves 30 | encapsulation and reduces the possibility that any one class or role does too 31 | much. Smaller, simpler, and better encapsulated entities are easier to 32 | understand, test, and maintain. 33 | 34 | =head2 Single Responsibility Principle 35 | 36 | X 37 | 38 | When you design your object system, consider the responsibilities of each 39 | entity. For example, an C object may represent specific information 40 | about a person's name, contact information, and other personal data, while a 41 | C object may represent business responsibilities. Separating these 42 | entities in terms of their responsibilities allows the C class to 43 | consider only the problem of managing information specific to who the person is 44 | and the C class to represent what the person does. (Two Cs may 45 | have a C-sharing arrangement, for example, or one C may have the 46 | CFO and the COO Cs.) 47 | 48 | When each class has a single responsibility, you reduce coupling between 49 | classes and improve the encapsulation of class-specific data and behavior. 50 | 51 | =head2 Don't Repeat Yourself 52 | 53 | X 54 | 55 | Complexity and duplication complicate development and maintenance. The I 56 | principle (Don't Repeat Yourself) is a reminder to seek out and to eliminate 57 | duplication within the system. Duplication exists in data as well as in code. 58 | Instead of repeating configuration information, user data, and other important 59 | artifacts of your system, create a single, canonical representation of that 60 | information from which you can generate the other artifacts. 61 | 62 | This principle helps you to find the optimal representation of your system and 63 | its data and reduces the possibility that duplicate information will get out of 64 | sync. 65 | 66 | =head2 Liskov Substitution Principle 67 | 68 | X 69 | 70 | The Liskov substitution principle suggests that you should be able to 71 | substitute a specialization of a class or a role for the original without 72 | violating the original's API. In other words, an object should be as or more 73 | general with regard to what it expects and at least as specific about what it 74 | produces as the object it replaces. 75 | 76 | Imagine two classes, C and its child class C. If the classes 77 | follow the Liskov substitution principle, you can replace every use of 78 | C objects with C objects in the test suite, and everything 79 | should pass. See Reg Braithwaite's 80 | "IS-STRICTLY-EQUIVALENT-TO-A"N.> 81 | for more details. 82 | 83 | =head2 Subtypes and Coercions 84 | 85 | Z 86 | 87 | X 88 | X 89 | X 90 | 91 | Moose allows you to declare and use types and extend them through subtypes to 92 | form ever more specialized descriptions of what your data represents and how it 93 | behaves. These type annotations help verify that the function and method 94 | parameters are correct--or can be coerced into the proper data types. 95 | 96 | X> 97 | X> 98 | 99 | For example, you may wish to allow people to provide dates to a C entry 100 | as strings while representing them as C instances internally. You can 101 | do this by creating a Date type and adding a coercion from string types. See 102 | C and C for more information. 103 | 104 | =head2 Immutability 105 | 106 | Z 107 | 108 | X 109 | 110 | With a well-designed object, you tell it I, not I. 111 | If you find yourself accessing object instance data (even through accessor 112 | methods) outside of the object itself, you may have too much access to an 113 | object's internals. 114 | 115 | OO novices often treat objects as if they were bundles of records which use 116 | methods to get and set internal values. This simple technique leads to the 117 | unfortunate temptation to spread the object's responsibilities throughout the 118 | entire system. 119 | 120 | You can prevent inappropriate access by making your objects immutable. Provide 121 | the necessary data to their constructors, then disallow any modifications of 122 | this information from outside the class. Expose no methods to mutate instance 123 | data--make all of your public accessors read-only and use internal attribute 124 | writers sparingly. Once you've constructed such an object, you know it's always 125 | in a valid state. You can never modify its data to put it in an invalid state. 126 | 127 | This takes tremendous discipline, but the resulting systems are robust, 128 | testable, and maintainable. Some designs go as far as to prohibit the 129 | modification of instance data I the class itself. 130 | -------------------------------------------------------------------------------- /sections/anonymous_functions.pod: -------------------------------------------------------------------------------- 1 | =head1 Anonymous Functions 2 | 3 | Z 4 | 5 | X 6 | 7 | An I is a function without a name. It behaves exactly like 8 | a named function--you can invoke it, pass it arguments, return values from it, 9 | and take references to it. Yet you can only access an anonymous function by 10 | reference (L), not by name. 11 | 12 | X 13 | X 14 | X 15 | 16 | A Perl idiom known as a I uses hashes to associate input with 17 | behavior: 18 | 19 | =begin programlisting 20 | 21 | my %dispatch = ( 22 | plus => \&add_two_numbers, 23 | minus => \&subtract_two_numbers, 24 | times => \&multiply_two_numbers, 25 | ); 26 | 27 | sub add_two_numbers { $_[0] + $_[1] } 28 | sub subtract_two_numbers { $_[0] - $_[1] } 29 | sub multiply_two_numbers { $_[0] * $_[1] } 30 | 31 | sub dispatch { 32 | my ($left, $op, $right) = @_; 33 | 34 | return unless exists $dispatch{ $op }; 35 | 36 | return $dispatch{ $op }->( $left, $right ); 37 | } 38 | 39 | =end programlisting 40 | 41 | The C function takes arguments of the form C<(2, 'times', 2)>, 42 | evaluates the operation, and returns the result. A trivial calculator 43 | application could use C to figure out which calculation to perform 44 | based on user input. 45 | 46 | =head2 Declaring Anonymous Functions 47 | 48 | X> 49 | 50 | The C builtin used without a name creates and returns an anonymous 51 | function. Use this function reference where you'd use a reference to a named 52 | function, such as to declare the dispatch table's functions in place: 53 | 54 | =begin programlisting 55 | 56 | my %dispatch = ( 57 | plus => sub { $_[0] + $_[1] }, 58 | minus => sub { $_[0] - $_[1] }, 59 | times => sub { $_[0] * $_[1] }, 60 | dividedby => sub { $_[0] / $_[1] }, 61 | raisedto => sub { $_[0] ** $_[1] }, 62 | ); 63 | 64 | =end programlisting 65 | 66 | =begin tip Defensive Dispatch 67 | 68 | Only those functions within this dispatch table are available for users to 69 | call. If your dispatch function used a user-provided string as the literal name 70 | of functions, a malicious user could call any function anywhere by passing a 71 | fully-qualified name such as C<'Internal::Functions::malicious_function'>. 72 | 73 | =end tip 74 | 75 | You may also see anonymous functions passed as function arguments: 76 | 77 | =begin programlisting 78 | 79 | sub invoke_anon_function { 80 | my $func = shift; 81 | return $func->( @_ ); 82 | } 83 | 84 | sub named_func { 85 | say 'I am a named function!'; 86 | } 87 | 88 | invoke_anon_function( \&named_func ); 89 | invoke_anon_function( B ); 90 | 91 | =end programlisting 92 | 93 | =head2 Anonymous Function Names 94 | 95 | X 96 | X> 97 | 98 | Use introspection to determine whether a function is named or anonymous, 99 | whether through C or the CPAN module C's C 100 | function: 101 | 102 | =begin programlisting 103 | 104 | package ShowCaller; 105 | 106 | sub show_caller { 107 | my ($package, $file, $line, $sub) = caller(1); 108 | say "Called from $sub in $package:$file:$line"; 109 | } 110 | 111 | sub main { 112 | my $anon_sub = sub { show_caller() }; 113 | show_caller(); 114 | $anon_sub->(); 115 | } 116 | 117 | main(); 118 | 119 | =end programlisting 120 | 121 | The result may be surprising: 122 | 123 | =begin screen 124 | 125 | Called from ShowCaller::B
126 | in ShowCaller:anoncaller.pl:20 127 | Called from ShowCaller::B<__ANON__> 128 | in ShowCaller:anoncaller.pl:17 129 | 130 | =end screen 131 | 132 | X> 133 | 134 | The C<__ANON__> in the second line of output demonstrates that the anonymous 135 | function has no name that Perl can identify. The CPAN module C's 136 | C function allows you to attach names to anonymous functions: 137 | 138 | =begin programlisting 139 | 140 | use Sub::Name; 141 | use Sub::Identify 'sub_name'; 142 | 143 | my $anon = sub {}; 144 | say sub_name( $anon ); 145 | 146 | my $named = subname( 'pseudo-anonymous', $anon ); 147 | say sub_name( $named ); 148 | say sub_name( $anon ); 149 | 150 | say sub_name( sub {} ); 151 | 152 | =end programlisting 153 | 154 | This program produces: 155 | 156 | =begin screen 157 | 158 | __ANON__ 159 | pseudo-anonymous 160 | pseudo-anonymous 161 | __ANON__ 162 | 163 | =end screen 164 | 165 | Be aware that both references refer to the same underlying anonymous function. 166 | Using C on one reference will change that underlying function; all 167 | other references to that function will see the new name. 168 | 169 | =head2 Implicit Anonymous Functions 170 | 171 | X 172 | 173 | X> 174 | 175 | Perl allows you to declare anonymous functions as function arguments without 176 | using the C keyword. Though this feature exists nominally to enable 177 | programmers to write their own syntax such as that for C and C 178 | (L), you can use it for other things, such as to write I 179 | functions that don't look like functions. 180 | 181 | Consider the CPAN module C, which takes an anonymous function as 182 | the first argument to its C function: 183 | 184 | =begin programlisting 185 | 186 | use Test::More; 187 | use Test::Fatal; 188 | 189 | my $croaker = exception { die 'I croak!' }; 190 | my $liver = exception { 1 + 1 }; 191 | 192 | like $croaker, qr/I croak/, 'die() should croak'; 193 | is $liver, undef, 'addition should live'; 194 | 195 | done_testing(); 196 | 197 | =end programlisting 198 | 199 | You might rewrite this more verbosely as: 200 | 201 | =begin programlisting 202 | 203 | my $croaker = exception( sub { die 'I croak!' } ); 204 | my $liver = exception( sub { 1 + 1 } ); 205 | 206 | =end programlisting 207 | 208 | ... or to pass named functions by reference: 209 | 210 | =begin programlisting 211 | 212 | B 213 | B 214 | 215 | my $croaker = exception \&croaker; 216 | my $liver = exception \&liver; 217 | 218 | like $croaker, qr/I croak/, 'die() should die'; 219 | is $liver, undef, 'addition should live'; 220 | 221 | =end programlisting 222 | 223 | ... but you may I pass them as scalar references: 224 | 225 | =begin programlisting 226 | 227 | B 228 | B 229 | 230 | # BUGGY: does not work 231 | my $croaker = exception $croak_ref; 232 | my $liver = exception $live_ref; 233 | 234 | =end programlisting 235 | 236 | ... because the prototype changes the way the Perl parser interprets this code. 237 | It cannot determine with 100% clarity I C<$croaker> and C<$liver> will 238 | contain, and so will throw an exception. 239 | 240 | =begin screen 241 | 242 | Type of arg 1 to Test::Fatal::exception 243 | must be block or sub {} (not private variable) 244 | 245 | =end screen 246 | 247 | A function which takes an anonymous function as the first of multiple arguments 248 | I have a trailing comma after the function block: 249 | 250 | =begin programlisting 251 | 252 | use Test::More; 253 | use Test::Fatal 'dies_ok'; 254 | 255 | dies_ok { die 'This is my boomstick!' } 'No movie references here'; 256 | 257 | =end programlisting 258 | 259 | This is an occasionally confusing wart on otherwise helpful syntax, courtesy of 260 | a quirk of the Perl parser. The syntactic clarity available by promoting bare 261 | blocks to anonymous functions can be helpful, but use it sparingly and document 262 | the API with care. 263 | -------------------------------------------------------------------------------- /sections/attributes.pod: -------------------------------------------------------------------------------- 1 | =head1 Attributes 2 | 3 | Z 4 | 5 | Named entities in Perl--variables and functions--can have additional metadata 6 | attached in the form of I. These attributes are arbitrary names and 7 | values used with certain types of metaprogramming (L). 8 | 9 | Attribute declaration syntax is awkward, and using attributes effectively is 10 | more art than science. Most programs never use them, but when used well they 11 | offer clarity and maintenance benefits. 12 | 13 | A simple attribute is a colon-preceded identifier attached to a declaration: 14 | 15 | =begin programlisting 16 | 17 | my $fortress B<:hidden>; 18 | 19 | sub erupt_volcano B<:ScienceProject> { ... } 20 | 21 | =end programlisting 22 | 23 | When Perl parses these declarations, it invokes attribute handlers named 24 | C and C, if they exist for the appropriate types 25 | (scalars and functions, respectively). These handlers can do I. If 26 | the appropriate handlers do not exist, Perl will throw a compile-time 27 | exception. 28 | 29 | X> 30 | X 31 | X> 32 | 33 | Attributes may include a list of parameters. Perl treats these parameters as 34 | lists of constant strings. The C module from the CPAN uses such 35 | parametric arguments to good effect: 36 | 37 | =begin programlisting 38 | 39 | sub setup_tests :Test(setup) { ... } 40 | sub test_monkey_creation :Test(10) { ... } 41 | sub shutdown_tests :Test(teardown) { ... } 42 | 43 | =end programlisting 44 | 45 | The C attribute identifies methods which include test assertions and 46 | optionally identifies the number of assertions the method intends to run. 47 | While introspection (L) of these classes could discover the 48 | appropriate test methods, given well-designed solid heuristics, the C<:Test> 49 | attribute is unambiguous. C provides attribute handlers which keep 50 | track of these methods. When the class has finished parsing, C can 51 | loop through the list of test methods and run them. 52 | 53 | The C and C parameters allow test classes to define their own 54 | support methods without worrying about conflicts with other such methods in 55 | other classes. This separates the idea of what this class must do from how 56 | other classes do their work. Otherwise a test class might have only one method 57 | named C and one named C and would have to do everything there, 58 | then call the parent methods, and so on. 59 | 60 | =head2 Drawbacks of Attributes 61 | 62 | X> 63 | X pragma> 64 | X> 65 | X> 66 | 67 | Attributes have their drawbacks. The canonical pragma for working with 68 | attributes (the C pragma) has listed its interface as experimental 69 | for many years, and for good reason. Damian Conway's core module 70 | C is much easier to use, and Andrew Main's 71 | C is a newer approach. Prefer either to C 72 | whenever possible. 73 | 74 | X> 75 | 76 | The worst feature of attributes is that they make it easy to warp the syntax of 77 | Perl in unpredictable ways. You may not be able to predict what code with 78 | attributes will do. Good documentation helps, but if an innocent-looking 79 | declaration on a lexical variable stores a reference to that variable 80 | somewhere, your expectations of its lifespan may be wrong. Likewise, a handler 81 | may wrap a function in another function and replace it in the symbol table 82 | without your knowledge--consider a C<:memoize> attribute which automatically 83 | invokes the core C module. 84 | 85 | Attributes I help you to solve difficult problems or to make an API much 86 | easier to use. When used properly, they're powerful--but most programs never 87 | need them. 88 | -------------------------------------------------------------------------------- /sections/autoload.pod: -------------------------------------------------------------------------------- 1 | =head1 AUTOLOAD 2 | 3 | Z 4 | 5 | Perl does not require you to declare every function before you call it. Perl 6 | will happily attempt to call a function even if it doesn't exist. Consider the 7 | program: 8 | 9 | =begin programlisting 10 | 11 | use Modern::Perl; 12 | 13 | bake_pie( filling => 'apple' ); 14 | 15 | =end programlisting 16 | 17 | When you run it, Perl will throw an exception due to the call to the undefined 18 | function C. 19 | 20 | Now add a function called C: 21 | 22 | =begin programlisting 23 | 24 | sub AUTOLOAD {} 25 | 26 | =end programlisting 27 | 28 | When you run the program now, nothing obvious will happen. Perl will call a 29 | function named C in a package--if it exists--whenever normal 30 | dispatch fails. Change the C to emit a message to demonstrate that 31 | it gets called: 32 | 33 | =begin programlisting 34 | 35 | sub AUTOLOAD { B } 36 | 37 | =end programlisting 38 | 39 | X> 40 | 41 | The C function receives the arguments passed to the undefined 42 | function in C<@_> and the fully-qualified I of the undefined function in 43 | the package global C<$AUTOLOAD> (here, C): 44 | 45 | =begin programlisting 46 | 47 | sub AUTOLOAD { 48 | B 49 | 50 | # pretty-print the arguments 51 | local $" = ', '; 52 | say "In AUTOLOAD(@_) B!" 53 | } 54 | 55 | =end programlisting 56 | 57 | Extract the method name with a regular expression (L): 58 | 59 | =begin programlisting 60 | 61 | sub AUTOLOAD { 62 | B 63 | 64 | # pretty-print the arguments 65 | local $" = ', '; 66 | say "In AUTOLOAD(@_) B!" 67 | } 68 | 69 | =end programlisting 70 | 71 | Whatever C returns, the original call receives: 72 | 73 | =begin programlisting 74 | 75 | say secret_tangent( -1 ); 76 | 77 | sub AUTOLOAD { return 'mu' } 78 | 79 | =end programlisting 80 | 81 | So far, these examples have merely intercepted calls to undefined functions. 82 | You have other options. 83 | 84 | =head2 Redispatching Methods in AUTOLOAD() 85 | 86 | X; redispatch> 87 | X; delegation> 88 | X 89 | X 90 | X 91 | X 92 | 93 | A common pattern in OO programming (L) is to I or I 94 | certain methods from one object to another. A logging proxy can help with 95 | debugging: 96 | 97 | =begin programlisting 98 | 99 | package Proxy::Log; 100 | 101 | # constructor blesses reference to a scalar 102 | 103 | sub AUTOLOAD { 104 | my ($name) = our $AUTOLOAD =~ /::(\w+)$/; 105 | Log::method_call( $name, @_ ); 106 | 107 | my $self = shift; 108 | return $$self->$name( @_ ); 109 | } 110 | 111 | =end programlisting 112 | 113 | This C extracts the name of the undefined method. Then it 114 | dereferences the proxied object from a blessed scalar reference, logs the 115 | method call, then invokes that method on the proxied object with the provided 116 | parameters. 117 | 118 | =head2 Generating Code in AUTOLOAD() 119 | 120 | X; code installation> 121 | 122 | This double dispatch is easy to write but inefficient. Every method call on the 123 | proxy must fail normal dispatch to end up in C. Pay that penalty 124 | only once by installing new methods into the proxy class as the program needs 125 | them: 126 | 127 | =begin programlisting 128 | 129 | sub AUTOLOAD { 130 | my ($name) = our $AUTOLOAD =~ /::(\w+)$/; 131 | my $method = sub { ... }; 132 | 133 | B 134 | B<*{ $AUTOLOAD } = $method;> 135 | return $method->( @_ ); 136 | } 137 | 138 | =end programlisting 139 | 140 | The body of the previous C has become a closure (L) bound 141 | over the I of the undefined method. Installing that closure in the 142 | appropriate symbol table allows all subsequent dispatch to that method to find 143 | the created closure (and avoid C). This code finally invokes the 144 | method directly and returns the result. 145 | 146 | Though this approach is cleaner and almost always more transparent than 147 | handling the behavior directly in C, the code I by 148 | C may see C in its C list. While it may 149 | violate encapsulation to care that this occurs, leaking the details of I 150 | an object provides a method may also violate encapsulation. 151 | 152 | X 153 | X; tailcall> 154 | 155 | Some code uses a tailcall (L) to I the current invocation 156 | of C with a call to the destination method: 157 | 158 | =begin programlisting 159 | 160 | sub AUTOLOAD { 161 | my ($name) = our $AUTOLOAD =~ /::(\w+)$/; 162 | my $method = sub { ... } 163 | 164 | no strict 'refs'; 165 | *{ $AUTOLOAD } = $method; 166 | B 167 | } 168 | 169 | =end programlisting 170 | 171 | This has the same effect as invoking C<$method> directly, except that 172 | C will no longer appear in the list of calls available from 173 | C, so it looks like normal method dispatch occurred. 174 | 175 | =head2 Drawbacks of AUTOLOAD 176 | 177 | Z 178 | 179 | X; drawbacks> 180 | X> 181 | X> 182 | X pragma> 183 | X> 184 | X 185 | 186 | C can be useful, though it is difficult to use properly. The 187 | naEve approach to generating methods at runtime means that the C 188 | method will not report the right information about the capabilities of objects 189 | and classes. The easiest solution is to predeclare all functions you plan to 190 | C with the C pragma: 191 | 192 | =begin programlisting 193 | 194 | use subs qw( red green blue ochre teal ); 195 | 196 | =end programlisting 197 | 198 | =begin tip Now You See Them 199 | 200 | Forward declarations are useful only in the two rare cases of attributes 201 | (L) and autoloading (L). 202 | 203 | =end tip 204 | 205 | That technique documents your intent well, but requires you to maintain a 206 | static list of functions or methods. Overriding C (L) 207 | sometimes works better: 208 | 209 | =begin programlisting 210 | 211 | sub can { 212 | my ($self, $method) = @_; 213 | 214 | # use results of parent can() 215 | my $meth_ref = $self->SUPER::can( $method ); 216 | return $meth_ref if $meth_ref; 217 | 218 | # add some filter here 219 | return unless $self->should_generate( $method ); 220 | 221 | $meth_ref = sub { ... }; 222 | no strict 'refs'; 223 | return *{ $method } = $meth_ref; 224 | } 225 | 226 | sub AUTOLOAD { 227 | my ($self) = @_; 228 | my ($name) = our $AUTOLOAD =~ /::(\w+)$/;> 229 | 230 | return unless my $meth_ref = $self->can( $name ); 231 | goto &$meth_ref; 232 | } 233 | 234 | =end programlisting 235 | 236 | C is a big hammer; it can catch functions and methods you had no 237 | intention of autoloading, such as C, the destructor of objects. If 238 | you write a C method with no implementation, Perl will happily 239 | dispatch to it instead of C: 240 | 241 | =begin programlisting 242 | 243 | # skip AUTOLOAD() 244 | sub DESTROY {} 245 | 246 | =end programlisting 247 | 248 | =begin tip A Very Special Method 249 | 250 | The special methods C, C, and C never go 251 | through C. 252 | 253 | =end tip 254 | 255 | If you mix functions and methods in a single namespace which inherits from 256 | another package which provides its own C, you may see the strange 257 | error: 258 | 259 | =begin screen 260 | 261 | Use of inherited AUTOLOAD for non-method I() is deprecated 262 | 263 | =end screen 264 | 265 | If this happens to you, simplify your code; you've called a function which does 266 | not exist in a package which inherits from a class which contains its own 267 | C. The problem compounds in several ways: mixing functions and 268 | methods in a single namespace is often a design flaw, inheritance and 269 | C get complex very quickly, and reasoning about code when you don't 270 | know what methods objects provide is difficult. 271 | 272 | C is useful for quick and dirty programming, but robust code avoids 273 | it. 274 | -------------------------------------------------------------------------------- /sections/automatic_dereferencing.pod: -------------------------------------------------------------------------------- 1 | =head1 Automatic Dereferencing 2 | 3 | Z 4 | 5 | X> 6 | 7 | Perl can automatically dereference certain references on your behalf. Given an 8 | array reference in C<$arrayref>, you can write: 9 | 10 | =begin programlisting 11 | 12 | push $arrayref, qw( list of values ); 13 | 14 | =end programlisting 15 | 16 | Given an expression which returns an array reference, you can do the same: 17 | 18 | =begin programlisting 19 | 20 | push $houses{$location}[$closets], \@new_shoes; 21 | 22 | =end programlisting 23 | 24 | =begin tip The Autoderef Experiment 25 | 26 | After Perl 5.18, you must enable this feature with C. That should be a sign to tread carefully here. 28 | 29 | =end tip 30 | 31 | X> 32 | X> 33 | X> 34 | X> 35 | X> 36 | X> 37 | X> 38 | X> 39 | 40 | The same goes for the array operators C, C, C, C, 41 | C, C, and C and the hash operators C, C, and 42 | C. If the reference provided is not of the proper type--if it does not 43 | dereference properly--Perl will throw an exception. While this may seem more 44 | dangerous than explicitly dereferencing references directly, it is in fact the 45 | same behavior: 46 | 47 | =begin programlisting 48 | 49 | my $ref = sub { ... }; 50 | 51 | # will throw an exception 52 | push $ref, qw( list of values ); 53 | 54 | # will also throw an exception 55 | push @$ref, qw( list of values ); 56 | 57 | =end programlisting 58 | 59 | Unfortunately, this automatic dereferencing has two problems. First, it only 60 | works on plain variables. If you have a Ced array or hash, a Cd 61 | hash, or an object with array or hash overloading, Perl will throw a runtime 62 | exception instead of dereferencing the reference. 63 | 64 | Second, remember that C, C, and C can operate on both 65 | arrays and hashes. You can't look at: 66 | 67 | =begin programlisting 68 | 69 | my @items = each $ref; 70 | 71 | =end programlisting 72 | 73 | ... and tell whether C<@items> contains a list of key/value pairs or 74 | index/value pairs, because you don't know whether you should expect C<$ref> to 75 | refer to a hash or an array. Yes, choosing good variable names will help, but 76 | this code is intrinsically confusing. 77 | 78 | Neither of these drawbacks make this syntax I in general, but its 79 | rough edges and potential for confusing readers make it less useful than it 80 | could be. 81 | -------------------------------------------------------------------------------- /sections/barewords.pod: -------------------------------------------------------------------------------- 1 | =head1 Barewords 2 | 3 | Z 4 | 5 | X 6 | X pragma> 7 | X> 8 | 9 | Perl's parser understands Perl's builtins and operators. It uses sigils to 10 | identify variables and other punctuation to recognize function and method 11 | calls. Yet sometimes the parser has to guess what you mean, especially when you 12 | use a I--an identifier without a sigil or other syntactically 13 | significant punctuation. 14 | 15 | =head2 Good Uses of Barewords 16 | 17 | X 18 | 19 | Though the C pragma (L) rightly forbids ambiguous barewords, 20 | some barewords are acceptable. 21 | 22 | =head3 Bareword hash keys 23 | 24 | X 25 | X; unary operator> 26 | 27 | Hash keys in Perl are usually I ambiguous because the parser can identify 28 | them as string keys; C in C<$games{pinball}> is obviously a string. 29 | 30 | Occasionally this interpretation is not what you want, especially when you 31 | intend to I a builtin or a function to produce the hash key. To make 32 | these cases clear, pass arguments to the function, use parentheses, or prepend 33 | a unary plus to force the evaluation of the builtin: 34 | 35 | =begin programlisting 36 | 37 | # the literal 'shift' is the key 38 | my $value = $items{B}; 39 | 40 | # the value produced by shift is the key 41 | my $value = $items{B} 42 | 43 | # the function returns the key 44 | my $value = $items{B} 45 | 46 | # unary plus indicates the builtin shift 47 | my $value = $items{B<+>shift}; 48 | 49 | =end programlisting 50 | 51 | =head3 Bareword package names 52 | 53 | Z 54 | 55 | X 56 | 57 | Package names are also barewords. If your naming conventions rule that package 58 | names have initial capitals and functions do not, you'll rarely encounter 59 | naming collisions. Even still, Perl must determine how to parse C<< 60 | Package->method >>. Does it mean "call a function named C and call 61 | C on its return value?" or "Call a method named C in the 62 | C namespace?" The answer depends on the code Perl has already compiled 63 | when it encounters that method call. 64 | 65 | Force the parser to treat C as a package name by appending the package 66 | separator (C<::>) or make it a literal string: 67 | 68 | =begin programlisting 69 | 70 | # probably a class method 71 | Package->method; 72 | 73 | # definitely a class method 74 | PackageB<::>->method; 75 | 76 | # a slightly less ugly class method 77 | B<'>PackageB<'>->method; 78 | 79 | # package separator 80 | my $q = Plack::Request::->new; 81 | 82 | # unambiguously a string literal 83 | my $q = 'Plack::Request'->new; 84 | 85 | =end programlisting 86 | 87 | Almost no real code does this, but it's unambiguous, so be able to read it. 88 | 89 | =head3 Bareword named code blocks 90 | 91 | X> 92 | X> 93 | X> 94 | X> 95 | X> 96 | X> 97 | X> 98 | 99 | The special named code blocks C, C, C, C, 100 | C, C, and C are barewords which I functions 101 | without the C builtin. You've seen this before (L): 102 | 103 | =begin programlisting 104 | 105 | package Monkey::Butler; 106 | 107 | BEGIN { initialize_simians( __PACKAGE__ ) } 108 | 109 | sub AUTOLOAD { ... } 110 | 111 | =end programlisting 112 | 113 | While you I declare C without using C, few people do. 114 | 115 | =head3 Bareword constants 116 | 117 | X 118 | 119 | Constants declared with the C pragma are usable as barewords: 120 | 121 | =begin programlisting 122 | 123 | # don't use this for real authentication 124 | use constant NAME => 'Bucky'; 125 | use constant PASSWORD => '|38fish!head74|'; 126 | 127 | return unless $name eq NAME && $pass eq PASSWORD; 128 | 129 | =end programlisting 130 | 131 | These constants do I interpolate in double-quoted strings. 132 | 133 | X 134 | 135 | Constants are a special case of prototyped functions (L). When you 136 | predeclare a function with a prototype, the parser will treat all subsequent 137 | uses of that bareword specially--and will warn about ambiguous parsing errors. 138 | All other drawbacks of prototypes still apply. 139 | 140 | =head2 Ill-Advised Uses of Barewords 141 | 142 | X 143 | 144 | No matter how cautiously you code, barewords still produce ambiguous code. You 145 | can avoid the worst abuses, but you will encounter several types of barewords 146 | in legacy code. 147 | 148 | =head3 Bareword hash values 149 | 150 | X 151 | 152 | Some old code may not take pains to quote the I of hash pairs: 153 | 154 | =begin programlisting 155 | 156 | # poor style; do not use 157 | my %parents = ( 158 | mother => Annette, 159 | father => Floyd, 160 | ); 161 | 162 | =end programlisting 163 | 164 | When neither the C nor C functions exist, Perl will 165 | interpret these barewords as strings. C will produce an error in 166 | this situation. 167 | 168 | =head3 Bareword function calls 169 | 170 | X 171 | X> 172 | 173 | Code written without C may use bareword function names. Adding 174 | parentheses will make the code pass strictures. Use C (see 175 | C) to discover how Perl parses them, then parenthesize 176 | accordingly. 177 | 178 | =head3 Bareword filehandles 179 | 180 | X 181 | 182 | Prior to lexical filehandles (L), all file and directory 183 | handles used barewords. You can almost always safely rewrite this code to use 184 | lexical filehandles. Perl's parser recognizes the special exceptions of 185 | C, C, and C. 186 | 187 | =head3 Bareword sort functions 188 | 189 | X 190 | X> 191 | X> 192 | 193 | The second operand of the C builtin can be the I of a function to 194 | use for sorting. While this is rarely ambiguous to the parser, it can confuse 195 | I readers. The alternative of providing a function reference in a scalar 196 | is little better: 197 | 198 | =begin programlisting 199 | 200 | # bareword style 201 | my @sorted = sort compare_lengths @unsorted; 202 | 203 | # function reference in scalar 204 | my $comparison = \&compare_lengths; 205 | my @sorted = sort $comparison @unsorted; 206 | 207 | =end programlisting 208 | 209 | The second option avoids the use of a bareword, but the result is longer. 210 | Unfortunately, Perl's parser I understand the single-line version due 211 | to the special parsing of C; you cannot use an arbitrary expression (such 212 | as taking a reference to a named function) where a block or a scalar might 213 | otherwise go. 214 | 215 | =begin programlisting 216 | 217 | # does not work 218 | my @sorted = sort \&compare_lengths @unsorted; 219 | 220 | =end programlisting 221 | 222 | In both cases, the way C invokes the function and provides arguments can 223 | be confusing (see C for the details). Where possible, consider 224 | using the block form of C instead. If you must use either function form, 225 | add a comment about what you're doing and why. 226 | -------------------------------------------------------------------------------- /sections/builtins.pod: -------------------------------------------------------------------------------- 1 | =head0 Builtins 2 | 3 | Z