http://www.perlmonks.org?node_id=847154

(Cross-posted a few places.)

I'm preparing to publish a book called Modern Perl which explains how Perl 5 works and how to write great code. The draft of the Modern Perl book is available for review. I'm especially interested in hearing from people who don't consider themselves expert Perl 5 programmers. The goal of the book is to explain how Perl 5 works (and how to write Perl 5 effectively) to help novices become adepts.

I welcome any and all comments and suggestions.

Replies are listed 'Best First'.
Re: Modern Perl: The Book: The Draft (feedback)
by eyepopslikeamosquito (Archbishop) on Jun 30, 2010 at 01:09 UTC

    Wow. I've taken a quick look and really like it!

    Given my keen interest in this domain, I read the "Stylish Perl" chapter first. This chapter is excellent as is, and very short (which is desirable). That said, taken from On Coding Standards and Code Reviews, you might consider adding more material derived from one or more of the following.

    Cleverness

    • If you must rely on cleverness, encapsulate and comment it.

    Design

    • Establish a rational error handling policy and follow it strictly.
    • Coupling and Cohesion. Systems should be designed as a set of cohesive modules as loosely coupled as is reasonably feasible.
    • Data hiding. Minimize the exposure of implementation details.
    • Minimize the use of global data.
    • Interfaces matter. Once an interface becomes widely used, changing it becomes practically impossible (just about anything else can be fixed in a later release).
    • Design the module's interface first.
    • Design interfaces that are: consistent; easy to use correctly; hard to use incorrectly; easy to read, maintain and extend; clearly documented; appropriate to your audience. Be sufficient, not complete; it is easier to add a new feature than to remove a mis-feature.

    Maintainability/Supportability

    • Minimize the scope of variables, pragmas, etc..
    • The result of every file operation or API call or external command should be checked, and unexpected results handled.

    Commenting

    • Generally, comments should describe what and why, not how.
    • Separate user versus maintainer documentation.
    • Every non-local named entity should be commented.
    • There should be a comment on any code that is likely to look wrong or confusing to the next person reading the code.

      Thanks for your comments. I've integrated several of your suggestions into that section. How would you like me to credit you in the CREDITS file?

Re: Modern Perl: The Book: The Draft
by Jenda (Abbot) on Jun 30, 2010 at 06:21 UTC

    ch 1, Perldoc: I think the windozers might appreciate a note that ActivePerl (and probably other distributions) contains and keeps updated a HTML version of the docs they can browse, accessible from the Start menu. And possibly even that they can create a simple batch like this:

    @rem Save as pdoc.bat @perldoc -o html -T -w index %* > %TEMP%\perldoc_temp.html && start %T +EMP%\perldoc_temp.html
    store it in a directory that's in PATH and then pdoc ... will render the documentation in HTML and open it in their favorite browser. I think they'll find that easier to read than if they stay restricted to the shell window.

    ch 1, Implicit ideas, The Default Scalar Variable: "the three-argument form of print and say"??? print FILEHANDLE "text"; has just two arguments. In either case I would not talk about N-argument form of print/say, it's not the number of arguments that matters. print/say simply uses $_ only if passed no arguments. Fullstop.

    ch 1, The Default Array Variables: s/Another default variable is available inside Perl subroutines; this is \@_\./Another default variable available inside Perl subroutines is @_./;

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

      Thanks for the suggestions. I've incorporated them; if I figure out an easy way to refer to pdoc without disrupting the flow of narrative, I'll include that too.

