Wednesday, July 14, 2010

Adventures in Ignorance: Autovivification for fun and profit

Perl 5 autovivifies hashes and arrays when an undef is used as a hashref or arrayref. Normally you see this when using multidimensional data structures like this:

my %hash;
$hash{foo}{bar} = 1;

The value in $hash{foo} is undefined, so Perl 5 turns it into a hashref so it can lookup the key "bar" in it. This is somewhat dangerous because you can create keys without meaning to:

if ($hash{bar}{baz} == 1) {
say "found "bar/baz";

Here the key "bar" will be added to the %hash if it doesn't already exist. To prevent this we must check every level but the last with exists:

if (exists $hash{bar} and $hash{bar}{baz} == 1) {
say "found "bar/baz";

When I think of autovivification, that is all I normally think of, but today I realized you can use it for more than that. I have a couple of hashrefs I want to set the initial size of with keys. I was saying

my $hashref     = {};
keys(%$hashref) = 1024;

As I wrote that I wondered if autovivification would turn an undef in $hashref into a hashref for me, and sure enough it will:


use 5.012;
use warnings;

use Scalar::Util qw/reftype/;

my $hashref; #not really a hashref yet
keys(%$hashref) = 1024; #but now it is

say reftype $hashref;

Friday, July 9, 2010

Adventures in Ignorance: when both Perl and the Developer are too smart for their own good.

So, split returns the number of fields it would have split into when called in scalar context, but it also throws a warning in Perl 5.10: "Use of implicit split to @_ is deprecated". In an attempt to placate the warning I wrote

my $count =()= split $delim, $string;

but was surprised to find that every string returned 1. This is due to a nice little optimization that split does for you:

When assigning to a list, if LIMIT is omitted, or zero, Perl
supplies a LIMIT one larger than the number of variables in the
list, to avoid unnecessary work. For the list above LIMIT
would have been 4 by default. In time critical applications it
behooves you not to split into more fields than you really
To get around this you must specify your own limit of -1:

my $count =()= split $delim, $string, -1;

Of course, -1 doesn't have the same behavior as no limit or a limit of 0 (a limit of -1 preserves empty trailing fields), so this is not necessarily what you want. This leaves us with the last line of defense, turning off warnings (and it isn't pretty):

my $count = do {
no warnings "deprecated";
split $delim, $second;

Thursday, July 1, 2010

Announcing the Perl 5 Documentation Team

I am excited to announce the formation of the Perl 5 Documentation Team. Our goal is to have the best, most current, and easiest to use and understand documentation of any programming language. Why settle for small goals?

Since the success of this team will depend on having both expert and novice points of view, membership is open to all, regardless of experience level with Perl. This is an excellent opportunity for people who would like to make a contribution back to the Perl community to do so in a way that doesn't require expert programming abilities.

If you are interested in being part of the team, please subscribe to the Perl Documentation mailing list, as future discussion will occur there (look for the thread named "I want to sign up"). If you know of other people who may be interested in being part of this effort, please pass this message on to them.

Areas where the team will be active include:

  • Reviewing and updating documentation to ensure that it is friendly to new users
  • Updating examples in documentation to a style compatible with Modern Perl practices
  • Updating the documentation so that all examples longer than one line contain a use statement indicating the minimum version of Perl 5 required to run the example
  • Monitoring p5p for incoming documentation patches, ensuring they contain a patch against the current delta, and forwarding them to committers as needed
  • Monitoring p5p for patches that will require modification of documentation, and ensuring that the documentation is modified appropriately
  • Verifying that perlglossary contains current accurate definitions for all jargon terms

Goals to be met for the Perl 5.14.0 release include:

  • Recruit novice and experienced Perl programmers to the team, and create a Perl module (a la Perl::Staff) and a Perl 5 wiki entry listing the team members
  • Finalize perlopquick as a replacement for perlop and modify the new perlop so that perlop and a shorter perlopref can be generated from a single source document
  • Extend perldoc to use the new perlop to provide documentation on operators (tenative proposal: perldoc -O "^=")
  • Create a perlfuncref, a series of short summaries of information in perlfunc, analogous to perlopref (Again, both of these will be generated from a single source document for ease of maintenance)
  • Define a policy for documenting documentation changes in the Perl deltas (e.g. perl5133delta.pod)
  • Define a set of documentation style guidelines, covering structure, style, and content
  • Formally define the Perl 5 Documentation Team functions
  • Set deadlines for the defining of longer term goals
  • Create a logo for the Perl 5 Documentation Team
  • Find a better name or nickname for the Perl 5 Documentation Team

Potential longer term (post-5.14.0) goals:

  • Clean up perlre
  • Extensive review and Modernization of all examples
  • Develop a plan to integrate with the Pod2 translation project