This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix typo in pod/perlhack.pod
[perl5.git] / pod / perlhack.pod
index 77df549..72c2fc0 100644 (file)
@@ -156,7 +156,7 @@ altogether without further notice.
 =item Is the implementation generic enough to be portable?
 
 The worst patches make use of a system-specific features.  It's highly
 =item Is the implementation generic enough to be portable?
 
 The worst patches make use of a system-specific features.  It's highly
-unlikely that nonportable additions to the Perl language will be
+unlikely that non-portable additions to the Perl language will be
 accepted.
 
 =item Is the implementation tested?
 accepted.
 
 =item Is the implementation tested?
@@ -207,23 +207,22 @@ interpreter.  "A core module" is one that ships with Perl.
 =head2 Keeping in sync
 
 The source code to the Perl interpreter, in its different versions, is
 =head2 Keeping in sync
 
 The source code to the Perl interpreter, in its different versions, is
-kept in a repository managed by a revision control system ( which is
-currently the Perforce program, see http://perforce.com/ ).  The
-pumpkings and a few others have access to the repository to check in
-changes.  Periodically the pumpking for the development version of Perl
-will release a new version, so the rest of the porters can see what's
-changed.  The current state of the main trunk of repository, and patches
-that describe the individual changes that have happened since the last
-public release are available at this location:
+kept in a repository managed by the git revision control system. The
+pumpkings and a few others have write access to the repository to check in
+changes.
 
 
-    http://public.activestate.com/pub/apc/
-    ftp://public.activestate.com/pub/apc/
+How to clone and use the git perl repository is described in L<perlrepository>.
 
 
-If you're looking for a particular change, or a change that affected
-a particular set of files, you may find the B<Perl Repository Browser>
-useful:
+You can also choose to use rsync to get a copy of the current source tree
+for the bleadperl branch and all maintenance branches :
 
 
-    http://public.activestate.com/cgi-bin/perlbrowse
+    $ rsync -avz rsync://perl5.git.perl.org/APC/perl-current .
+    $ rsync -avz rsync://perl5.git.perl.org/APC/perl-5.10.x .
+    $ rsync -avz rsync://perl5.git.perl.org/APC/perl-5.8.x .
+    $ rsync -avz rsync://perl5.git.perl.org/APC/perl-5.6.x .
+    $ rsync -avz rsync://perl5.git.perl.org/APC/perl-5.005xx .
+
+(Add the C<--delete> option to remove leftover files)
 
 You may also want to subscribe to the perl5-changes mailing list to
 receive a copy of each patch that gets submitted to the maintenance
 
 You may also want to subscribe to the perl5-changes mailing list to
 receive a copy of each patch that gets submitted to the maintenance
@@ -240,375 +239,38 @@ Needless to say, the source code in perl-current is usually in a perpetual
 state of evolution.  You should expect it to be very buggy.  Do B<not> use
 it for any purpose other than testing and development.
 
 state of evolution.  You should expect it to be very buggy.  Do B<not> use
 it for any purpose other than testing and development.
 
-Keeping in sync with the most recent branch can be done in several ways,
-but the most convenient and reliable way is using B<rsync>, available at
-ftp://rsync.samba.org/pub/rsync/ .  (You can also get the most recent
-branch by FTP.)
-
-If you choose to keep in sync using rsync, there are two approaches
-to doing so:
-
-=over 4
-
-=item rsync'ing the source tree
-
-Presuming you are in the directory where your perl source resides
-and you have rsync installed and available, you can "upgrade" to
-the bleadperl using:
-
- # rsync -avz rsync://public.activestate.com/perl-current/ .
-
-This takes care of updating every single item in the source tree to
-the latest applied patch level, creating files that are new (to your
-distribution) and setting date/time stamps of existing files to
-reflect the bleadperl status.
-
-Note that this will not delete any files that were in '.' before
-the rsync. Once you are sure that the rsync is running correctly,
-run it with the --delete and the --dry-run options like this:
-
- # rsync -avz --delete --dry-run rsync://public.activestate.com/perl-current/ .
-
-This will I<simulate> an rsync run that also deletes files not
-present in the bleadperl master copy. Observe the results from
-this run closely. If you are sure that the actual run would delete
-no files precious to you, you could remove the '--dry-run' option.
-
-You can than check what patch was the latest that was applied by
-looking in the file B<.patch>, which will show the number of the
-latest patch.
-
-If you have more than one machine to keep in sync, and not all of
-them have access to the WAN (so you are not able to rsync all the
-source trees to the real source), there are some ways to get around
-this problem.
-
-=over 4
-
-=item Using rsync over the LAN
-
-Set up a local rsync server which makes the rsynced source tree
-available to the LAN and sync the other machines against this
-directory.
-
-From http://rsync.samba.org/README.html :
-
-   "Rsync uses rsh or ssh for communication. It does not need to be
-    setuid and requires no special privileges for installation.  It
-    does not require an inetd entry or a daemon.  You must, however,
-    have a working rsh or ssh system.  Using ssh is recommended for
-    its security features."
-
-=item Using pushing over the NFS
-
-Having the other systems mounted over the NFS, you can take an
-active pushing approach by checking the just updated tree against
-the other not-yet synced trees. An example would be
-
-  #!/usr/bin/perl -w
-
-  use strict;
-  use File::Copy;
-
-  my %MF = map {
-      m/(\S+)/;
-      $1 => [ (stat $1)[2, 7, 9] ];    # mode, size, mtime
-      } `cat MANIFEST`;
-
-  my %remote = map { $_ => "/$_/pro/3gl/CPAN/perl-5.7.1" } qw(host1 host2);
-
-  foreach my $host (keys %remote) {
-      unless (-d $remote{$host}) {
-         print STDERR "Cannot Xsync for host $host\n";
-         next;
-         }
-      foreach my $file (keys %MF) {
-         my $rfile = "$remote{$host}/$file";
-         my ($mode, $size, $mtime) = (stat $rfile)[2, 7, 9];
-         defined $size or ($mode, $size, $mtime) = (0, 0, 0);
-         $size == $MF{$file}[1] && $mtime == $MF{$file}[2] and next;
-         printf "%4s %-34s %8d %9d  %8d %9d\n",
-             $host, $file, $MF{$file}[1], $MF{$file}[2], $size, $mtime;
-         unlink $rfile;
-         copy ($file, $rfile);
-         utime time, $MF{$file}[2], $rfile;
-         chmod $MF{$file}[0], $rfile;
-         }
-      }
-
-though this is not perfect. It could be improved with checking
-file checksums before updating. Not all NFS systems support
-reliable utime support (when used over the NFS).
-
-=back
-
-=item rsync'ing the patches
-
-The source tree is maintained by the pumpking who applies patches to
-the files in the tree. These patches are either created by the
-pumpking himself using C<diff -c> after updating the file manually or
-by applying patches sent in by posters on the perl5-porters list.
-These patches are also saved and rsync'able, so you can apply them
-yourself to the source files.
-
-Presuming you are in a directory where your patches reside, you can
-get them in sync with
-
- # rsync -avz rsync://public.activestate.com/perl-current-diffs/ .
-
-This makes sure the latest available patch is downloaded to your
-patch directory.
-
-It's then up to you to apply these patches, using something like
-
- # last="`cat ../perl-current/.patch`.gz"
- # rsync -avz rsync://public.activestate.com/perl-current-diffs/ .
- # find . -name '*.gz' -newer $last -exec gzcat {} \; >blead.patch
- # cd ../perl-current
- # patch -p1 -N <../perl-current-diffs/blead.patch
-
-or, since this is only a hint towards how it works, use CPAN-patchaperl
-from Andreas König to have better control over the patching process.
-
-=back
-
-=head2 Why rsync the source tree
-
-=over 4
-
-=item It's easier to rsync the source tree
-
-Since you don't have to apply the patches yourself, you are sure all
-files in the source tree are in the right state.
-
-=item It's more reliable
-
-While both the rsync-able source and patch areas are automatically
-updated every few minutes, keep in mind that applying patches may
-sometimes mean careful hand-holding, especially if your version of
-the C<patch> program does not understand how to deal with new files,
-files with 8-bit characters, or files without trailing newlines.
-
-=back
-
-=head2 Why rsync the patches
-
-=over 4
-
-=item It's easier to rsync the patches
-
-If you have more than one machine that you want to keep in track with
-bleadperl, it's easier to rsync the patches only once and then apply
-them to all the source trees on the different machines.
-
-In case you try to keep in pace on 5 different machines, for which
-only one of them has access to the WAN, rsync'ing all the source
-trees should than be done 5 times over the NFS. Having
-rsync'ed the patches only once, I can apply them to all the source
-trees automatically. Need you say more ;-)
-
-=item It's a good reference
-
-If you do not only like to have the most recent development branch,
-but also like to B<fix> bugs, or extend features, you want to dive
-into the sources. If you are a seasoned perl core diver, you don't
-need no manuals, tips, roadmaps, perlguts.pod or other aids to find
-your way around. But if you are a starter, the patches may help you
-in finding where you should start and how to change the bits that
-bug you.
-
-The file B<Changes> is updated on occasions the pumpking sees as his
-own little sync points. On those occasions, he releases a tar-ball of
-the current source tree (i.e. perl@7582.tar.gz), which will be an
-excellent point to start with when choosing to use the 'rsync the
-patches' scheme. Starting with perl@7582, which means a set of source
-files on which the latest applied patch is number 7582, you apply all
-succeeding patches available from then on (7583, 7584, ...).
-
-You can use the patches later as a kind of search archive.
-
-=over 4
-
-=item Finding a start point
-
-If you want to fix/change the behaviour of function/feature Foo, just
-scan the patches for patches that mention Foo either in the subject,
-the comments, or the body of the fix. A good chance the patch shows
-you the files that are affected by that patch which are very likely
-to be the starting point of your journey into the guts of perl.
-
-=item Finding how to fix a bug
-
-If you've found I<where> the function/feature Foo misbehaves, but you
-don't know how to fix it (but you do know the change you want to
-make), you can, again, peruse the patches for similar changes and
-look how others apply the fix.
-
-=item Finding the source of misbehaviour
-
-When you keep in sync with bleadperl, the pumpking would love to
-I<see> that the community efforts really work. So after each of his
-sync points, you are to 'make test' to check if everything is still
-in working order. If it is, you do 'make ok', which will send an OK
-report to perlbug@perl.org. (If you do not have access to a mailer
-from the system you just finished successfully 'make test', you can
-do 'make okfile', which creates the file C<perl.ok>, which you can
-than take to your favourite mailer and mail yourself).
-
-But of course, as always, things will not always lead to a success
-path, and one or more test do not pass the 'make test'. Before
-sending in a bug report (using 'make nok' or 'make nokfile'), check
-the mailing list if someone else has reported the bug already and if
-so, confirm it by replying to that message. If not, you might want to
-trace the source of that misbehaviour B<before> sending in the bug,
-which will help all the other porters in finding the solution.
-
-Here the saved patches come in very handy. You can check the list of
-patches to see which patch changed what file and what change caused
-the misbehaviour. If you note that in the bug report, it saves the
-one trying to solve it, looking for that point.
-
-=back
-
-If searching the patches is too bothersome, you might consider using
-perl's bugtron to find more information about discussions and
-ramblings on posted bugs.
-
-If you want to get the best of both worlds, rsync both the source
-tree for convenience, reliability and ease and rsync the patches
-for reference.
-
-=back
-
-=head2 Working with the source
-
-Because you cannot use the Perforce client, you cannot easily generate
-diffs against the repository, nor will merges occur when you update
-via rsync.  If you edit a file locally and then rsync against the
-latest source, changes made in the remote copy will I<overwrite> your
-local versions!
-
-The best way to deal with this is to maintain a tree of symlinks to
-the rsync'd source.  Then, when you want to edit a file, you remove
-the symlink, copy the real file into the other tree, and edit it.  You
-can then diff your edited file against the original to generate a
-patch, and you can safely update the original tree.
-
-Perl's F<Configure> script can generate this tree of symlinks for you.
-The following example assumes that you have used rsync to pull a copy
-of the Perl source into the F<perl-rsync> directory.  In the directory
-above that one, you can execute the following commands:
-
-  mkdir perl-dev
-  cd perl-dev
-  ../perl-rsync/Configure -Dmksymlinks -Dusedevel -D"optimize=-g"
-
-This will start the Perl configuration process.  After a few prompts,
-you should see something like this:
-
-  Symbolic links are supported.
-
-  Checking how to test for symbolic links...
-  Your builtin 'test -h' may be broken.
-  Trying external '/usr/bin/test -h'.
-  You can test for symbolic links with '/usr/bin/test -h'.
-
-  Creating the symbolic links...
-  (First creating the subdirectories...)
-  (Then creating the symlinks...)
-
-The specifics may vary based on your operating system, of course.
-After you see this, you can abort the F<Configure> script, and you
-will see that the directory you are in has a tree of symlinks to the
-F<perl-rsync> directories and files.
-
-If you plan to do a lot of work with the Perl source, here are some
-Bourne shell script functions that can make your life easier:
-
-    function edit {
-       if [ -L $1 ]; then
-           mv $1 $1.orig
-               cp $1.orig $1
-               vi $1
-       else
-           /bin/vi $1
-               fi
-    }
-
-    function unedit {
-       if [ -L $1.orig ]; then
-           rm $1
-               mv $1.orig $1
-               fi
-    }
-
-Replace "vi" with your favorite flavor of editor.
-
-Here is another function which will quickly generate a patch for the
-files which have been edited in your symlink tree:
-
-    mkpatchorig() {
-       local diffopts
-           for f in `find . -name '*.orig' | sed s,^\./,,`
-               do
-                   case `echo $f | sed 's,.orig$,,;s,.*\.,,'` in
-                       c)   diffopts=-p ;;
-               pod) diffopts='-F^=' ;;
-               *)   diffopts= ;;
-               esac
-                   diff -du $diffopts $f `echo $f | sed 's,.orig$,,'`
-                   done
-    }
-
-This function produces patches which include enough context to make
-your changes obvious.  This makes it easier for the Perl pumpking(s)
-to review them when you send them to the perl5-porters list, and that
-means they're more likely to get applied.
-
-This function assumed a GNU diff, and may require some tweaking for
-other diff variants.
-
 =head2 Perlbug administration
 
 =head2 Perlbug administration
 