Re: Modern Perl: The Book: The Draft
by hexcoder (Curate) on Jun 29, 2010 at 21:00 UTC
    Hi chromatic,
    thanks for your work! Here are my review comments (caution: not from a native speaker):

    Chapter 1:
    3rd paragraph, 2nd sentence:
    I find the wording (Its design goals ...) a bit complicated and hard to swallow.

    4th paragraph, typo:
    philsophies -> philosophies

    5th paragraph in section 'Perldoc':
    It describes each section of the documentation
    instead of
    It describes each section of documentation

    1st paragraph, 2nd sentence of section 'Expressivity':
    I do not understand the phrase
    ... inform Perl's design
    I suggest
    ... influenced Perl's design

    3rd paragraph, 1st sentence (yes, but please let this style be the absolute exception, thank you :-)

    1st sentence of section 'Void, Scalar, and List Context'
    The wording 'One of the axes' suggests orthogonality to me, as if there were (pure) arrays of strings as well as (pure) arrays of numbers. Since there are only arrays of scalars, I would phrase that as 'One of the aspects'.

    Regarding the marked text 'Check how many other string functions this includes?' in section 'The Default Scalar Variable'; this question is answered in the book 'Effective Perl Programming', 2nd ed., on page 58

    9th paragraph (Note that ...)
    I suggest
    must compare always two elements of its list
    instead of
    must process the elements of its list two at a time.

    Chapter 3:
    3rd sentence in section 'Variable Naming', typo
    Variables
    instead of
    Varibles

      As a native speaker, I just want to remark that I disagree completely with each of your suggestions to rephrase. If I were the author, I would go on to illustrate my meaning in each of these cases and prod you for information on how I could really improve them, based on whatever unstated misunderstanding is actually troubling you.

      But I'm not the author; I'm just an enthusiast of expression in such ways as provided by English and Perl. So, my curiosity is piqued: what is more awkward in the third paragraph of the first chapter than "must compare always two elements"?

        Thanks, that is interesting to hear! If the original phrases are comprehensible, I need to work a bit on my skills...

        BTW: i just noticed the book is really a moving target, as i cannot find the original text anymore.

        Anyway, the vanished text under chapter 1, section 'The Default Scalar Variable' described the predeclared variables $a and $b, and reasoned that $_ could not be used in sort() because sort() 'must process the elements of its list two at a time'. This is correct of course (the elements are just not necessarily neighbors), but the wording suggested to me: sort() iterates on adjacent elements pairs of its list.

      Thanks for all of your comments. Please let me know how you'd like me to credit you in the book's CREDITS file.

Re: Modern Perl: The Book: The Draft
by Anonymous Monk on Jun 30, 2010 at 15:52 UTC

    Hi chromatic. Thanks for the great work.

    I think the book also needs an early chapter covering:

    • installing your own perl into someplace like /usr/local/perl-5.x.y (that is, into a tree all to itself) since the OS tends to use its own system Perl for its own business, and new users should have their own Perl that they can play with
    • installing cpan packages into your own /usr/local Perl but using your OS's package manager for installing packages into the system Perl.
    • installing and using cpanm
    • local::lib -- though this is less important if they've installed their own Perl into /usr/local

    New users need that stuff before they can feel comfortable with their setup and dig into more language details.

    I'd also like to see a brief "cpan module recommendations" chapter.

    This book looks great. Looking forward to making time to read it. Thanks again.

      I agree with these points pretty strongly. Being able to run your own perl installation is important in the scheme of "Modern Perl." A huge amount of what ends up being recommended/used is not core. Being stuck with a core installation makes following the advice an exercise in pain and confusion unless there is help for getting the pieces together.

      I am extremely happy with cpanm so far.

      Thanks for the suggestion. I've added a preface which will cover these topics in brief. (I'd most rather link to a section on the Perl 5 wiki with full installation instructions.)

Re: Modern Perl: The Book: The Draft
by atcroft (Abbot) on Jul 02, 2010 at 06:36 UTC
    In Chapter 03, under the header "Names", you have a comment block regarding rearranging the following two sections. If one of those is the one on the utf8 pragma, then may I humbly suggest moving that section into the section above the examples, such as (emphasis added for change clarity):

    Names (or identifiers) are everywhere in Perl programs: variables, functions, packages, classes, and even filehandles have names. These names all start with a letter or an underscore. They may optionally include any combination of letters, numbers, and underscores. When the utf8 pragma (Pragmas, Unicode and Strings) is in effect, you may use any valid UTF-8 characters in identifiers, provided that they still start with a letter or underscore and optionally contain one or more alphanumeric or underscore characters. These are all valid Perl identifiers:

    This would also optionally allow you to provide an example of a UTF-8 character in a variable, if you so desired.

    Still reading, but looks impressive so far. I hope to have the time to dig further, and to pick it up when it comes out in dead-tree form.

    HTH.

      Thanks for the suggestion. I've integrated it into that section. How would you like me to credit you in CREDITS?

