Another day, another argument over how to document TIMTOWTDI.
Some people prefer to write tutorials for novices that start from "the
simplest thing imaginable" and then gradually introduce newer features. I took
a different approach in the Modern Perl book.
In the context of the open
tutorial discussion, the book very
deliberately recommends against the use of bareword filehandles (except in
named exceptions of STDIN
, STDOUT
,
STDERR
, and DATA
) and always recommends
three-argument open
over the one- and two-argument
alternatives.
This is a matter of philosophy on which reasonable people differ.
For the book, I wanted every example to run without error under
strict
and warnings
. Most examples use Perl 5.10
features such as say
. That's part of the reason I wrote the Modern::Perl
metapragma—I wanted to explain once a single line of magic that helps
novices get as much assistance as perl
itself can provide to write
good code.
That does mean that any discussion of opening files depends on the reader already knowing how to declare a variable. That also means that the discussion of declaring variables has to take place at or before the discussion of assigning to variables.
Of course, someone who's never used Perl 5 before will, from the start, have strictures available to help catch undeclared variables and typos in variable names. The first lines of code this novices writes will be strict safe.
(I spent ten minutes the other day wondering why Devel::Cover couldn't
see the documentation for two methods generated during BEGIN
time
as closures, and was almost ready to file a bug until I noticed that my
documentation had typos in the method names. Typos happen.)
This strategy also means that the open
code novices write won't
use package global variables, so they'll avoid spooky action at a distance if
they keep their lexical scopes sane. Even better, they don't have to understand
how local
works and what dynamic scope is in order to write safe
code.
In other words, Perl 5 novices who read Modern Perl: learn from the first page to write code which:
- Allows
perl
to give better warnings and error messages about dubious constructs - Limits the possibilities of using global variables
- Avoids subtle security problems from magical filemode detection
- Scales up to larger programs, mostly thanks to the first three items in this list.
In addition, these readers do not have to unlearn habits the book
has previously helped them adopt. Plenty of people use Perl 5 to write little
programs of a couple of dozen lines where the risk of a typo is minimal or the
spooky action of an unexpected global change is almost irrelevant, but there
are plenty of other people using Perl 5 to build bigger programs or programs
which will become big. Why deny them the perl
's full abilities to
help them write correct code?
All it takes is the philosophy of "teach people to write code that can scale to larger programs" and the willingness to rearrange the order of concepts presented so that variable declarations come before opening files. (It's easy to write real programs which only ever print to standard output until readers understand variable declarations.)
It's not that package globals or barewords are intrinsically and always bad,
and so you should never use them. (Even if I wanted that to be true, it
wouldn't be true.) Instead, the book always takes the approach of showing a
better (easier to verify, safer, more secure, easier to understand, fewer
loopholes, simpler) approach over the alternatives. That's why it teaches OO
with Moose, why it recommends Try::Tiny over
eval
, and why autodie gets prominent
mention.
If experienced Perl 5 programmers use all of these great tools to take care of unsafe, complex, messy, fragile details, why not help novices use them as soon as possible? Certainly, some of them only need to know a few details to write a couple of dozen lines of code, and that's perfectly acceptable—but plenty of others could be great programmers solving real problems with more ease if we smoothed out the way for them a little bit more.
I used to teach bare word file handles and 2 parameter open() for a long time. Back then I used to introduce strict and "my" on the 3rd day of my class.
It hasn't been like that for at least 6 years now. More like 8.
Now I start with use strict and warnings from the very first script and teach open() with 3 parameters and with lexical variable.
I do that as I think it is better to teach them good practices from the beginning especially if they don't have a lot of prerequisites.
On the last page of the "File" chapter I do explain about 2 parameter open and barewords. I do that mostly because people will encounter that kind of code and they should understand what they see and what are the potential issues.
I just wish open could be written like this:
my $fh = open '<', 'filename';
The "the simplest thing imaginable" is subjective. In a tutorial it is what ever the tutor says it is. Heck, what do the students know? And if they do what are they doing in this class? It is incumbent on the tutor to teach the best current practice as the way students are expected to work and discuss alternate and archaic forms as what they are.
Documentation is the same. We don't want to optimize our documentation updates for laziness. We want to optimize them for future code robustness.
It would be fine to have a side bar or other markup distinction to discuss archaic techniques that are still valid, but the up front cut-n-paste fodder should all emphasize best available practice.