-There is a single remote administrative interface for modifying bug status, 
-category, open issues etc. using the B<RT> I<bugtracker> system, maintained
-by I<Robert Spier>.  Become an administrator, and close any bugs you can get 
+There is a single remote administrative interface for modifying bug status,
+category, open issues etc. using the B<RT> bugtracker system, maintained
+by Robert Spier.  Become an administrator, and close any bugs you can get
 your sticky mitts on:
 
 your sticky mitts on:
 
-       http://rt.perl.org
-
-The bugtracker mechanism for B<perl5> bugs in particular is at:
-
-       http://bugs6.perl.org/perlbug
+       http://bugs.perl.org/
 
 To email the bug system administrators:
 
        "perlbug-admin" <perlbug-admin@perl.org>
 
 
 To email the bug system administrators:
 
        "perlbug-admin" <perlbug-admin@perl.org>
 
-
 =head2 Submitting patches
 
 Always submit patches to I<perl5-porters@perl.org>.  If you're
 patching a core module and there's an author listed, send the author a
 copy (see L<Patching a core module>).  This lets other porters review
 your patch, which catches a surprising number of errors in patches.
 =head2 Submitting patches
 
 Always submit patches to I<perl5-porters@perl.org>.  If you're
 patching a core module and there's an author listed, send the author a
 copy (see L<Patching a core module>).  This lets other porters review
 your patch, which catches a surprising number of errors in patches.