Re: Modern Perl: The Book: The Draft
by roboticus (Chancellor) on Jul 05, 2010 at 13:39 UTC

    chromatic:

    I've read a bit of it, and here are my notes so far:

    Chapter 1

    When you mention Baby perl, I'd suggest including a sidebar giving examples, such as:

    # new programmer from C/C++ background my $count = @array_of_stuff; for (my $index=0; $index<$count; ++$index) { $array_of_stuff[$index] = $array_of_stuff[$index]*3; } # Baby perl (?) my @new_array; for (@array_of_stuff) { push @new_array, $_*3; } @array_of_stuff = @new_array; # More advanced: operate on the whole list @array_of_stuff = map { $_*3 } @array_of_stuff

    In Numeric, String, and Boolean Context, first I'd move:

    In exchange for not having to declare (or at least track) explicitly what type of data a variable contains or a function produces, Perl offers specific type contexts that tell the compiler how to treat a given value during an operation.

    to the end of the first paragraph. I'd then change:

    In exchange for not having to declare (or at least track) explicitly what type of data a variable contains or a function produces, Perl offers specific type contexts that tell the compiler how to treat a given value during an operation. The eq operator treats its operands as strings by enforcing string context on them. The == operator enforces numeric context.

    to something like:

    The code fails because the == operator enforces numeric context (e.g., it treats both 'alice' and 'bob' as numbers, and both are 0 in numeric context). You use the eq operator to specify string context for the comparison.

    In the section The Default Scalar Variable you may want to change "best example a linguistic" to "best example of a linguistic".

    In the same section, you have a snippet of code including:

    say "'$uncle'"

    Which may give a confusing error message to someone reading the book. (Generally, when reading a programming book, I keep a couple editor windows open and try executing all the snippets I find, and make variations to verify I understand what's being said, and to solidify what I'm told.) So if someone is noodling around and tries the snippet, they'll get an error since "say" isn't enabled by default. You might want to add a sidebar earlier in the chapter giving them an example of how they can follow along in the book. Something like telling them to add the module with the -M switch on all your examples, or a use statement at the start of their test files or some such. (In fact, I'd suggest you have a template for them to use for their experiments, and then run all your snippets in the template to ensure that no syntax errors pop up. This can give you an opportunity to enforce the mantra "always use strict and warnings". Then, if you have "answers" at the end of your book, you can include the complete bit using your template.)

    Chapter 3

    I've not finished this chapter yet. But I wanted to get you these notes before they become stale and useless...

    In the Names section, I'd move the paragraph starting "When the utf8 pragma" into the introduction--specifically into the sidebar suggested earlier with the template. Then you have an opportunity to have them add it to the template (or not) as they see fit.

    In the paragraph starting "These rules only apply to literal names found", I don't follow what you mean in the first sentence. If you're referring to the stuff just before the utf8 bit, then I'd change "literal" to "variable" and /, and I'd put the sentence after the end of the invalid perl identifiers list, fleshing it out a bit to make a paragraph. (When you say literal, I think stuff in single/double quotes, so it makes the sentence feel somewhat "off".)

    As for the rest of the paragraph, I'd hold that for later (probably in the hash section) as many won't know what a symbolic lookup is, and you'll have the chance to explain that in the hash section.


    I'll try to find some time to continue reading later.

    ...roboticus

      Thanks for your comments. How would you like me to credit you?

        chromatic:

        I didn't do enough to warrant anything. I'd be happy to be included as part of "and many other contributors from www.perlmonks.com" or some such.

        ...roboticus

Re: Modern Perl: The Book: The Draft
by mr_mischief (Monsignor) on Jul 05, 2010 at 11:52 UTC

    In chapter 3, where you mention "Interpolating undef into a string--or evaluating it in a string context--produces an uninitialized value warning, if you have warnings enabled.", I would consider adding " (and you usually should)" or something close to the end of the sentence, possibly with a reference to the appropriate section in chapter 12. Warnings and strictures are difficult to overemphasize for all but quick-and-dirty programs after all.

    Also in chapter 3, you have a type in "It cheap, both in terms of code and memory, to use only the keys of a hash for storage." in the Hash Idioms section. We're missing a form of "to be", either "It's" or "It is".

    Again in the hash idioms section, you have "Hashes can also serve many purposes named parameters passed to functions." which seems to have a word or two missing, like perhaps "such as".

    s/intent/intend/ in "To prevent someone from accidentally adding a hash key you did not intent" in the Locking Hashes section of chapter 3.

    Under Boolean Coercion in chapter 3, you use "truthiness" rather than "truthfulness" or some other wording. I've seen "truthiness", particularly in the Perl community, and it's easy enough to understand. I just thought a nonstandard usage was worth reconsidering even if reconsidering it means you still use it. My concern would be the impression left on those not familiar with it. You might even consider introducing it as a term as you would with "stringify" and others, since it is both nonstandard English and denotes a specific meaning with slightly different connotations from "truthfulness".

    In the Autovivication section in ch. 3, you have the following sentence: "You can also check for the existence of specific hash keys and the number of elements in arrays before dereferencing each level of a complex data structure, but that can produce tedious, length code which many Perl programmers prefer to avoid." in which "length" should be "lengthy".

    In chapter 4's Arity section, I think "Grouping parentheses clarify, yet watch out for confusion in code such as:" reads better starting as "Use grouping parentheses".

    In Chapter 5, your State vs. Closures section has a recursive link to the section.

    In your Drawbacks of AUTOLOAD section in chapter 5, you have an improperly escaped entity in "naïve", such that it currently reads "naiumlve" instead.

    In Chapter 6, in your The qr// Operator and Regex Combinations section, one of your examples is missing a closing slash after '$field'.

    Your character classes in chapter 6 are kind of tacked on to the section Metacharacters. The prose reads very clearly this way and the examples follow well as is, so I'm not sure if your intent was to only define character classes or also to have a section header for them.

    Still in the Metacharacters section, you have the sentence "Just as the word and digit class metacharacters (\w and \d) have negations, so to you can negate a character class.". I'm thinking s/so too you can/so too can you/ to make that read more clearly.

    In chapter 7 in the Methods section, you have the following sentence which seems half-edited: "The invocant of a method in Perl 5 method is its first argument."; the second instance of "method" seems out of place.

    The first paragraph of your Polymorphism section has a closing parenthesis which no matching open parenthesis. When reading, I inserted the open parenthesis such that the phrase "(into a single place)" is the parenthetical.

    Moving on to chapter 8, in your Writing Maintainable Perl section, under the "name entities well" bullet point, you have the sentence "The ease with which you can name these entities system reveals your understanding of the problem and the cohesion of your design." in which the word "system" seems simply superfluous. Maybe accidentally left in during a rewording?

    In the Running Tests section of chapter 9, the following sentence has a doubled word: "The core module Test::Harness interprets TAP and and displays only the most pertinent information."

    In your exporting example featuring the functions monkey_dance and monkey_sleep, you've currently got @EXPORT_OK where it seems you want @EXPORT instead.

    In chapter 10, in your section on the Schwartzian Transform, you have, "Suppose you want to print a list of extensions and co-workers sorted by their names, not their extensions. In other words, you need to sort a hash by its keys." s/keys/values/ there.

    In chapter 11, there exists a paragraph in the Prototypes section that is, in its entirety, "A prototype is a piece of optional metadata attached to a function declaration. Novices commonly assume that these ". That thought isn't finished elsewhere, and that seems a good place to go ahead and finish it.

    In chapter 12, the Missing Defaults section is missing some punctuation, and around that missing punctuation is a little confusing content. "Perl 5 added many great new features, but it also kept compatibility with the previous seven Sixteen years later, the best way to write clean, maintainable, powerful, and succinct Perl 5 code is very different from Perl 5.000.". I can easily guess that there should be a period between "seven" and "Sixteen". It's less obvious what "seven" itself means in context. Seven versions before 5? Seven previous years? Yes, in 1994 it'd been seven years since Perl 1.0 was released, but that's not clear to the uninitiated. Perhaps s/seven Sixteen/seven years of Perl's history. Sixteen/ makes it more clear.

    I also, between your chapter on what to avoid in 11 and the pointers on what to add to default behavior in chapter 12 was left wondering where and whether 2-argument vs. 3-argument open could be mentioned. I'm not sure where exactly I'd put it if I were writing, and not entirely sure if it would make the cut. I'd at least consider putting it somewhere, and I was a little surprised I didn't see the tip somewhere among the mentions of IO::Handle, lexical filehandles, and such.

      Thanks for all of this review! How would you like me to credit you in the book?

        I sign all my professional work as "Christopher E. Stith".

        It would be quite nice see my name in such a clear and useful volume. I'm considering transitioning to tech writer or proofreader if I decide to go back to school. A credit in your book would be a fine addition to my portfolio for that.

        In any event, I appreciate the chance to read and comment on the manuscript. It was a pleasure. I've been meaning actually to give it another read through, and I'll see if there's anything I didn't see the first time. If you get a newer draft ready, I'd be happy to read that, too.

Re: Modern Perl: The Book: The Draft
by jethro (Monsignor) on Jul 06, 2010 at 13:06 UTC

    I've got two problems with Chapter 3. Paragraph "Strings":

    You may escape control and non-printable characters in the string:

    my $newline = "\n"; my $tab = "\t"; my $carriage = "\r";

    You may also embed these control characters themselves directly into the string--a string declaration may cross lines and run as long as you want, but it's often more maintainable to use the escapes."

    * 1) First sentence doesn't fit with the examples and is half wrong. You can escape '"', but you can't escape a non-printable character like the newline. You can only embed it by escaping the character 'n'. (Am I nitpicking? Could be)

    I would change that to "You may embed control and non-printable characters in the string by escaping" (which is essentially the same info as in the second sentence, after the examples) or upgrade the examples to include actual characters you need to escape

    * 2) The second part of the second sentence I had to read 4 times before I understood it. Since only $newline has anything to do with making a string cross lines at minimum the plural form of "escape" is misleading

    Also a source of my confusion was probably the different meaning of 'crossing lines' in the source code and in the string. It should be mentioned explicitly or shown by example that if a string declaration crosses lines so does the string itself. Actually an example like

    $n= "two lines";

    is equivalent to

    $n= "two\nlines";

    might say more than a thousand words.

Re: Modern Perl: The Book: The Draft
by jethro (Monsignor) on Jul 06, 2010 at 14:36 UTC

    Chapter 7, Encapsulation

    The examples shown so far do not describe how to store those instances.

    Either "instances" should be "attributes" or the sentence makes no sense to me

    Chapter 7, Polymorphism

    A Cheese object may have an age() method that lets you determine how long to stow $cheddar so that it becomes sharp

    I'm not a native english speaker, but this only became clear after reading on, because 'determine' also has a meaning of ascertain, i.e. "I determined the length of a day to be 10 hours on this planet". Maybe 'decide' or 'define' are less ambiguous.

    UPDATE: Chapter 7, Blessed References

    An class representing basketball players
      At least one source, the free online dictionary (favored by Google when a search is bound to 'dict'), gives chromatic's use as the second choice for 'determine' when used transitively. Personally, I disagree, particularly in this context: 'determine' in the sense of 'ascertain' appears close to optimal.

      "stow" may be otherwise; perhaps "store"?

      But lest any take jethro's reference to his relationship with English as an adverse indicator, my view is that his use of the language puts to shame much of what we see here from individuals whose status as "native English speaker(s)" is self-evident.

        Could it be that you and Anonymous Monk made the same mistake as I did initially of reading the example as if age() was meant as a read-only function?

        As I understand the example, age() is a write-only(!) function, you set the time you want to stow away the cheese in a dark cellar (or you simply stow away the cheese a predetermined time). The following sentence in the book makes that quite clear I think. So 'ascertain' would be exactly the wrong meaning, suggesting reading of a stored value.

        If I'm right, you made my point ;-). And in any case thanks for the compliment.

        PS: If I'm right, the second age() call in the example following the cheese paragraph should have a parameter of "6", "6m" or "6 months"

      Or like
      A Cheese object may have an age() method that tells you how long to keep $cheddar for a sharper flavor.