-Either use the diff program (available in source code form from
-ftp://ftp.gnu.org/pub/gnu/ , or use Johan Vromans' I<makepatch>
-(available from I<CPAN/authors/id/JV/>).  Unified diffs are preferred,
-but context diffs are accepted.  Do not send RCS-style diffs or diffs
-without context lines.  More information is given in the
-I<Porting/patching.pod> file in the Perl source distribution.  Please
-patch against the latest B<development> version. (e.g., even if you're
-fixing a bug in the 5.8 track, patch against the latest B<development>
-version rsynced from rsync://public.activestate.com/perl-current/ )
+Please patch against the latest B<development> version. (e.g., even if
+you're fixing a bug in the 5.8 track, patch against the C<blead> branch in
+the git repository.)
 
 If changes are accepted, they are applied to the development branch. Then
 
 If changes are accepted, they are applied to the development branch. Then
-the 5.8 pumpking decides which of those patches is to be backported to the
-maint branch.  Only patches that survive the heat of the development
-branch get applied to maintenance versions.
+the maintenance pumpking decides which of those patches is to be
+backported to the maint branch.  Only patches that survive the heat of the
+development branch get applied to maintenance versions.
 
 
-Your patch should also update the documentation and test suite.  See
-L<Writing a test>.
+Your patch should update the documentation and test suite.  See
+L<Writing a test>.  If you have added or removed files in the distribution,
+edit the MANIFEST file accordingly, sort the MANIFEST file using
+C<make manisort>, and include those changes as part of your patch.
 
 Patching documentation also follows the same order: if accepted, a patch
 is first applied to B<development>, and if relevant then it's backported
 
 Patching documentation also follows the same order: if accepted, a patch
 is first applied to B<development>, and if relevant then it's backported
@@ -620,7 +282,7 @@ To report a bug in Perl, use the program I<perlbug> which comes with
 Perl (if you can't get Perl to work, send mail to the address
 I<perlbug@perl.org> or I<perlbug@perl.com>).  Reporting bugs through
 I<perlbug> feeds into the automated bug-tracking system, access to
 Perl (if you can't get Perl to work, send mail to the address
 I<perlbug@perl.org> or I<perlbug@perl.com>).  Reporting bugs through
 I<perlbug> feeds into the automated bug-tracking system, access to
-which is provided through the web at http://bugs.perl.org/ .  It
+which is provided through the web at http://rt.perl.org/rt3/ .  It
 often pays to check the archives of the perl5-porters mailing list to
 see whether the bug you're reporting has been reported before, and if
 so whether it was considered a bug.  See above for the location of
 often pays to check the archives of the perl5-porters mailing list to
 see whether the bug you're reporting has been reported before, and if
 so whether it was considered a bug.  See above for the location of
@@ -628,9 +290,15 @@ the searchable archives.
 
 The CPAN testers ( http://testers.cpan.org/ ) are a group of
 volunteers who test CPAN modules on a variety of platforms.  Perl
 
 The CPAN testers ( http://testers.cpan.org/ ) are a group of
 volunteers who test CPAN modules on a variety of platforms.  Perl
-Smokers ( http://archives.develooper.com/daily-build@perl.org/ )
-automatically tests Perl source releases on platforms with various
-configurations.  Both efforts welcome volunteers.
+Smokers ( http://www.nntp.perl.org/group/perl.daily-build and
+http://www.nntp.perl.org/group/perl.daily-build.reports/ )
+automatically test Perl source releases on platforms with various
+configurations.  Both efforts welcome volunteers. In order to get
+involved in smoke testing of the perl itself visit
+L<http://search.cpan.org/dist/Test-Smoke>. In order to start smoke
+testing CPAN modules visit L<http://search.cpan.org/dist/CPAN-YACSmoke/>
+or L<http://search.cpan.org/dist/POE-Component-CPAN-YACSmoke/> or
+L<http://search.cpan.org/dist/CPAN-Reporter/>.
 
 It's a good idea to read and lurk for a while before chipping in.
 That way you'll get to see the dynamic of the conversations, learn the
 
 It's a good idea to read and lurk for a while before chipping in.
 That way you'll get to see the dynamic of the conversations, learn the
@@ -679,11 +347,9 @@ wanting to go about Perl development.
 
 =item The perl5-porters FAQ
 
 
 =item The perl5-porters FAQ
 
-This should be available from http://simon-cozens.org/writings/p5p-faq ;
-alternatively, you can get the FAQ emailed to you by sending mail to
-C<perl5-porters-faq@perl.org>. It contains hints on reading perl5-porters,
-information on how perl5-porters works and how Perl development in general
-works.
+This should be available from http://dev.perl.org/perl5/docs/p5p-faq.html .
+It contains hints on reading perl5-porters, information on how
+perl5-porters works and how Perl development in general works.
 
 =back
 
 
 =back
 
@@ -759,8 +425,11 @@ This is very high-level code, enough to fit on a single screen, and it
 resembles the code found in L<perlembed>; most of the real action takes
 place in F<perl.c>
 
 resembles the code found in L<perlembed>; most of the real action takes
 place in F<perl.c>
 
+F<perlmain.c> is generated by L<writemain> from F<miniperlmain.c> at
+make time, so you should make perl to follow this along.
+
 First, F<perlmain.c> allocates some memory and constructs a Perl
 First, F<perlmain.c> allocates some memory and constructs a Perl
-interpreter:
+interpreter, along these lines:
 
     1 PERL_SYS_INIT3(&argc,&argv,&env);
     2
 
     1 PERL_SYS_INIT3(&argc,&argv,&env);
     2
@@ -789,16 +458,19 @@ later: C<PerlMem_malloc> is either your system's C<malloc>, or Perl's
 own C<malloc> as defined in F<malloc.c> if you selected that option at
 configure time.
 
 own C<malloc> as defined in F<malloc.c> if you selected that option at
 configure time.
 
-Next, in line 7, we construct the interpreter; this sets up all the
-special variables that Perl needs, the stacks, and so on.
+Next, in line 7, we construct the interpreter using perl_construct, 
+also in F<perl.c>; this sets up all the special variables that Perl 
+needs, the stacks, and so on.
 
 Now we pass Perl the command line options, and tell it to go:
 
     exitstatus = perl_parse(my_perl, xs_init, argc, argv, (char **)NULL);
 
 Now we pass Perl the command line options, and tell it to go:
 
     exitstatus = perl_parse(my_perl, xs_init, argc, argv, (char **)NULL);
-    if (!exitstatus) {
-        exitstatus = perl_run(my_perl);
-    }
+    if (!exitstatus)
+        perl_run(my_perl);
+
+    exitstatus = perl_destruct(my_perl);
 
 
+    perl_free(my_perl);
 
 C<perl_parse> is actually a wrapper around C<S_parse_body>, as defined
 in F<perl.c>, which processes the command line options, sets up any
 
 C<perl_parse> is actually a wrapper around C<S_parse_body>, as defined
 in F<perl.c>, which processes the command line options, sets up any
@@ -887,7 +559,7 @@ retrieves the return op from it, and returns it.
 
 =item Exception handing
 
 
 =item Exception handing
 
-Perl's exception handing (i.e. C<die> etc) is built on top of the low-level
+Perl's exception handing (i.e. C<die> etc.) is built on top of the low-level
 C<setjmp()>/C<longjmp()> C-library functions. These basically provide a
 way to capture the current PC and SP registers and later restore them; i.e.
 a C<longjmp()> continues at the point in code where a previous C<setjmp()>
 C<setjmp()>/C<longjmp()> C-library functions. These basically provide a
 way to capture the current PC and SP registers and later restore them; i.e.
 a C<longjmp()> continues at the point in code where a previous C<setjmp()>
@@ -1509,8 +1181,8 @@ cpd (http://pmd.sourceforge.net/cpd.html) is part of the pmd project
 analysis of Java code, but later the cpd part of it was extended to
 parse also C and C++.
 
 analysis of Java code, but later the cpd part of it was extended to
 parse also C and C++.
 
-Download the pmd-X.y.jar from the SourceForge site, and then run
-it on source code thusly:
+Download the pmd-bin-X.Y.zip () from the SourceForge site, extract the
+pmd-X.Y.jar from it, and then run that on source code thusly:
 
   java -cp pmd-X.Y.jar net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files /some/where/src --language c > cpd.txt
 
 
   java -cp pmd-X.Y.jar net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files /some/where/src --language c > cpd.txt
 
@@ -1555,7 +1227,7 @@ C<-Wdeclaration-after-statement>
 =back
 
 The following flags would be nice to have but they would first need
 =back
 
 The following flags would be nice to have but they would first need
-their own Stygian stablemaster:
+their own Augean stablemaster:
 
 =over 4
 
 
 =over 4
 
@@ -1717,7 +1389,7 @@ but you have to say
 
 You may find it helpful to have a "macro dictionary", which you can
 produce by saying C<cpp -dM perl.c | sort>. Even then, F<cpp> won't
 
 You may find it helpful to have a "macro dictionary", which you can
 produce by saying C<cpp -dM perl.c | sort>. Even then, F<cpp> won't
-recursively apply those macros for you. 
+recursively apply those macros for you.
 
 =head2 gdb macro support
 
 
 =head2 gdb macro support
 
@@ -1733,7 +1405,7 @@ One way to get around this macro hell is to use the dumping functions in
 F<dump.c>; these work a little like an internal
 L<Devel::Peek|Devel::Peek>, but they also cover OPs and other structures
 that you can't get at from Perl. Let's take an example. We'll use the
 F<dump.c>; these work a little like an internal
 L<Devel::Peek|Devel::Peek>, but they also cover OPs and other structures
 that you can't get at from Perl. Let's take an example. We'll use the
-C<$a = $b + $c> we used before, but give it a bit of context: 
+C<$a = $b + $c> we used before, but give it a bit of context:
 C<$b = "6XXXX"; $c = 2.3;>. Where's a good place to stop and poke around?
 
 What about C<pp_add>, the function we examined earlier to implement the
 C<$b = "6XXXX"; $c = 2.3;>. Where's a good place to stop and poke around?
 
 What about C<pp_add>, the function we examined earlier to implement the
@@ -1768,7 +1440,7 @@ C<POPn> takes the SV from the top of the stack and obtains its NV either
 directly (if C<SvNOK> is set) or by calling the C<sv_2nv> function.
 C<TOPs> takes the next SV from the top of the stack - yes, C<POPn> uses
 C<TOPs> - but doesn't remove it. We then use C<SvNV> to get the NV from
 directly (if C<SvNOK> is set) or by calling the C<sv_2nv> function.
 C<TOPs> takes the next SV from the top of the stack - yes, C<POPn> uses
 C<TOPs> - but doesn't remove it. We then use C<SvNV> to get the NV from
-C<leftsv> in the same way as before - yes, C<POPn> uses C<SvNV>. 
+C<leftsv> in the same way as before - yes, C<POPn> uses C<SvNV>.
 
 Since we don't have an NV for C<$b>, we'll have to use C<sv_2nv> to
 convert it. If we step again, we'll find ourselves there:
 
 Since we don't have an NV for C<$b>, we'll have to use C<sv_2nv> to
 convert it. If we step again, we'll find ourselves there:
@@ -1821,7 +1493,7 @@ similar output to L<B::Debug|B::Debug>.
 All right, we've now had a look at how to navigate the Perl sources and
 some things you'll need to know when fiddling with them. Let's now get
 on and create a simple patch. Here's something Larry suggested: if a
 All right, we've now had a look at how to navigate the Perl sources and
 some things you'll need to know when fiddling with them. Let's now get
 on and create a simple patch. Here's something Larry suggested: if a
-C<U> is the first active format during a C<pack>, (for example, 
+C<U> is the first active format during a C<pack>, (for example,
 C<pack "U3C8", @stuff>) then the resulting string should be treated as
 UTF-8 encoded.
 
 C<pack "U3C8", @stuff>) then the resulting string should be treated as
 UTF-8 encoded.
 
@@ -1907,7 +1579,7 @@ else along the line.
 The regression tests for each operator live in F<t/op/>, and so we
 make a copy of F<t/op/pack.t> to F<t/op/pack.t~>. Now we can add our
 tests to the end. First, we'll test that the C<U> does indeed create
 The regression tests for each operator live in F<t/op/>, and so we
 make a copy of F<t/op/pack.t> to F<t/op/pack.t~>. Now we can add our
 tests to the end. First, we'll test that the C<U> does indeed create
-Unicode strings.  
+Unicode strings.
 
 t/op/pack.t has a sensible ok() function, but if it didn't we could
 use the one from t/test.pl.
 
 t/op/pack.t has a sensible ok() function, but if it didn't we could
 use the one from t/test.pl.
@@ -1923,8 +1595,8 @@ so instead of this:
 we can write the more sensible (see L<Test::More> for a full
 explanation of is() and other testing functions).
 
 we can write the more sensible (see L<Test::More> for a full
 explanation of is() and other testing functions).
 
- is( "1.20.300.4000", sprintf "%vd", pack("U*",1,20,300,4000), 
-                                       "U* produces unicode" );
+ is( "1.20.300.4000", sprintf "%vd", pack("U*",1,20,300,4000),
+                                       "U* produces Unicode" );
 
 Now we'll test that we got that space-at-the-beginning business right:
 
 
 Now we'll test that we got that space-at-the-beginning business right:
 
@@ -1935,7 +1607,7 @@ And finally we'll test that we don't make Unicode strings if C<U> is B<not>
 the first active format:
 
  isnt( v1.20.300.4000, sprintf "%vd", pack("C0U*",1,20,300,4000),
 the first active format:
 
  isnt( v1.20.300.4000, sprintf "%vd", pack("C0U*",1,20,300,4000),
-                                       "U* not first isn't unicode" );
+                                       "U* not first isn't Unicode" );
 
 Mustn't forget to change the number of tests which appears at the top,
 or else the automated tester will get confused.  This will either look
 
 Mustn't forget to change the number of tests which appears at the top,
 or else the automated tester will get confused.  This will either look
@@ -2110,6 +1782,11 @@ The old home for the module tests, you shouldn't put anything new in
 here.  There are still some bits and pieces hanging around in here
 that need to be moved.  Perhaps you could move them?  Thanks!
 
 here.  There are still some bits and pieces hanging around in here
 that need to be moved.  Perhaps you could move them?  Thanks!
 
+=item F<t/mro/>
+
+Tests for perl's method resolution order implementations
+(see L<mro>).
+
 =item F<t/op/>
 
 Tests for perl's built in functions that don't fit into any of the
 =item F<t/op/>
 
 Tests for perl's built in functions that don't fit into any of the
@@ -2149,7 +1826,7 @@ decision of which to use depends on what part of the test suite you're
 working on.  This is a measure to prevent a high-level failure (such
 as Config.pm breaking) from causing basic functionality tests to fail.
 
 working on.  This is a measure to prevent a high-level failure (such
 as Config.pm breaking) from causing basic functionality tests to fail.
 
-=over 4 
+=over 4
 
 =item t/base t/comp
 
 
 =item t/base t/comp
 
@@ -2174,9 +1851,9 @@ also use the full suite of core modules in the tests.
 =back
 
 When you say "make test" Perl uses the F<t/TEST> program to run the
 =back
 
 When you say "make test" Perl uses the F<t/TEST> program to run the
-test suite (except under Win32 where it uses F<t/harness> instead.)  
-All tests are run from the F<t/> directory, B<not> the directory 
-which contains the test.  This causes some problems with the tests 
+test suite (except under Win32 where it uses F<t/harness> instead.)
+All tests are run from the F<t/> directory, B<not> the directory
+which contains the test.  This causes some problems with the tests
 in F<lib/>, so here's some opportunity for some patching.
 
 You must be triply conscious of cross-platform concerns.  This usually
 in F<lib/>, so here's some opportunity for some patching.
 
 You must be triply conscious of cross-platform concerns.  This usually
@@ -2215,7 +1892,7 @@ are expected to succeed (until they're specifically fixed, of course).
 =item minitest
 
 Run F<miniperl> on F<t/base>, F<t/comp>, F<t/cmd>, F<t/run>, F<t/io>,
 =item minitest
 
 Run F<miniperl> on F<t/base>, F<t/comp>, F<t/cmd>, F<t/run>, F<t/io>,
-F<t/op>, and F<t/uni> tests.
+F<t/op>, F<t/uni> and F<t/mro> tests.
 
 =item test.valgrind check.valgrind utest.valgrind ucheck.valgrind
 
 
 =item test.valgrind check.valgrind utest.valgrind ucheck.valgrind
 
@@ -2301,15 +1978,15 @@ that they must appear if used together.
     harness -v -torture -re LIST OF PATTERNS TO MATCH
 
 If C<LIST OF FILES TO TEST> is omitted the file list is obtained from
     harness -v -torture -re LIST OF PATTERNS TO MATCH
 
 If C<LIST OF FILES TO TEST> is omitted the file list is obtained from
-the manifest. The file list may include shell wildcards which will be 
+the manifest. The file list may include shell wildcards which will be
 expanded out.
 
 =over 4
 
 =item -v
 
 expanded out.
 
 =over 4
 
 =item -v
 
-Run the tests under verbose mode so you can see what tests were run, 
-and debug outbut.
+Run the tests under verbose mode so you can see what tests were run,
+and debug output.
 
 =item -torture
 
 
 =item -torture
 
@@ -2323,7 +2000,7 @@ in that it allows the file list to be provided as well.
 
 =item -re LIST OF PATTERNS
 
 
 =item -re LIST OF PATTERNS
 
-Filter the file list so that all the test files run match 
+Filter the file list so that all the test files run match
 /(LIST|OF|PATTERNS)/. Note that with this form the patterns
 are joined by '|' and you cannot supply a list of files, instead
 the test files are obtained from the MANIFEST.
 /(LIST|OF|PATTERNS)/. Note that with this form the patterns
 are joined by '|' and you cannot supply a list of files, instead
 the test files are obtained from the MANIFEST.
@@ -2337,7 +2014,7 @@ You can run an individual test by a command similar to
 except that the harnesses set up some environment variables that may
 affect the execution of the test :
 
 except that the harnesses set up some environment variables that may
 affect the execution of the test :
 
-=over 4 
+=over 4
 
 =item PERL_CORE=1
 
 
 =item PERL_CORE=1
 
@@ -2361,6 +2038,29 @@ running 'make test_notty'.
 
 =back
 
 
 =back
 
+=head3 Other environment variables that may influence tests
+
+=over 4
+
+=item PERL_TEST_Net_Ping
+
+Setting this variable runs all the Net::Ping modules tests,
+otherwise some tests that interact with the outside world are skipped.
+See L<perl58delta>.
+
+=item PERL_TEST_NOVREXX
+
+Setting this variable skips the vrexx.t tests for OS2::REXX.
+
+=item PERL_TEST_NUMCONVERTS
+
+This sets a variable in op/numconvert.t.
+
+=back
+
+See also the documentation for the Test and Test::Harness modules,
+for more environment variables that affect testing.
+
 =head2 Common problems when patching Perl source code
 
 Perl source plays by ANSI C89 rules: no C99 (or C++) extensions.  In
 =head2 Common problems when patching Perl source code
 
 Perl source plays by ANSI C89 rules: no C99 (or C++) extensions.  In
@@ -2386,8 +2086,8 @@ and "Perl_-ly" APIs, for example:
 
 The first one explicitly passes in the context, which is needed for e.g.
 threaded builds.  The second one does that implicitly; do not get them
 
 The first one explicitly passes in the context, which is needed for e.g.
 threaded builds.  The second one does that implicitly; do not get them
-mixed.  If you are not passing in a aTHX_, you will need to do a dTHX as
-the first thing in the function.
+mixed.  If you are not passing in a aTHX_, you will need to do a dTHX
+(or a dVAR) as the first thing in the function.
 
 See L<perlguts/"How multiple interpreters and concurrency are supported">
 for further discussion about context.
 
 See L<perlguts/"How multiple interpreters and concurrency are supported">
 for further discussion about context.
@@ -2404,9 +2104,9 @@ therefore more ways for things to go wrong.  You should try it.
 Introducing (non-read-only) globals
 
 Do not introduce any modifiable globals, truly global or file static.
 Introducing (non-read-only) globals
 
 Do not introduce any modifiable globals, truly global or file static.
-They are bad form and break multithreading.  The right way is to
-introduce them as new interpreter variables, see F<intrpvar.h> (at the
-very end for binary compatibility).
+They are bad form and complicate multithreading and other forms of
+concurrency.  The right way is to introduce them as new interpreter
+variables, see F<intrpvar.h> (at the very end for binary compatibility).
 
 Introducing read-only (const) globals is okay, as long as you verify
 with e.g. C<nm libperl.a|egrep -v ' [TURtr] '> (if your C<nm> has
 
 Introducing read-only (const) globals is okay, as long as you verify
 with e.g. C<nm libperl.a|egrep -v ' [TURtr] '> (if your C<nm> has
@@ -2417,12 +2117,17 @@ If you want to have static strings, make them constant:
 
   static const char etc[] = "...";
 
 
   static const char etc[] = "...";
 
-If you want to have arrays of static strings, note carefully
+If you want to have arrays of constant strings, note carefully
 the right combination of C<const>s:
 
     static const char * const yippee[] =
        {"hi", "ho", "silver"};
 
 the right combination of C<const>s:
 
     static const char * const yippee[] =
        {"hi", "ho", "silver"};
 
+There is a way to completely hide any modifiable globals (they are all
+moved to heap), the compilation setting C<-DPERL_GLOBAL_STRUCT_PRIVATE>.
+It is not normally used, but can be used for testing, read more
+about it in L<perlguts/"Background and PERL_IMPLICIT_CONTEXT">.
+
 =item *
 
 Not exporting your new function
 =item *
 
 Not exporting your new function
@@ -2438,7 +2143,7 @@ Exporting your new function
 
 The new shiny result of either genuine new functionality or your
 arduous refactoring is now ready and correctly exported.  So what
 
 The new shiny result of either genuine new functionality or your
 arduous refactoring is now ready and correctly exported.  So what
-could possibly be wrong?
+could possibly go wrong?
 
 Maybe simply that your function did not need to be exported in the
 first place.  Perl has a long and not so glorious history of exporting
 
 Maybe simply that your function did not need to be exported in the
 first place.  Perl has a long and not so glorious history of exporting
@@ -2462,18 +2167,28 @@ reading.  Please test your changes with as many C compilers and
 platforms as possible -- we will, anyway, and it's nice to save
 oneself from public embarrassment.
 
 platforms as possible -- we will, anyway, and it's nice to save
 oneself from public embarrassment.
 
-If using gcc, starting from Perl 5.9.4 Perl core C files will be
-compiled with the C<-std=c89> option which will hopefully catch
-most of these unportabilities.
+If using gcc, you can add the C<-std=c89> option which will hopefully
+catch most of these unportabilities. (However it might also catch
+incompatibilities in your system's header files.)
 
 Use the Configure C<-Dgccansipedantic> flag to enable the gcc
 C<-ansi -pedantic> flags which enforce stricter ANSI rules.
 
 
 Use the Configure C<-Dgccansipedantic> flag to enable the gcc
 C<-ansi -pedantic> flags which enforce stricter ANSI rules.
 
+If using the C<gcc -Wall> note that not all the possible warnings
+(like C<-Wunitialized>) are given unless you also compile with C<-O>.
+
+Note that if using gcc, starting from Perl 5.9.5 the Perl core source
+code files (the ones at the top level of the source code distribution,
+but not e.g. the extensions under ext/) are automatically compiled
+with as many as possible of the C<-std=c89>, C<-ansi>, C<-pedantic>,
+and a selection of C<-W> flags (see cflags.SH).
+
 Also study L<perlport> carefully to avoid any bad assumptions
 Also study L<perlport> carefully to avoid any bad assumptions
-about the operating system, filesystem, and so forth.
+about the operating system, filesystems, and so forth.
 
 
-You may once in a while try a "make miniperl" to see whether we
+You may once in a while try a "make microperl" to see whether we
 can still compile Perl with just the bare minimum of interfaces.
 can still compile Perl with just the bare minimum of interfaces.
+(See README.micro.)
 
 Do not assume an operating system indicates a certain compiler.
 
 
 Do not assume an operating system indicates a certain compiler.
 
@@ -2527,7 +2242,7 @@ guaranteed to be B<int> or B<long>.  If you really explicitly need
 Assuming one can dereference any type of pointer for any type of data
 
   char *p = ...;
 Assuming one can dereference any type of pointer for any type of data
 
   char *p = ...;
-  long pony = *p;
+  long pony = *p;    /* BAD */
 
 Many platforms, quite rightly so, will give you a core dump instead
 of a pony if the p happens not be correctly aligned.
 
 Many platforms, quite rightly so, will give you a core dump instead
 of a pony if the p happens not be correctly aligned.
@@ -2536,17 +2251,126 @@ of a pony if the p happens not be correctly aligned.
 
 Lvalue casts
 
 
 Lvalue casts
 
-  (int)*p = ...;
+  (int)*p = ...;    /* BAD */
 
 Simply not portable.  Get your lvalue to be of the right type,
 
 Simply not portable.  Get your lvalue to be of the right type,
-or maybe use temporary variables.
+or maybe use temporary variables, or dirty tricks with unions.
+
+=item *
+
+Assume B<anything> about structs (especially the ones you
+don't control, like the ones coming from the system headers)
+
+=over 8
+
+=item *
+
+That a certain field exists in a struct
+
+=item *
+
+That no other fields exist besides the ones you know of
+
+=item *
+
+That a field is of certain signedness, sizeof, or type
+
+=item *
+
+That the fields are in a certain order
+
+=over 8
+
+=item *
+
+While C guarantees the ordering specified in the struct definition,
+between different platforms the definitions might differ
+
+=back
+
+=item *
+
+That the sizeof(struct) or the alignments are the same everywhere
+
+=over 8
+
+=item *
+
+There might be padding bytes between the fields to align the fields -
+the bytes can be anything
+
+=item *
+
+Structs are required to be aligned to the maximum alignment required
+by the fields - which for native types is for usually equivalent to
+sizeof() of the field
+
+=back
+
+=back
+
+=item *
+
+Assuming the character set is ASCIIish
+
+Perl can compile and run under EBCDIC platforms.  See L<perlebcdic>.
+This is transparent for the most part, but because the character sets
+differ, you shouldn't use numeric (decimal, octal, nor hex) constants
+to refer to characters.  You can safely say 'A', but not 0x41.
+You can safely say '\n', but not \012.
+If a character doesn't have a trivial input form, you can
+create a #define for it in both C<utfebcdic.h> and C<utf8.h>, so that
+it resolves to different values depending on the character set being used.
+(There are three different EBCDIC character sets defined in C<utfebcdic.h>,
+so it might be best to insert the #define three times in that file.)
+
+Also, the range 'A' - 'Z' in ASCII is an unbroken sequence of 26 upper case
+alphabetic characters.  That is not true in EBCDIC.  Nor for 'a' to 'z'.
+But '0' - '9' is an unbroken range in both systems.  Don't assume anything
+about other ranges.
+
+Many of the comments in the existing code ignore the possibility of EBCDIC,
+and may be wrong therefore, even if the code works.
+This is actually a tribute to the successful transparent insertion of being
+able to handle EBCDIC without having to change pre-existing code.
+
+UTF-8 and UTF-EBCDIC are two different encodings used to represent Unicode
+code points as sequences of bytes.  Macros 
+with the same names (but different definitions)
+in C<utf8.h> and C<utfebcdic.h>
+are used to allow the calling code to think that there is only one such
+encoding.
+This is almost always referred to as C<utf8>, but it means the EBCDIC version
+as well.  Again, comments in the code may well be wrong even if the code itself
+is right.
+For example, the concept of C<invariant characters> differs between ASCII and
+EBCDIC.
+On ASCII platforms, only characters that do not have the high-order
+bit set (i.e. whose ordinals are strict ASCII, 0 - 127)
+are invariant, and the documentation and comments in the code
+may assume that,
+often referring to something like, say, C<hibit>.
+The situation differs and is not so simple on EBCDIC machines, but as long as
+the code itself uses the C<NATIVE_IS_INVARIANT()> macro appropriately, it
+works, even if the comments are wrong.
+
+=item *
+
+Assuming the character set is just ASCII
+
+ASCII is a 7 bit encoding, but bytes have 8 bits in them.  The 128 extra
+characters have different meanings depending on the locale.  Absent a locale,
+currently these extra characters are generally considered to be unassigned,
+and this has presented some problems.
+This is scheduled to be changed in 5.12 so that these characters will
+be considered to be Latin-1 (ISO-8859-1).
 
 =item *
 
 Mixing #define and #ifdef
 
   #define BURGLE(x) ... \
 
 =item *
 
 Mixing #define and #ifdef
 
   #define BURGLE(x) ... \
-  #ifdef BURGLE_OLD_STYLE
+  #ifdef BURGLE_OLD_STYLE        /* BAD */
   ... do it the old way ... \
   #else
   ... do it the new way ... \
   ... do it the old way ... \
   #else
   ... do it the new way ... \
@@ -2557,17 +2381,17 @@ you need two separate BURGLE() #defines, one for each #ifdef branch.
 
 =item *
 
 
 =item *
 
-Adding stuff after #endif or #else
+Adding non-comment stuff after #endif or #else
 
   #ifdef SNOSH
   ...
 
   #ifdef SNOSH
   ...
-  #else !SNOSH
+  #else !SNOSH    /* BAD */
   ...
   ...
-  #endif SNOSH
+  #endif SNOSH    /* BAD */
 
 
-The #endif and #else cannot portably have anything after them.  If you
-want to document what is going (which is a good idea especially if the
-branches are long), use (C) comments:
+The #endif and #else cannot portably have anything non-comment after
+them.  If you want to document what is going (which is a good idea
+especially if the branches are long), use (C) comments:
 
   #ifdef SNOSH
   ...
 
   #ifdef SNOSH
   ...
@@ -2580,9 +2404,24 @@ The gcc option C<-Wendif-labels> warns about the bad variant
 
 =item *
 
 
 =item *
 
+Having a comma after the last element of an enum list
+
+  enum color {
+    CERULEAN,
+    CHARTREUSE,
+    CINNABAR,     /* BAD */
+  };
+
+is not portable.  Leave out the last comma.
+
+Also note that whether enums are implicitly morphable to ints
+varies between compilers, you might need to (int).
+
+=item *
+
 Using //-comments
 
 Using //-comments
 
-  // This function bamfoodles the zorklator.
+  // This function bamfoodles the zorklator.    /* BAD */
 
 That is C99 or C++.  Perl is C89.  Using the //-comments is silently
 allowed by many C compilers but cranking up the ANSI C89 strictness
 
 That is C99 or C++.  Perl is C89.  Using the //-comments is silently
 allowed by many C compilers but cranking up the ANSI C89 strictness
@@ -2595,7 +2434,7 @@ Mixing declarations and code
   void zorklator()
   {
     int n = 3;
   void zorklator()
   {
     int n = 3;
-    set_zorkmids(n);
+    set_zorkmids(n);    /* BAD */
     int q = 4;
 
 That is C99 or C++.  Some C compilers allow that, but you shouldn't.
     int q = 4;
 
 That is C99 or C++.  Some C compilers allow that, but you shouldn't.
@@ -2607,7 +2446,7 @@ The gcc option C<-Wdeclaration-after-statements> scans for such problems
 
 Introducing variables inside for()
 
 
 Introducing variables inside for()
 
-  for(int i = ...; ...; ...)
+  for(int i = ...; ...; ...) {    /* BAD */
 
 That is C99 or C++.  While it would indeed be awfully nice to have that
 also in C89, to limit the scope of the loop variable, alas, we cannot.
 
 That is C99 or C++.  While it would indeed be awfully nice to have that
 also in C89, to limit the scope of the loop variable, alas, we cannot.
@@ -2619,22 +2458,23 @@ Mixing signed char pointers with unsigned char pointers
   int foo(char *s) { ... }
   ...
   unsigned char *t = ...; /* Or U8* t = ... */
   int foo(char *s) { ... }
   ...
   unsigned char *t = ...; /* Or U8* t = ... */
-  foo(t);
+  foo(t);   /* BAD */
 
 While this is legal practice, it is certainly dubious, and downright
 fatal in at least one platform: for example VMS cc considers this a
 
 While this is legal practice, it is certainly dubious, and downright
 fatal in at least one platform: for example VMS cc considers this a
-fatal error.  One cause for people often making this mistake is that
-a "naked char" and therefore dereferencing a "naked char pointer" have
-an undefined signedness: it depends on the compiler and the platform
-whether the result is signed or unsigned.  For this very same reason
-using a 'char' as an array index is bad.
+fatal error.  One cause for people often making this mistake is that a
+"naked char" and therefore dereferencing a "naked char pointer" have
+an undefined signedness: it depends on the compiler and the flags of
+the compiler and the underlying platform whether the result is signed
+or unsigned.  For this very same reason using a 'char' as an array
+index is bad.
 
 =item *
 
 Macros that have string constants and their arguments as substrings of
 the string constants
 
 
 =item *
 
 Macros that have string constants and their arguments as substrings of
 the string constants
 
-  #define FOO(n) printf("number = %d\n", n)
+  #define FOO(n) printf("number = %d\n", n)    /* BAD */
   FOO(10);
 
 Pre-ANSI semantics for that was equivalent to
   FOO(10);
 
 Pre-ANSI semantics for that was equivalent to
@@ -2651,7 +2491,7 @@ rest of the AIX compiler is very happily C89.
 Using printf formats for non-basic C types
 
    IV i = ...;
 Using printf formats for non-basic C types
 
    IV i = ...;
-   printf("i = %d\n", i);
+   printf("i = %d\n", i);    /* BAD */
 
 While this might by accident work in some platform (where IV happens
 to be an C<int>), in general it cannot.  IV might be something larger.
 
 While this might by accident work in some platform (where IV happens
 to be an C<int>), in general it cannot.  IV might be something larger.
@@ -2659,7 +2499,7 @@ Even worse the situation is with more specific types (defined by Perl's
 configuration step in F<config.h>):
 
    Uid_t who = ...;
 configuration step in F<config.h>):
 
    Uid_t who = ...;
-   printf("who = %d\n", who);
+   printf("who = %d\n", who);    /* BAD */
 
 The problem here is that Uid_t might be not only not C<int>-wide
 but it might also be unsigned, in which case large uids would be
 
 The problem here is that Uid_t might be not only not C<int>-wide
 but it might also be unsigned, in which case large uids would be
@@ -2707,15 +2547,17 @@ Perl_va_copy() if the NEED_VA_COPY is defined.
 
 =item *
 
 
 =item *
 
-Using gcc brace groups
+Using gcc statement expressions
 
 
-   val = ({...;...;...});
+   val = ({...;...;...});    /* BAD */
 
 
-While a nice extension, it's not portable.
+While a nice extension, it's not portable.  The Perl code does
+admittedly use them if available to gain some extra speed
+(essentially as a funky form of inlining), but you shouldn't.
 
 =item *
 
 
 =item *
 
-Binding together several statements
+Binding together several statements in a macro
 
 Use the macros STMT_START and STMT_END.
 
 
 Use the macros STMT_START and STMT_END.
 
@@ -2727,7 +2569,7 @@ Use the macros STMT_START and STMT_END.
 
 Testing for operating systems or versions when should be testing for features
 
 
 Testing for operating systems or versions when should be testing for features
 
-  #ifdef __FOONIX__
+  #ifdef __FOONIX__    /* BAD */
   foo = quux();
   #endif
 
   foo = quux();
   #endif
 
@@ -2741,8 +2583,8 @@ not perfect, because the below is a compile-time check):
   foo = quux();
   #endif
 
   foo = quux();
   #endif
 
-How does the HAS_QUUX become defined where it needs to be? Well, if
-Foonix happens to be UNIXy enought to be able to run the Configure
+How does the HAS_QUUX become defined where it needs to be?  Well, if
+Foonix happens to be UNIXy enough to be able to run the Configure
 script, and Configure has been taught about detecting and testing
 quux(), the HAS_QUUX will be correctly defined.  In other platforms,
 the corresponding configuration step will hopefully do the same.
 script, and Configure has been taught about detecting and testing
 quux(), the HAS_QUUX will be correctly defined.  In other platforms,
 the corresponding configuration step will hopefully do the same.
@@ -2765,6 +2607,22 @@ But in any case, try to keep the features and operating systems separate.
 
 =back
 
 
 =back
 
+=head2 Problematic System Interfaces
+
+=over 4
+
+=item *
+
+malloc(0), realloc(0), calloc(0, 0) are non-portable.  To be portable
+allocate at least one byte.  (In general you should rarely need to
+work at this low level, but instead use the various malloc wrappers.)
+
+=item *
+
+snprintf() - the return type is unportable.  Use my_snprintf() instead.
+
+=back
+
 =head2 Security problems
 
 Last but not least, here are various tips for safer coding.
 =head2 Security problems
 
 Last but not least, here are various tips for safer coding.
@@ -2836,6 +2694,10 @@ errors within eval or require, seeing C<S_doeval> in the call stack
 is a good sign of these.  Fixing these leaks is non-trivial,
 unfortunately, but they must be fixed eventually.
 
 is a good sign of these.  Fixing these leaks is non-trivial,
 unfortunately, but they must be fixed eventually.
 
+B<NOTE 4>: L<DynaLoader> will not clean up after itself completely
+unless Perl is built with the Configure option
+C<-Accflags=-DDL_UNLOAD_ALL_AT_EXIT>.
+
 =head2 Rational Software's Purify
 
 Purify is a commercial tool that is helpful in identifying
 =head2 Rational Software's Purify
 
 Purify is a commercial tool that is helpful in identifying
@@ -2886,7 +2748,7 @@ number of bogus leak reports from Purify.
 Once you've compiled a perl suitable for Purify'ing, then you
 can just:
 
 Once you've compiled a perl suitable for Purify'ing, then you
 can just:
 
-    make pureperl   
+    make pureperl
 
 which creates a binary named 'pureperl' that has been Purify'ed.
 This binary is used in place of the standard 'perl' binary
 
 which creates a binary named 'pureperl' that has been Purify'ed.
 This binary is used in place of the standard 'perl' binary
@@ -2898,7 +2760,7 @@ perl as:
 
     make pureperl
     cd t
 
     make pureperl
     cd t
-    ../pureperl -I../lib harness 
+    ../pureperl -I../lib harness
 
 which would run Perl on test.pl and report any memory problems.
 
 
 which would run Perl on test.pl and report any memory problems.
 
@@ -2937,7 +2799,7 @@ should change to get the most use out of Purify:
 You should add -DPURIFY to the DEFINES line so the DEFINES
 line looks something like:
 
 You should add -DPURIFY to the DEFINES line so the DEFINES
 line looks something like:
 
-    DEFINES = -DWIN32 -D_CONSOLE -DNO_STRICT $(CRYPT_FLAG) -DPURIFY=1 
+    DEFINES = -DWIN32 -D_CONSOLE -DNO_STRICT $(CRYPT_FLAG) -DPURIFY=1
 
 to disable Perl's arena memory allocation functions, as
 well as to force use of memory allocation functions derived
 
 to disable Perl's arena memory allocation functions, as
 well as to force use of memory allocation functions derived
@@ -2969,7 +2831,7 @@ standard Perl testset you would create and run Purify as:
     cd win32
     make
     cd ../t
     cd win32
     make
     cd ../t
-    purify ../perl -I../lib harness 
+    purify ../perl -I../lib harness
 
 which would instrument Perl in memory, run Perl on test.pl,
 then finally report any memory problems.
 
 which would instrument Perl in memory, run Perl on test.pl,
 then finally report any memory problems.
@@ -2977,10 +2839,14 @@ then finally report any memory problems.
 =head2 valgrind
 
 The excellent valgrind tool can be used to find out both memory leaks
 =head2 valgrind
 
 The excellent valgrind tool can be used to find out both memory leaks
-and illegal memory accesses.  As of August 2003 it unfortunately works
-only on x86 (ELF) Linux.  The special "test.valgrind" target can be used
-to run the tests under valgrind.  Found errors and memory leaks are
-logged in files named F<test.valgrind>.
+and illegal memory accesses.  As of version 3.3.0, Valgrind only
+supports Linux on x86, x86-64 and PowerPC.  The special "test.valgrind" 
+target can be used to run the tests under valgrind.  Found errors 
+and memory leaks are logged in files named F<testfile.valgrind>.
+
+Valgrind also provides a cachegrind tool, invoked on perl as:
+
+    VG_OPTS=--tool=cachegrind make test.valgrind
 
 As system libraries (most notably glibc) are also triggering errors,
 valgrind allows to suppress such errors using suppression files. The
 
 As system libraries (most notably glibc) are also triggering errors,
 valgrind allows to suppress such errors using suppression files. The
@@ -3051,6 +2917,27 @@ memory usage, so it shouldn't be used in production environments. It also
 converts C<new_SV()> from a macro into a real function, so you can use
 your favourite debugger to discover where those pesky SVs were allocated.
 
 converts C<new_SV()> from a macro into a real function, so you can use
 your favourite debugger to discover where those pesky SVs were allocated.
 
+If you see that you're leaking memory at runtime, but neither valgrind
+nor C<-DDEBUG_LEAKING_SCALARS> will find anything, you're probably
+leaking SVs that are still reachable and will be properly cleaned up
+during destruction of the interpreter. In such cases, using the C<-Dm>
+switch can point you to the source of the leak. If the executable was
+built with C<-DDEBUG_LEAKING_SCALARS>, C<-Dm> will output SV allocations
+in addition to memory allocations. Each SV allocation has a distinct
+serial number that will be written on creation and destruction of the SV. 
+So if you're executing the leaking code in a loop, you need to look for
+SVs that are created, but never destroyed between each cycle. If such an
+SV is found, set a conditional breakpoint within C<new_SV()> and make it
+break only when C<PL_sv_serial> is equal to the serial number of the
+leaking SV. Then you will catch the interpreter in exactly the state
+where the leaking SV is allocated, which is sufficient in many cases to
+find the source of the leak.
+
+As C<-Dm> is using the PerlIO layer for output, it will by itself
+allocate quite a bunch of SVs, which are hidden to avoid recursion.
+You can bypass the PerlIO layer if you use the SV logging provided
+by C<-DPERL_MEM_LOG> instead.
+
 =head2 PERL_MEM_LOG
 
 If compiled with C<-DPERL_MEM_LOG>, all Newx() and Renew() allocations
 =head2 PERL_MEM_LOG
 
 If compiled with C<-DPERL_MEM_LOG>, all Newx() and Renew() allocations
@@ -3064,6 +2951,17 @@ This logging is somewhat similar to C<-Dm> but independent of C<-DDEBUGGING>,
 and at a higher level (the C<-Dm> is directly at the point of C<malloc()>,
 while the C<PERL_MEM_LOG> is at the level of C<New()>).
 
 and at a higher level (the C<-Dm> is directly at the point of C<malloc()>,
 while the C<PERL_MEM_LOG> is at the level of C<New()>).
 
+In addition to memory allocations, SV allocations will be logged, just as
+with C<-Dm>. However, since the logging doesn't use PerlIO, all SV allocations
+are logged and no extra SV allocations are introduced by enabling the logging.
+If compiled with C<-DDEBUG_LEAKING_SCALARS>, the serial number for each SV
+allocation is also logged.
+
+You can control the logging from your environment if you compile with
+C<-DPERL_MEM_LOG_ENV>. Then you need to explicitly set C<PERL_MEM_LOG> and/or
+C<PERL_SV_LOG> to a non-zero value to enable logging of memory and/or SV
+allocations.
+
 =head2 Profiling
 
 Depending on your platform there are various of profiling Perl.
 =head2 Profiling
 
 Depending on your platform there are various of profiling Perl.
@@ -3141,6 +3039,13 @@ Display routines that have zero usage.
 For more detailed explanation of the available commands and output
 formats, see your own local documentation of gprof.
 
 For more detailed explanation of the available commands and output
 formats, see your own local documentation of gprof.
 
+quick hint:
+
+    $ sh Configure -des -Dusedevel -Doptimize='-g' -Accflags='-pg' -Aldflags='-pg' && make
+    $ ./perl someprog # creates gmon.out in current directory
+    $ gprof perl > out
+    $ view out
+
 =head2 GCC gcov Profiling
 
 Starting from GCC 3.0 I<basic block profiling> is officially available
 =head2 GCC gcov Profiling
 
 Starting from GCC 3.0 I<basic block profiling> is officially available
@@ -3177,6 +3082,15 @@ and its section titled "8. gcov: a Test Coverage Program"
 
     http://gcc.gnu.org/onlinedocs/gcc-3.0/gcc_8.html#SEC132
 
 
     http://gcc.gnu.org/onlinedocs/gcc-3.0/gcc_8.html#SEC132
 
+quick hint:
+
+    $ sh Configure -des  -Doptimize='-g' -Accflags='-fprofile-arcs -ftest-coverage' \
+        -Aldflags='-fprofile-arcs -ftest-coverage' && make perl.gcov
+    $ rm -f regexec.c.gcov regexec.gcda
+    $ ./perl.gcov
+    $ gcov regexec.c
+    $ view regexec.c.gcov
+
 =head2 Pixie Profiling
 
 Pixie is a profiling tool available on IRIX and Tru64 (aka Digital
 =head2 Pixie Profiling
 
 Pixie is a profiling tool available on IRIX and Tru64 (aka Digital
@@ -3296,8 +3210,47 @@ If you see in a debugger a memory area mysteriously full of 0xABABABAB
 or 0xEFEFEFEF, you may be seeing the effect of the Poison() macros,
 see L<perlclib>.
 
 or 0xEFEFEFEF, you may be seeing the effect of the Poison() macros,
 see L<perlclib>.
 
+=item *
+
+Under ithreads the optree is read only. If you want to enforce this, to check
+for write accesses from buggy code, compile with C<-DPL_OP_SLAB_ALLOC> to
+enable the OP slab allocator and C<-DPERL_DEBUG_READONLY_OPS> to enable code
+that allocates op memory via C<mmap>, and sets it read-only at run time.
+Any write access to an op results in a C<SIGBUS> and abort.
+
+This code is intended for development only, and may not be portable even to
+all Unix variants. Also, it is an 80% solution, in that it isn't able to make
+all ops read only. Specifically it
+
+=over
+
+=item 1
+
+Only sets read-only on all slabs of ops at C<CHECK> time, hence ops allocated
+later via C<require> or C<eval> will be re-write
+
+=item 2
+
+Turns an entire slab of ops read-write if the refcount of any op in the slab
+needs to be decreased.
+
+=item 3
+
+Turns an entire slab of ops read-write if any op from the slab is freed.
+
+=back
+
+It's not possible to turn the slabs to read-only after an action requiring
+read-write access, as either can happen during op tree building time, so
+there may still be legitimate write access.
+
+However, as an 80% solution it is still effective, as currently it catches
+a write access during the generation of F<Config.pm>, which means that we
+can't yet build F<perl> with this enabled.
+
 =back
 
 =back
 
+
 =head1 CONCLUSION
 
 We've had a brief look around the Perl source, how to maintain quality
 =head1 CONCLUSION
 
 We've had a brief look around the Perl source, how to maintain quality
@@ -3311,7 +3264,7 @@ test Perl.
 
 I'd now suggest you read over those references again, and then, as soon
 as possible, get your hands dirty. The best way to learn is by doing,
 
 I'd now suggest you read over those references again, and then, as soon
 as possible, get your hands dirty. The best way to learn is by doing,
-so: 
+so:
 
 =over 3
 
 
 =over 3
 
@@ -3352,7 +3305,66 @@ activity as well, and probably sooner than you'd think.
 If you can do these things, you've started on the long road to Perl porting.
 Thanks for wanting to help make Perl better - and happy hacking!
 
 If you can do these things, you've started on the long road to Perl porting.
 Thanks for wanting to help make Perl better - and happy hacking!
 
+=head2 Metaphoric Quotations
+
+If you recognized the quote about the Road above, you're in luck.
+
+Most software projects begin each file with a literal description of each
+file's purpose.  Perl instead begins each with a literary allusion to that
+file's purpose.
+
+Like chapters in many books, all top-level Perl source files (along with a
+few others here and there) begin with an epigramic inscription that alludes,
+indirectly and metaphorically, to the material you're about to read.
+
+Quotations are taken from writings of J.R.R Tolkien pertaining to his
+Legendarium, almost always from I<The Lord of the Rings>.  Chapters and
+page numbers are given using the following editions:
+
+=over 4
+
+=item * 
+
+I<The Hobbit>, by J.R.R. Tolkien.  The hardcover, 70th-anniversary
+edition of 2007 was used, published in the UK by Harper Collins Publishers
+and in the US by the Houghton Mifflin Company.
+
+=item *
+
+I<The Lord of the Rings>, by J.R.R. Tolkien.  The hardcover,
+50th-anniversary edition of 2004 was used, published in the UK by Harper
+Collins Publishers and in the US by the Houghton Mifflin Company.
+
+=item *
+
+I<The Lays of Beleriand>, by J.R.R. Tolkien and published posthumously by his
+son and literary executor, C.J.R. Tolkien, being the 3rd of the 12 volumes
+in Christopher's mammoth I<History of Middle Earth>.  Page numbers derive
+from the hardcover edition, first published in 1983 by George Allen &
+Unwin; no page numbers changed for the special 3-volume omnibus edition of
+2002 or the various trade-paper editions, all again now by Harper Collins
+or Houghton Mifflin.
+
+=back
+
+Other JRRT books fair game for quotes would thus include I<The Adventures of
+Tom Bombadil>, I<The Silmarillion>, I<Unfinished Tales>, and I<The Tale of
+the Children of Hurin>, all but the first posthumously assembled by CJRT.
+But I<The Lord of the Rings> itself is perfectly fine and probably best to
+quote from, provided you can find a suitable quote there.
+
+So if you were to supply a new, complete, top-level source file to add to
+Perl, you should conform to this peculiar practice by yourself selecting an
+appropriate quotation from Tolkien, retaining the original spelling and
+punctuation and using the same format the rest of the quotes are in.
+Indirect and oblique is just fine; remember, it's a metaphor, so being meta
+is, after all, what it's for.
+
 =head1 AUTHOR
 
 This document was written by Nathan Torkington, and is maintained by
 the perl5-porters mailing list.
 =head1 AUTHOR
 
 This document was written by Nathan Torkington, and is maintained by
 the perl5-porters mailing list.
+
+=head1 SEE ALSO
+
+L<perlrepository>