Re: Modern Perl: The Book: The Draft
by RedElk (Hermit) on Jul 05, 2010 at 02:46 UTC

    I've only read the first few chapters but like it so far. I'm by no means an expert so I feel like your target audience. Generally speaking, the tone is good. I can wade right in with you.

    A couple minor points that I will point out which may have been corrected already:
    Chapt. 3: variables paragraph, last sentence, used the word "genericity". I suggest "genericness" instead.
    Chapt. 3: variables, types and coercion section, it says "assigning to a variable". I assume that should read "assigning type to a variable"?
    Chapt. 3. var, types and coercion section, your note "should I include a table of escapes here..?". Why not reference the table here if it is used elsewhere?

    I look forward to getting through the rest of the book. Writing about perl 5.10.1 is a good idea, not only because I could benefit from it but it appears overlooked.

      Moderately agree with point 1, only on the grounds that the "-icity" element may pose a stumbling block to some readers (IMHO_and_E, less common and therefore less familiar_and_understandable than "-ness") but am skeptical about recommendation 2:

      'Chapt. 3: variables, types and coercion section, it says "assigning to a variable". I assume that should read "assigning type to a variable"?'

      Methinks this has serious potential for confusing readers, who've been told that:

      "... the sigil of the variable in a declaration determines the type of the variable...."
      at "Variable Sigils"
      and that...
      "Perl 5 variables do not enforce types on their values."
      at "Variables, Types, and Coercion"

      Perhaps this "potential" arises only from the limits of my own understanding/appreciation, but I must obviously leave that judgement to others.

      Suggestion 3 makes excellent sense to me.

      Finally (for this post anyway), I find the sections on references, beginning with "Array References" particularly clear. Well done!

        Thanks for your comments. How would you like me to credit you in the book?

      Chapt. 3: variables paragraph, last sentence, used the word "genericity". I suggest "genericness" instead.

      "Genericness" is correct english; however "genericity" carries a particular meaning in programming jargon.

      Thanks for your comments. How would you like me to credit you in the book?

Re: Modern Perl: The Book: The Draft
by jethro (Monsignor) on Jul 08, 2010 at 15:58 UTC

    Chapter 7. Method Overriding and SUPER:

    You may override methods in the default Perl 5 OO system as well as in Moose. Unfortunately, core Perl 5 provides no mechanism for indicating your intent to override a parent's method. Worse yet, any function you predeclare, declare, or import into the child class may override a method in the parent class simply by existing and having the same name.

    This whole paragraph seems to say that Moose has none of these faults. But even in Moose a method may override simply by existing and having the same name since the override keyword is optional

      Thanks for all of your comments. How would you like me to credit you within the book?

Re: Modern Perl: The Book: The Draft
by jethro (Monsignor) on Jul 12, 2010 at 13:33 UTC

    Chapter 7. Immutability

    While this is simple to implement and easy to understand, it can lead to the unfortunate temptation to spread the behavioral responsibilities out individual classes throughout the system.

    Probably "out *to* individual classes" (?)

Re: Modern Perl: The Book: The Draft
by morgon (Priest) on Jul 25, 2010 at 09:31 UTC
    Just a tiny thing (or maybe just a matter of taste):

    In Chapter 10 "Easy File Slurping", you use this idiom for slurping:

    my $file = do { local $/ = <$fh> };

    For me the assignment to the localized $/ (that is done just so that the do-block returns the file-content) is confusing.

    Clearer (for me):

    my $file = do { local $/; <$fh> };

      I've seen both idioms, so both deserve an explanation. Thanks for the suggestion; how would you like me to credit you?

Re: Modern Perl: The Book: The Draft
by hexcoder (Curate) on Jul 05, 2010 at 20:44 UTC
    Hi again,

    in chapter 3, section 'Hash idioms', 2nd paragraph, 2nd sentence, typo at the beginning:
    It's
    instead of
    It

Re: Modern Perl: The Book: The Draft
by morgon (Priest) on Jul 26, 2010 at 02:07 UTC
    So far I have just poked here and there in your draft, but I think this will be a really great book.

    But here is something I would not like as a reader (as I said I have not yet read anything so sorry if I have overlooked stuff):

    In Chapter 3, "Unicode in Your Filehandles" you introduce the notion of a filehandle without any explanation at all. In the code the autodie-pragma falls from the sky (finally explained in Chapter 11 I think) and you use the <>-operator, again without any explanation.

    Who is the target audience? As a novice I certainly would be confused at this point.

    I would add a chapter (or a section) about strict, warnings and autodie before this as well as a chapter (or section) about file-handling (explaining filehandles, open and <>).

      Since this writing I've added a section on files and a link to that section from the Unicode discussion. It's impossible to avoid forward references in general, but hopefully the link to the subsequent chapter will help. Thanks for the feedback! (How would you like me to credit you?)

Re: Modern Perl: The Book: The Draft
by RedElk (Hermit) on Aug 12, 2010 at 17:08 UTC

    A few observations about chapters 8 and 9. Coming from someone in/around your target audience who's reading the HTML draft.

    I don't get a lot out of chapter 8. The title is enticing, but I was surprised by its brevity. Then chapter 9, also an enticing title, went straight to testing. Diverged from the title. I began to wonder: did I miss something? Who's the target audience again?

    Based on that experience, I got the idea that directories, paths, exceptions and warnings from chapter 9 might be something to incorporate into chapter 8. Then 8 would be fleshed out a bit, and could be more about "understanding how perl works", effective perl. Consideration of style and maintainability included. Simplicity, duplication, naming could then be substantiated with code examples (perchance with existing code examples). Continuing that thought, chapter 9 would still discuss testing, modules, cpan, pragmas, importing etc. It could be more about "how to manage perl code", idiomatic perl. Community wisdom/norms, testable code, and modularize, formerly discussed in 8, could then be substantiated with existing code examples.

    On the other hand, it's conceivable that both chapters 8 and 9 could get combined into one chapter. As it stands, chapter 8 seems to be missing something. It's like a prelude to 9. But 9 goes straight into the weeds without a second thought. Combining them appears to be a matter of strategically interjecting points from 8 into 9.

    Or, on the gripping hand, simply leave these chapters as they are. Although the title for chapter 9 leads me to expect one thing, as I stated, but immediately talks about testing. Including a transitional final sentence in the second paragraph of chapter 9 might be good (e.g. "Testing is one of those many techniques.").

    Again, observations.

      Good thoughts, thank you. I've rearranged chapters 8 and 9. Are they more to your liking now?

        Thanks for your consideration.

Re: Modern Perl: The Book: The Draft
by choroba (Cardinal) on Aug 30, 2010 at 11:47 UTC
    One more: at the find_a_rational example in Regex chapter, you have Unmatched ( in regex.
Re: Modern Perl: The Book: The Draft
by hbm (Hermit) on Sep 21, 2010 at 18:44 UTC

    Comments on a portion of Chapter 6. I apologize for any formatting glitches.

    No need for acknowledgement. When do you hope to go to print - or, until when are you seeking feedback?

    1. Which/That

    Paraphrasing a styleguide I have on hand:

    "That" introduces a phrase that is essential to the meaning of the word it modifies, and the phrase is not set off with commas. "Which" introduces a non-essential phrase, and is set off with commas.

    You seem to use "which" exclusively. For example, in the following paragraph, both instances should be "that".

    Perl's powerful ability to manipulate text comes in part from its inclusion of a computing concept known as regular expressions. A regular expression (often shortened to regex or regexp) is a pattern which describes characteristics of a string of text. A regular expression engine interprets a pattern and applies it to strings of text to identify those which match.

    2. Cross-Referencing

    I would modify your cross-referencing convention slightly, by including "see" or "see also" in parens and linking to the corresponding heading (e.g. <h3>) wherever possible. Consider this text:

    You may use a string in other contexts, such as boolean or numeric; its contents will determine the resulting value (Coercion).

    Which links to this text:

    Unlike other languages, where a variable can hold only a particular type of value…

    I would prefer "(see Coercion)", linked to the <h3>Coercion heading. (Or perhaps this markup is only for print, and a moot point.)

    3. Fixity

    I suggest reorganizing this paragraph:

    The fixity of an operator is its position relative to its operands. The mathematic operators tend to be infix operators, where they appear between their operands. Other operators are prefix, where they appear before their operands; these tend to be unary operators, such as the prefix increment operator ++$x or the mathematical and boolean negation operators (-$x and !$x, respectively). Postfix operators appear after their operands (such as postfix increment $x++). Circumfix operators surround their operands, such as the anonymous hash and anonymous array creation operators or quoting operators ({ ... } and [ ... ] or qq{ ... }, for example). Postcircumfix operators surround some operands but follow others, as in the case of array or hash indices ($hash{ ... } and $array[ ... ], for example).

    To this:

    Fixity is an operator’s position relative to its operands:
    • Infix operators appear between their operands. Most mathematical operators are infix, such as multiplication ($x * $y).
    • Prefix operators appear before their operands and postfix appear after. These tend to be unary, such as mathematical negation (-$x); boolean negation (!$x); and postfix increment ($x++).
    • Circumfix operators surround their operands. Examples include anonymous hash creation ({ ... }) and quoting operators (qq{ ... }).
    • Postcircumfix operators surround some operands and follow others, as in the case of array or hash indices ($hash{ ... } and $array[ ... ]).

    4. First-Class?

    The following sentence leaves me wondering what is a "first-class entity"?

    Regexes are first-class entities in modern Perl when created with the qr// operator.

    5. Greediness

    I’d like to reorganize your Greediness section, by moving non-greedy quantifiers up; and creating a new heading for Regex Anchors.

    Greediness

    The + and * quantifiers by themselves are greedy quantifiers; they match as many times as long a string as possible. This is particularly pernicious when using the tempting-but-troublesome "match matching “any amount of anything" with .*:

    # a poor regex my $hot_meal = qr/hot.*meal/; say 'Found a hot meal!' if 'I have a hot meal' =~ $hot_meal; say 'Found a hot meal!' if 'I did some one-shot, piecemeal work!' =~ $hot_meal;

    The problem is more obvious when you expect to match a short portion of a string. Greediness Greedy quantifiers always try to match as much of the input string as possible first, backing off only when it's obvious that the match will not succeed. Thus you may not be able to fit all of the results into the four boxes in 7 Down if you go looking for "loam" with: [But] you can turn a greedy quantifier into a non-greedy quantifier by appending the ? quantifier:

    my $minimal_greedy_match = qr/hot.*?meal/;

    In this case, the regular expression engine will prefer the shortest possible potential match, increasing the number of characters identified by the .*? token combination only if the current number fails to match. Because * matches zero or more times characters, the minimal potential match for this token combination is zero characters:

    say 'Found a hot meal' if 'ilikeahotmeal' =~ /$minimal_greedy_matc +h/;

    If this isn't what you want, use the + quantifier to match one or more items:

    my $minimal_greedy_at_least_one = qr/hot.+?meal/; unlike( 'ilikeahotmeal', $minimal_greedy_at_least_one ); like( 'i like a hot meal', $minimal_greedy_at_least_one );

    The ? quantifier modifier also applies to the ? (zero or one matches) quantifier as well as the range quantifiers. In every case, it causes the regex to match as few times characters as possible. In general, the greedy modifiers .+ and .* are tempting but dangerous tools. For simple programs which need little maintenance, they may be quick and easy to write, but non-greedy matching seems to match human expectations better. If you find yourself writing a lot of regular expression with greedy matches, test them thoroughly with a comprehensive and automated test suite with representative data to lessen the possibility of unpleasant surprises.

    Regex Anchors

    Regex anchors force a match at a specific position in a string. \A ensures that any match will start at the beginning of the string; and \Z ensures that any match will finish at the end of the string. For example, to find a four-letter word that starts with “l” and ends with “m”, you can use this expression:

    my $seven_down = qr/\Al${letters_only}{2}m\Z/;

    [ Actually, you might pick an example letter more prominent than "l"...]

    If you're not fortunate enough to have a Unix word dictionary file available [what if I am fortunate enough?], the word boundary metacharacter (\b) matches only at the boundary between a word character (\w) and a non-word character (\W):     my $seven_down = qr/\bl${letters_only}{2}m\b/;

    Like Perl, there's more than one way to write a regular expression. Consider choosing the most expressive and maintainable one.

    Metacharacters

    ...

      Thanks for your suggestions; I've taken most of them. (That versus which is a hot button most style guides can't explain without resorting to "But that's how we've always heard it.")

      I hope to have a camera-ready PDF for the printer by the end of the month.

Re: Modern Perl: The Book: The Draft
by choroba (Cardinal) on Aug 19, 2010 at 14:17 UTC
    Just two details from the chapters I have yet read:
    • In chapter 3, the condition say "Boolean false!" if !! $false_name is wrong, as far as I am able to check the logic.
    • In chapter 4, ^ is presented as "binary or" instead of "bitwise xor".

      Thanks! Please let me know how you'd like me to credit you in the acknowledgements section.