August 2004 Archives

Hacking Perl in Nightclubs

I've found the experiences of dancing and programming to have a great deal in common. With both I am immersed in an abstract world of animated structures, building up and breaking down many times before finally reaching a conclusion. Indeed, when the operation of even the dullest data-munging computer program is visualized, for example in a debugger, it does seem to be dancing around its loops and conditions -- moving in patterns through time.

In other words, a musical score is a kind of source code, and a musical performance is a kind of running program. When you play from a musical score or run a program you are bringing instructions to life.

So a piece of composed music is like a Perl script, but let's not forget improvised music. The rules behind improvised music -- for example improvised jazz -- develop during a performance, perhaps with little or no predefined plan. Where is the comparison with code here? Well, how many times have you sat down to write some Perl without first deciding exactly how you were going to structure it? Perl is great for improvising. The question is, can you write improvised Perl scripts on stage? This article hopes to answer this question.

Consumer Software v. Live Programming

If music and software have so much in common, how do they commonly meet? Well, modern-day music is often composed not at a piano but at a computer. Here the limits of composition are defined by the creators of software, with musicians eagerly waiting for the next upgrade of their favorite music application. However, at the fringes of electronic music, you find musicians who are also programmers, writing their own software to generate their music. This is a diverse world, spanning and mixing all the genres you could think of, from classical cantata form to speed garage to dance hall. Very few of these musicians have chosen Perl to write their musical code, but this article hopes to encourage more Perl hackers to turn their tools to music.

A little about myself -- I'm a musician who for the last few years has used Perl as my only musical instrument. I've had some successes, with hundreds of people dancing to my Perl, jumping about to my subroutines, whooping as I started up a new script. To this end, I built a whole library of little compositional Perl scripts that I ran together to make music. However, when running my Perl scripts during a performance I grew to feel as if I wasn't really performing -- I was running software I'd written earlier, so to some extent the performance was pre-prepared. I could tweak parameters and so on, but the underlying structure was dictated by my software. So what's the alternative?

Over the last couple of months, I've moved toward writing software live, in front of an audience. If a programmer is onstage, then they should program! This may seem a little extreme, but I'm not the only one making music this way. This approach grew through a collaboration with Adrian Ward called "slub," and also from a fast-growing organization called TOPLAP, the Temporary Organisation for the Promotion of Live Algorithm Programming. Check http://toplap.org/ for more information.

I'll introduce my live-programming environment -- "feedback.pl" --later. First, I'll talk a little about writing code that generates music.

Generative Music in Practice

When I use the phrase Perl Music, I mean music that is generated live by Perl code. Instead of writing a melodic sequence by hand, a Perl Musician writes a Perl script that algorithmically generates a melody. When making music in this way, the composer is taking a step back from the music, working with the structure behind a composition rather than with the composition itself. This approach is often termed "Generative music."

Perl hackers know that programming is a creative endeavour. So instead of starting with someone else's software, why not start with nothing apart from some vague musical idea? Then sit down and start to express that idea as code.

Now, while musical Perl code doesn't have to be complicated, it doesn't have to make sense either, you don't have to plan on making anything that is at all readable the next day. Saying that, to take full advantage of any inspiration you have found, code needs to be written very quickly, so keen programming skills and good knowledge of Perl is of great advantage.

In any case, the most important thing is that your code makes a musical pattern that you judge to be good. Sometimes elegant mathematical forms sound good, other times unexpected bugs and chaotic nonsense produce the most interesting results.

Let's sidetrack to talk a little about how you might build an environment to make live Perl music, starting with a brief tour around some useful CPAN modules.

CPAN Music Modules

Sadly Perl isn't quite fast enough to be useful for synthesizing sounds directly. Instead we have to use Perl to trigger sounds by talking to other bits of software or hardware.

There are a fair few music related Perl modules to be found on CPAN, perhaps the best known being the MIDI-Perl package by Sean Burke. MIDI-Perl concerns itself only with the reading and writing of MIDI files, which are a kind of musical score - this article is concerned with making live music, not writing scores. However, if you do want to create or manipulate MIDI files, the MIDI::Simple module in the MIDI-Perl package is a great place to start.

As well as a file format for storing musical scores, MIDI also provides a real time protocol for triggering sounds on synthesizers and samplers in real time. If you have a MIDI compatible synthesizer or sampler then there are CPAN modules to help you take advantage of them; MIDI::Music for UNIX and Win32API::MIDI for Windows.

Software synthesizers are now commonplace and reliable, thanks to the increasing speed of computers and improving latency times of operating systems including the Linux kernel. Most music software is still controllable by MIDI, but for a faster and more modern alternative, have a look at Open Sound Control (OSC).

OSC is an open network protocol for music, and is well supported by the best free software music applications including pure-data, SuperCollider and CSound. It's most commonly carried over UDP, so you can use your existing TCP/IP network and Internet connection for OSC.

For sending and receiving OSC messages with Perl, install the Audio::OSC package from CPAN. Here's an example of its use:


  my $osc = 
      Audio::OSC::Client->new(Host => 'localhost', Port => 57120);

  $osc->send(['#bundle', time() + 0.25, ['/play', 'i', "60"]]);

This example sends a message to port 57120 telling it to play number 60 in a quarter of a second's time. The OSC protocol doesn't define the meaning of such commands, it's up to you to make sure that the receiving application understands what the sending application is asking of it. Later I'll show the use of Audio::OSC to talk to an application called SuperCollider.

Ecasound is an excellent piece of software useful for live routing and recording of audio. It supports LADSPA plug-ins, allowing you full programmatic control over a wide range of effects such as noise filters, reverb, chorus and so on. For full real time control over ecasound, install the Audio::Ecasound module.

While not likely to have a place in a professional studio, Audio::Beep is a fun way of making primitive, monophonic music. I'll use this in an example later.

Finally, perhaps the most essential CPAN module for live music is Time::HiRes. Unless your music is very intense, at some point you'll want your script to pause before triggering the next sound. Normally Perl only lets you sleep for whole seconds at a time, but Time::HiRes offers a great deal more accuracy. Time is such an important issue in music, that I've dedicated the whole of the next section to it.

Time

Time is central to music, and presents a few technical hurdles to jump. If you have more than one music-generating Perl script running at the same time, you'll want to keep them in sync somehow, and if you're playing with someone else, you'll need to keep in sync with them as well. You not only need to make sure all the different scripts are playing at the same speed, but also in phase - that is, everything needs to be able to work out when the start of the bar is. Further, at some point you'll want to change the speed of the music, especially if your crowd are looking a bit restless. And if you want to start up a new script while another is running, how do get it to start at the right moment?

Here's how I do it, in brief. I have a central time server called 'tm.pl', that stores the current bangs per minute (bpm), the number of bangs that have occurred since the script started, the number of bangs since the last bpm tempo change and the time of that change. It keeps this information up to date by referring to the system clock. By fetching these four simple bits of information it's possible for another Perl script to work out what it should be doing and when.

A 'bang' is like a musical beat, or the regular tick of a clock. Each Perl script keeps its own 'heart beat', an event that regularly calls a method called 'bang'. I put all my music generating code inside that 'bang' method. If it receives a bpm change from the server it schedules the change of speed at exactly the right moment.

Well, I say that but of course computers are volatile things, and so in practice events never happen at exactly the right moment. But as long as the math is right, any slight error is corrected, and so the scripts stay in synchrony.

Introducing feedback.pl

Now as I tried to explain earlier, I like to write code live while practicing and performing. I should really explain what this means.

I wrote my own little text editor for live coding. The editor is only intended for writing Perl code, but doesn't have a save function. In that case, you might wonder how I execute the code.

Well if you're using feedback.pl, the code you're writing is running all the time, in the background. In fact feedback.pl has two "threads" - one thread is the text editor and another runs the code that is being edited. The running code in the second thread re-parses itself whenever you press ctrl-x, leaving all variables intact. mod_perl programmers will be familiar with this concept -- the Apache::StatINC and Apache::Reload modules do something very similar.

It gets weirder -- the running code can edit its own source code. This is really useful for user feedback. I quite often write code that puts comments in its source that tells me what the running code is up to. So, the human interface to the running code is its source code. You edit the code to modify the process; the process edits the code in response. That's why it's called feedback.pl.

If you want to see what I mean, download feedback.pl from:

http://cpan.org/authors/id/Y/YA/YAXU/perl-music-article/examples/feedback-0.1.pl

You'll need a few modules installed from CPAN to get it to work. Audio::Beep, Audio::OSC and Time::HiRes. Sadly Audio::Beep only works under Linux and Microsoft Windows at the moment, users of other operating systems will have to fiddle about to get these examples to work.

Once everything is ready, run feedback.pl and type this little script in:


  # 231
  sub bang {
      my $self = shift;
      $self->code->[0] = '# ' . $self->{bangs};
      $self->modified;
  }

Press ctrl-x and it will start to run. $self->{bangs} contains the number of bangs since the script was started, and this is written to the first line of the code (make sure that line doesn't have anything important in it). Calling $self->modified tells the editor that the code has changed, causing it to refresh the screen with the changes.

OK, lets make some sounds.


  #
  sub bang {
      my $self = shift;
      my $note = 100;
      $note += 50 if $self->{bangs} % 4 == 0;  
      $note -= 30 if $self->{bangs} % 3 == 0;  
      $note += 60 if $self->{bangs} % 7 == 0;
      beep($note, 40);
      $self->code->[0] = '# note: ' . $note;
      $self->modified;
  }

Hopefully this should play a bassline through your speaker. beep() is a routine imported from Audio::Beep; you just pass it a frequency in Hz and a duration in milliseconds.

The bassline is surprisingly complex for such a short program. It could almost be the theme tune to an 8-bit computer game. The complexity comes from the use of polyrhythms, in this case three different modulus combined together.

Polyrhythms are wonderful to play with but largely absent from commercial dance music. You can see one reason for this absence by looking at consumer music software -- while such pieces of software are obsessed with loops, they don't make it very easy for you to mix loops with different time signatures together. Writing our own code brings us freedom from such constraints, and you can really hear that freedom in polyrhythms.

Now these simple beeps are fun, but quite limited, obviously. You can only play one beep at a time, and have no control over the timbral qualities of the sound. Lets have a quick look at getting better sounds out of our computers by controlling SuperCollider from Perl.

Beyond the Beep -- SuperCollider

SuperCollider is a powerful language for audio synthesis, is free Software, and runs under both Linux and Mac OS X. It consists of two Parts: scserver, a real-time sound synthesis server, and sclang, an Object-Oriented interpreted language based on smalltalk (sclang). Due to SuperCollider's client-server architecture, it's possible for other languages to replace sclang and control scserver directly, although scheme is the only other language with the libraries for this so far. However, with Perl it's easy to control sclang scripts with the aforementioned Audio::OSC module.

As a rich programming language, SuperCollider takes a bit of learning; however, if you want to try making some sounds with Perl and SuperCollider script. Here it is:

http://cpan.org/authors/id/Y/YA/YAXU/perl-music-article/examples/simple.sc

Once you have SuperCollider running, you can start up the script like so:


  sclang ./simple.sc -

Note that SuperCollider users call their programs "patches" rather than "scripts". Patching (or paching) is a historical term that originally referred to the programming of analog synthesizers, but as far as SuperCollider is concerned, it's mostly synonymous with scripting.

The simple.sc script listens for OSC messages, which you can send from feedback.pl using the built in methods 'play' and 'trigger' like this:


  sub bang {
      my $self = shift;
      # play a "middle c" note every fourth bang
      $self->play({num => 60})
        if $self->{bangs} % 4 == 0;
  }

You can also trigger a sample in this way:


  sub bang {
      my $self = shift;
      # play a drum sample for 100 milliseconds, panned slightly to the left,
      # every sixth bang
      $self->trigger({sample => '/home/alex/samples/drum.wav'
                      ts     => 100,
                      pan    => 0.4
                     }
                    )
        if $self->{bangs} % 6 == 0;
  }

Check the source code of feedback.pl to see how the OSC message is sent, and to seek out extra parameters to effect the sound further.

Multiple Scripts

To have multiple scripts running at the same time, you can use my "tm.pl" script.

http://cpan.org/authors/id/Y/YA/YAXU/perl-music-article/examples/tm-0.1.pl

It requires a spread communication daemon (http://spread.org/) to be running and the Spread::Session Perl module to be installed. Start the tm.pl script, set the environment variable SPREAD to 1, and then multiple invocations of feedback.pl will stay in synch. You can change the bpm (bangs per minute, similar to beats per minute) at any time, for example $self->set_bpm(800) will set the bpm to 800, which is suitable for fast gabba techno.

Further Experiments

I haven't gone into detail about how to generate the music itself - that's really up to you and your imagination. However, here are a few pointers toward some interesting areas of research.

Markov chains are a way of probabilistically analyzing a one-dimensional structure and then generating new structures based on the original. It's used often for producing amusingly garbled text, but can also be used for making amusingly garbled music. Check Richard Clamp's Algorithm::MarkovChain module on CPAN for more details.

Regular expressions are of course excellent for manipulating chunks of text, but why not instead use them to manipulate sequences of notes while they are playing? Being able to hear as well as see the effect of a regex is rather pleasing.

Lastly, my best advice when looking for inspiration is to listen to your favorite pieces of music. Listen to the structure behind a piece and think about how you might write an algorithm to create that structure. Once you start writing the code you'll start to get more ideas based upon it, so that the eventual music sounds nothing like what you found inspiration from.

Conclusion

This might all sound like a rather strange and tortured way of making music, but actually the opposite is true. It's not strange, there is structure behind every piece of music, and it's quite normal for composers to think of the composition of this structure in terms of a defined process. The classic example is of Mozart using dice to generate tunes. It's not tortured either. Thanks to Perl, music generating code can be extremely fast to work with.

The aims of all this are many and varied. One is to make people dance to Perl code, another is to be able to jam freely with others, not only laptop musicians but also drummers, singers and other 'real' musicians. Indeed, although programming does allow a certain unique perspective on things, the overall aim is to be able to reach some kind of level playing field with other musicians. I believe to reach this point, we have to learn how to use the whole computer as a musical instrument, rather than limiting ourselves to consumer software packages. So give it a go with Perl.

Footnote

At the time of writing and due to active development, Audio::OSC is not currently passing tests under Linux and quite possibly other architectures. It'll be fixed soon but until then users can find a patch that allows it to work under Intel-based Linux. To be truthful, all of this software is heavily experimental, feel free to contact me if you'd like some help.

Content Management with Bricolage


If you've ever had to manage a web site with tens of thousands of pages of content where many people need to be able to update that content, you've no doubt recognized the need for a content management system (CMS). Once you start to manage several such sites, the problem becomes even worse. Since you're reading this article on Perl.com, I'm going to go out on a limb and guess that you're actually interested in Perl-based content management systems.

Well, you're in luck.

This article is the first in a series on Perl.com introducing Bricolage, a Perl-powered, open-source, enterprise-class CMS currently in production for some of the most actively updated sites on the Internet today, including MacCentral, ETonline, and the World Health Organization. I start with a high-level overview (think executive summary) of the concept of content management, the nature of the content management ecosystem, and how Bricolage competes with other solutions in that ecosystem. Future articles will cover installation, document modeling, templating, and the Bricolage SOAP interface, among other topics. But first, the basics.

What is Content Management?

So much is made of the importance of web content management these days that the term, unfortunately, has been used to apply to just about any piece of software that somehow relates to the Web or to HTML. This trend has naturally eroded the meaning of the term content management. So I'm just going to punt on providing yet another definition, and focus instead on contrasting some of the categories of site-management software. In the process, I highlight where and how Bricolage fits into the CM ecosystem, and you get the benefit of determining what category of solution best fits your own content management needs.

Content Management vs. Community Building

First, there is the difference between content management systems and what I call community-building solutions, such as Slash and the various Nuke engines. These applications are ideal for setting up community-building and discussion sites, such as Slashdot, MacRumors.com, or (my favorite) use Perl. The idea behind these solutions is to allow site users to register with the site and post comments about articles, content on other sites, or each other's comments.

True content management systems, on the other hand, are primarily designed to allow organizations to centrally manage and deliver content, such as articles, white papers, marketing materials, or what have you. The emphasis is not on discussion (and indeed, most content management systems -- including Bricolage -- don't offer discussion interfaces), but on assuring the consistency of content structure and formatting. Good examples of such systems include Bricolage, Plone, Vignette, and Interwoven TeamSite.

Application Framework vs. Turnkey Application

Next, there's the distinction between application frameworks and turnkey applications. Frameworks are not actual solutions, but provide the tools for you to create your own solutions. Anyone who has programmed in Java understands what a framework is; a content-management framework provides an array of tools and libraries that you can use (or pay high-priced consultants to use on your behalf) to create an application to meet your needs.

Many organizations have bought such frameworks, and in large, heterogeneous environments with six- and seven-figure budgets and years to implement a solution, it can make a lot of sense. Good examples of such frameworks are Vignette, TeamSite, and the Python-based Zope.

A turnkey application, on the other hand, is a complete application out of the box. It will still likely require a good deal of customization to implement a turnkey application-based solution in a complex environment, but we're typically talking weeks or, at the most, a few months. The downside to such a solution is that you're limited to the features that the developers of the application anticipated would be needed; only with open-source solutions do you have the possibility of adding your own. Fortunately, this category of content management is well represented in the open-source space, including such stalwarts as Bricolage, Plone (built on the Zope framework), and TYPO3.

Application Server vs. Document Management and Publishing

And finally, there is the difference between content management application servers and document management and publishing solutions. Application servers serve dual roles in life: they provide an interface for managing content, and they deliver that content to the final audience. This approach has advantages for some organizations, in that it requires only a single server, document updates are immediate, and you need deal with only one technology. Plone, Zope, and the various Wiki solutions for ad-hoc content management are typical content-management application servers. Blogging software tends to fall into this category, as well.

The downside to application servers is that, because they both manage and deliver content, your choice of delivery technology is limited to the technology choices of the software developers. With Plone, for example, you have to use Zope to serve content to the final audience. Furthermore, many of them provide templates for the output of content that limit how much you can customize the look and feel of your site. And finally, performance on a high-volume site can suffer, due to the overhead of the API and database, as well as the trickiness of distributing content across an array of application servers (think caching).

Document management and publishing systems, however, function entirely independent of delivery solutions. They focus on managing documents, moving them through workflow, ensuring the consistency of their structures, and publishing them to external systems for delivery to the end audience. Content is completely independent of presentation in these systems. Upon publication, they push content through templates to format it into one or more types of output (HTML, XML, RSS, Mason, PHP, etc.), and then distribute the resulting files to other servers (typically a web, file, or application server) for delivery to the final audience.

This separation allows the document management and publishing server to do what it does best, freeing up the delivery server to do what it does best: serve content. Bricolage is perhaps the best-known solution in this category. Another one is the recently introduced Krang, which is itself heavily based on Bricolage.

The downside to the document management and publishing systems is that, while you are free to use whatever delivery technology you wish (plain HTML, PHP, JSP, ASP, TT3, SSI, etc.), for security and scalability reasons the publishing server generally must run on its own hardware, independent of the delivery server. Furthermore, these solutions tend to have a broader set of features than their application-server cousins. Since they don't worry about serving content, they can provide other essentials such as document modeling, workflow, multi-site management, multiple output channels, etc. While such functionality increases the flexibility of the software, it can also increase the complexity of an implementation. The upshot is that the implementation of such a solution requires a good deal of forethought and planning.

Why Bricolage?

Now that you have a feel for where Bricolage fits into the content-management universe (see how it's grown beyond an "ecosystem" in the space of a few paragraphs?), let's take a look at why Bricolage is a good solution for the complex content-management needs of organizations with large volumes of content, many content contributors and editors, and/or multiple sites to manage. Essentially, this boils down to a brief overview of some of the more important features of Bricolage. Once you've read this section, you should have a good idea of whether Bricolage is right for your organization.

Browser-based Editing and Administration

Bricolage provides a complete browser-based interface. Designed to work with any standards-compliant graphical browser, you can handle nearly all configuration and administration tasks via the browser. All document editing can be carried out in the browser, as well. Content authors can create and edit content using up to four different interfaces, including separate fields for each block-level piece of content (paragraphs, headers, blockquotes, etc.), bulk editing of multiple fields at once, or WYSIWYG-style editing with htmlArea in Internet Explorer and Gecko-based browsers such as Mozilla and Firefox.

Document Modeling

The document-modeling features of Bricolage allow you to model the structure of your documents entirely via the browser-based interface. Once you've ascertained the different types of documents your organization needs to manage, and what their structures will be, you can model them in Bricolage. All documents created in Bricolage are based on such models, and as such, must adhere to the hierarchical definition of elements and fields that constitute their models. This approach assures the consistency of document structure.

Bricolage Element Profile

Bricolage's element-administration interface makes it easy to create new elements, add sub-elements, and create content fields.

Bricolage document models are built into a tree-like structure of elements and fields. Elements are the building blocks of content in Bricolage. They represent various parts of documents, such as pages; side bars; related media such as images, lists, related links; and the like. Every element can contain zero or more sub-elements, and together the hierarchy of elements make up the "branches" of the document model tree. Fields represent the "leaves", and are the containers into which content can be entered. Any kind of HTML field can be defined for use in the Bricolage UI, including text input fields, textarea fields, and select lists. Typical fields include "paragraphs," "headers," "list items," "teasers," and "URLs."

When an editor creates a document, it is based on a document model, and its structure must adhere to the model's element structure. Documents consist of a tree structure of elements, corresponding to the element structure of the document model, and in this way ensure the consistency of structure across documents. For more on Bricolage document modeling and elements, watch for the third article in this series, "Bricolage Document Modeling."

Separation of Content from Presentation

Since Bricolage document models are purely about structure, and a document's content will be stored in Bricolage in the same structured fashion as its model defines, no presentation information is generally included in a document. In other words, the content of a document is pure content, with little or no reference to formatting. Instead, it is a simple structural object representing the tree-like configuration of content elements.

The upside to this architecture is that highly structured content enables a virtually unlimited array of output options. The templates that format content can take advantage of the well-defined composition of a document model to grab the elements they need for the format they understand. Thus, a single document can be used to output a structured XML file, a set of HTML pages, an RSS feed, a PDF file, or whatever you require.

Done right, you get the Holy Grail of one canonical document and unlimited representations of that document. This capability is especially important in the fast-moving environment of the Internet, where new formatting standards are regularly introduced, demanding the creation of new templates to output existing content to satisfy the new standards.

Content Categorization

All Bricolage documents can be organized into one or more categories. These categories are hierarchical, and the hierarchies are used in part to create document URLs. This design allows you to store your documents in sensible locations on your web site, and provides them with legible URLs that search engines just love. Furthermore, it's easy to search for documents in a given category or set of categories using the Bricolage API, so that you can quickly create templates to generate category-specific directories of documents, such as RSS feeds.

Bricolage Category Manager

Bricolage allows you to create an unlimited number of hierarchical categories in which to file documents.

Meaningful URLs

In addition to categories, Bricolage document URLs can include the year, month, day of the month, and/or a slug — which is a short string describing the document, such as "bricolage-intro." Combined, these pieces of metadata generate meaningful URLs, such as /features/perl/2004/17/26/bricolage-intro for a Perl feature introducing Bricolage and published on 26 July 2004. Such URLs are very search-engine friendly, too, so they should greatly enhance your Google rankings, for example.

Keywords

Bricolage documents can be associated with arbitrary keywords. These, too, can be queried via the Bricolage API, making keyword indexes a possibility. And of course, they're available in templates for outputting <meta> tags, Dublin Core Metadata, and the like.

Workflow

Bricolage provides a workflow interface for managing your documents and templates. A workflow is a way to organize the process of creating a document. Typically, a document workflow defines areas of responsibility in the process of creating a document, such as writing, copy editing, legal review, and publishing. True to its original genesis among newspaper publishers, Bricolage workflows divide these responsibilities between desks. So one might have a workflow named "Document" for managing documents, with an "Edit Desk," a "Copy Desk," a "Legal Desk," and a "Publish Desk."

Bricolage Document Workflow

Bricolage workflows can be configured to reflect your organization's standard editorial processes.

You can create as many workflows as your organization requires, each with as many desks as you require. Desks can be shared across workflows — if you need certain parties to assume similar responsibilities in different workflows — and you can set up permissions such that certain users have access only to the documents in specific workflows and on specific desks. In short, you have a lot of flexibility to closely model the actual workflow in your organization, so that working with Bricolage is simply an extension of your users' standard editorial processes.

Output Channels

Output channels are collections of templates that output content in particular formats. Typical Bricolage solutions in production today have output channels for XHTML, RSS, WML, etc. Furthermore, output channels can include templates from other output channels. When Bricolage looks for a template, it looks in the output channel being published to, and then any output channels it includes. The search for the template resembles how Perl searches through the @INC array for a module. The upshot is that Bricolage makes it easy for you to create libraries of templates that can be used across output channels.

Bricolage templates correspond to document categories and elements, so that one element template outputs the content of a single element, or wraps the output of document-element templates for all documents in a category. Because a single element definition can be associated with different document models, this approach ensures the formatting of the content in elements based on that definition will be consistent across all documents.

Perl Templating

The templates in Bricolage output channels can be implemented in one of three templating architectures: Mason, Template Toolkit, or HTML::Template.

Yes, that's right, not only do you have three different choices for templating in Bricolage, but they're all Perl-based! In addition to being able to provide a familiar templating environment to tens of thousands of Perl programmers worldwide, the templating solutions can leverage the full power of Perl to generate output for your documents. That power of course includes CPAN, where you'll find modules to ease the generation of RSS feeds, HTML, XML, PDFs, or even Excel files!

Furthermore, Bricolage has a sub-classable templating architecture, which means that, with a little bit of work, you can add your own templating architecture. Anyone care to add support for Embperl, Apache::ASP, or XSLT?

For more on Bricolage templating, watch for the fourth article in this series, "Mason Templating in Bricolage."

Multi-site Management

More and more organizations are finding themselves managing more and more sites as part of their content-management responsibilities. As of version 1.8.0, Bricolage offers support for managing multiple sites from a single instance. Different sites can have their own categories, workflows (but share desks), output channels (but can include output channels from other sites), and distribution destinations. They can also share document models, so that different sites can manage the same types of documents but publish them with their own templates. This flexible multi-site management allows you to divide responsibilities appropriately while keeping all content centrally managed and accessible via a common interface.

Bricolage Site Profile

You can manage any number of different sites in Bricolage, each with its own documents, categories, templates, and workflows.

Document Aliasing

Once you have several departments in your organization managing their own sites, they might decide that they need to publish each other's content. Fortunately, if these sites are using the same document models, they can. Users with READ access to another site can create aliases to documents on that site. They can edit the title, URL, and keywords of the alias for the benefit of their own site, but the content remains in read-only form, so that editorial control remains in the hands of the originating site. Document aliasing thus provides a simple approach for sites to publish each other's content without violating one another's editorial integrity.

SOAP Interface

Bricolage features a robust and full-featured SOAP interface. The included bric_soap command-line client makes it easy to import and export documents, templates, and administrative objects, as well as bulk publish or update content. The ability to import content is especially important for organizations that wish to migrate their existing documents into Bricolage for management and publishing going forward. Watch for an article later in this series that highlights the flexibility and power of the Bricolage SOAP server.

Scalability

Bricolage is designed to scale to the needs of the largest organizations. Its scalability manifests in three directions. Horizontal scalability is ensured by the ability to distribute the load between separate database, application, preview, and distribution servers. And remember, because Bricolage operates independent of the delivery of content to the final audience, your site's front-end servers can scale independently of Bricolage.

The browser-based interface provides Geographical scalability by allowing users to securely use Bricolage from anywhere in the world. Whether content editors are down the hall, across the country, or on the other side of the globe, if they have a browser and access to the Bricolage server's network, then they can be contributing content to your sites.

And finally, the Bricolage feature-set ensures organizational scalability, allowing for the centralized management of multiple sites, multiple types of documents, content categorization, and flexible templating across an organization and its sites. These features can be exercised as necessary as the needs of your organization evolve. In other words, Bricolage rapidly adapts to the changing requirements of your content-management environment.

Security

Bricolage provides comprehensive security via encryption, user permissions, and its independence from your delivery servers. All communications with Bricolage can be encrypted over SSH/TLS to ensure secure use of the server from anywhere in the world. The same applies to the SOAP server, of course. At the access level, Bricolage provides a comprehensive permissions system to ensure that users get access only to the content and administrative objects relevant to getting their work done. And because Bricolage does not serve content to your final audience — it generally runs as a back-office application and often behind a secure firewall — your content library remains safe in Bricolage even if the security of your front-end servers becomes compromised.

Bricolage Permissions Administration

Bricolage offers a comprehensive permissions system to ensure users get access to only the objects they need to get their jobs done.

ROI

Bricolage's open-source licensing helps to ensure that it is fully buzzword compliant, in that you can achieve a much higher return on investment (ROI) than with competitive commercial systems. Furthermore, Bricolage runs exclusively open-source software, including Apache/mod_perl and the PostgreSQL RDBMS, so there are no hidden licensing costs, either. And finally, even organizations that decide to use <plug>professional consulting services</plug> for their Bricolage implementations find that the expense tends to be around half what it costs for the rollout of a commercial content-management solution.

Who Uses Bricolage?

Despite its genesis in the online news niche, Bricolage has managed it to go into production in a variety of settings. This success is a function of its broad feature-set, as well as the regard it has gained from the press. So who uses it?

And there are many other organizations quietly using Bricolage without publicly making that fact known.

Right for You?

If Bricolage sounds like a good fit for your organization's content-management needs, or if you're interested in how Bricolage really works, stay tuned to Perl.com for my next article, "Bricolage Installation and Configuration," and we'll have you up and running in no time!

Acknowledgments

I'd like to thank Darren Duncan, James Duncan Davidson, and Rael Dornfest for providing valuable feedback on drafts of this article.

This Week on Perl 6, Week Ending 2004-08-20

The Perl 6 Summary for the fortnight ending 2004-08-20

Harrumph. Note to self; never miss a week when you could actually have written the summary. I lulled myself into a false sense of security with the quiet week for the last summary. The last two weeks have been rather more busy and I've been away at EuroFoo over the weekend.

So, this fortnight's summary might be a bit sketchy.

We're back with starting with perl6-internals this time as it continues to comfortably out traffic perl6-language (message count was running about 3:1 in favour of p6i).

Register allocation

Work continued apace on adding a bullet proof failsafe register spilling algorithm so that Dan's work project could be made to at least compile. There was much discussion of what was actually causing the problem and several attempts to fix it. Work is ongoing.

Melvin Smith coined a new acronym: DSWEPIC, which stands for Dan Stop Writing Evil Pathological Intermediate Code though, as chromatic pointed out, it's actually Dan's compiler that's generating Evil Pathological code and Dan claimed that that's because he's writing a compiler for an Evil Pathological language.

http://groups.google.com/groups?threadm=41133881.5050009@toetsch.at

Parrot cvs mirrored with svk

Chia-liang Kao announced that he (I'm guessing, I'm not very good at divining the gender of none western names. Sadly 'he' is usually a safe bet in this field though) was mirroring the Parrot CVS repository in a Subversion repository for those who didn't like CVS. There was a certain amount of chuntering but most people seemed pleased by this.

http://groups.google.com/groups?threadm=20040807085230.GA33705@portege.clkao.org

The Pie-thon post-mortem

Dan posted his notes on the aftermath of the pie-thon push. Next time we do this, we'll start earlier.

http://groups.google.com/groups?threadm=a0611042dbd3acdf97ef5@[172.24.18.98]

An alternate call scheme

Dan ruled on Leo's alternate call scheme proposal, but wasn't entirely comfortable with it. However, he sketched out another idea inspired by it. Leo didn't sound convinced.

http://groups.google.com/groups?threadm=a06110418bd397f6e35e5@[172.24.18.98]

Source mangling slides

Dan posted a link to an abortive talk on some of the cunning tricks we do with source mangling in Parrot.

http://groups.google.com/groups?threadm=a06110404bd3d23cf4f7b@[10.0.1.3]

http://www.sidhe.org/~dan/presentations/Parrot_Implementation.pdf

Making NCI work with a nasty library

Hildo Biersma is trying to write parrot support for IBM's MQ library. He had a couple of questions about the best way to go about it. Leo and chromatic had some suggestions.

http://groups.google.com/groups?threadm=16663.29639.371953.272205@saimq5.ms.com

Functions for embedders to override

Noting that Ponie was already have problems, Dan outlined those functions that embedding environments may need to override to get things working. He asked for help and comments in getting a system in place to allow overriding functions to be registered in order to give embedders control over parrot's interface to the real world. This is something which needs doing sooner rather than later so as to avoid storing up pain.

This triggered a fairly wide ranging discussion, but progress is being made.

http://groups.google.com/groups?threadm=a0611040cbd3d4f989298@[10.0.1.3]

What Unicode means to us

Mmm... Unicode. Dan outlined what need to deal with to do Unicode sufficiently well. Discussion ensued.

http://groups.google.com/groups?threadm=a0611040ebd3d6a1ac8fe@[10.0.1.3]

Fix generation of src/nci.c to be more efficient

I don't normally point out patches, but Dan's patch to improve the generation of src/nci.c spawned a longish thread with commentary from Nicholas Clark and chromatic.

http://groups.google.com/groups?threadm=rt-3.0.11-31026-93446.17.5789743157492@perl.org

A small task for the interested

Dan posted another of his small tasks for the interested (maybe we should start calling them STFTIs?). This time he's after source tests to test the embedding interface and some fixing of the auto-prefix scheme.

http://groups.google.com/groups?threadm=a0611040cbd3da10ca9c3@[172.24.18.98]

The encoding API

Dan detailed the encoding API, the layer that mediates between Parrot, which sees strings as a sequence of codepoints and the underlying buffer full of bytes. Gopal V and Michael Stone had questions and suggestions.

http://groups.google.com/groups?threadm=a06110400bd3daa20ca5a@[172.24.18.98]

COBOL on Parrot?

Remember Dan pointed everyone at a GPL'd COBOL compiler and suggested that a Parrot backend would be cool? David Essex (if that's the British singer from the 70s then I'll be boggling like a good 'un) pointed everyone at a couple of others. He and Uri Guttman discussed runtime libraries.

http://groups.google.com/groups?threadm=41182276.2080908@arvotek.net

The Perl 6 compiler pumpking

Patrick Michaud, Perl 6 compiler pumpking, outlined his plan for getting us to a working Perl 6 compiler.

http://groups.google.com/groups?threadm=20040809192444.GH18480@contra.vosn.net

PMC semantics

Leo kicked off what looks like being a long running thread when he opened discussion of the semantics of the various integerish PMCs in Parrot. Larry and Dan both pitched in with discussion.

http://groups.google.com/groups?threadm=4118B4E9.9070906@toetsch.at

Charset API

Dan posted part two of the charset API, which confused me slightly by arriving on my computer before Part 1.

http://groups.google.com/groups?threadm=a06110410bd4148de4d94@[172.24.18.155] -- Part 1

http://groups.google.com/groups?threadm=a06110400bd416568fe25@[172.24.10.164] -- Part 2

Handling block parameters in Ruby

Mark Sparshatt asked for advice on how to handle method invocations that include special block parameters like Ruby's. Leo thought that handling it in the parser/compiler and simply passing the block in as an extra parameter was the best way forward. Larry and Dan discussed complications associated with that idea.

http://groups.google.com/groups?threadm=411A83D9.1060502@yahoo.co.uk

Parakeet breaks and recovers

Michel Pelletier updated his Parrot distribution and managed to kill his Parakeet language. Dan and Leo set about trying to track the underlying bug down. I presume it got fixed because Michel posted a new version of Parakeet soon after.

http://groups.google.com/groups?threadm=20040813112456.1bc2ec2f.michel@dialnetwork.com

http://groups.google.com/groups?threadm=20040815133243.20f37973.michel@dialnetwork.com

NCI and callback functions

Stephane Peiry had some problems getting NCI callbacks working with GTK. He and Leo went tried the debugging by email trick, but with little joy before the end of the week.

http://groups.google.com/groups?threadm=20040815205143.GA12992@pittypanda

TODOs added

Will Coleda added a vast number of TODO items to Parrot's RT queue.

His TODO about the configuration system sparked a good deal of discussion. At least one person suggested ditching make, which seems to be par for the course in these kinds of discussions.

http://www.parrotcode.org/todo.html

http://groups.google.com/groups?threadm=rt-3.0.11-31138-93745.19.5978270633675@perl.org

Popping an empty array

Michel Pelletier wondered how to generate a catchable exception when he tried to pop from an empty PerlArray. Larry reckoned that, if it's really a PerlArray it should return an undef containing an unthrown exception. Which sparked a longish discussion...

http://groups.google.com/groups?threadm=20040816050945.63280604.michel@dialnetwork.com

Parrot interfaces

Noticing that there appeared to be ops for handling interfaces, Michel Pelletier wondered when we might see an implementation or PDD covering their semantics. Our resident roles guy, chromatic, pointed out that Parrot will actually have roles, which can look like interfaces in the right light and pointed at Apocalypse 12 for more in the way of detail.

Later on, Dan sketched out an initial interface spec. Parrot level interfaces are very simple indeed.

http://groups.google.com/groups?threadm=20040816113022.2941e76f.michel@dialnetwork.com

http://groups.google.com/groups?threadm=a06110403bd47c07ce518@[10.0.1.2]

Interpreter permissioning

Felix Gallo sought input on the problem of interpreter permissioning. He got lots.

http://groups.google.com/groups?threadm=20040817161114.GA47639@amse.pair.com

What?

Dan Sugalski is a very, very bad man. Sure, he gets a good deal of mitigation from Parrot working as well as it does, but... well... Multi Method Dispatch on return continuations is sick, evil, and a strangely fascinating idea.

http://groups.google.com/groups?threadm=a06110409bd4815efebe7@[172.24.10.164]

Span praise

Dan's been catching up with his mail and popped his head up to say nice things about Span, a very pleasant looking OO language based around Parrot.

http://groups.google.com/groups?threadm=a06110407bd4a7b7edc43@[172.24.10.164]

Incremental garbage collection

Leo's working on implementing an incremental garbage collector for Parrot. The idea behind it is to reduce the amount of time the GC system spends with the world stopped. The response was generally positive, with discussion of potential edge cases.

http://groups.google.com/groups?threadm=4126558A.8000803@toetsch.at

http://groups.google.com/groups?threadm=4125B668.2070400@toetsch.at

GC/DOD API

Whee, a subject that's all acronym. That's Garbage Collection/Dead Object Detection Application Programming Interface for those of you who are bemused by the alphabet soup.

Dan pointed out that, before we get a fully reworked garbage collection system in place, it would be a good idea to get the API designed and documented.

http://groups.google.com/groups?threadm=a0611040dbd4bfbdcca85@[10.0.1.2]

Meanwhile, in perl6-language

Revision of Apocalypse 12's lookahead notions

Larry posted a a message resolving issues with method lookahead and adverb parsing. And there was much discussion and clarification. Expect to see the results in Synopsis 12 when it gets written.

http://groups.google.com/groups?threadm=20040810180759.GA16766@wall.org

Handling block parameters in Ruby

Matt Diephouse spawned a subthread from the A12 lookahead discussion by wondering how Perl 6 will handle multiple blocks as arguments. Larry had some thoughts.

http://groups.google.com/groups?threadm=198c873804081311217628470@mail.gmail.com

Precedence table update

Larry posted a newly tweaked Perl 6 operator precedence table. If you're one of those chaps who thinks Perl has too much syntax look away (or point and laugh depending on your persuasion) now.

Various oversights were quickly spotted and fixed up.

http://groups.google.com/groups?threadm=20040814071716.GB11366@wall.org

Synopses drafts

Larry posted the first draft of Synopses 1, 2 and 4 the condensed, updated, versions of their respective apocalypses. The list did the usual proofreading/patching thing.

http://groups.google.com/groups?threadm=20040814183225.GB2827@wall.org

http://groups.google.com/groups?threadm=20040814183149.GA2827@wall.org

http://groups.google.com/groups?threadm=20040820024536.GA28138@wall.org

Return with no expression

Matt Diephouse found something surprising in Perl 5's handling of a return with no arguments and wondered if Perl 6 would magically solve his problem. Luke thinks it'll do the right thing by making the right hand side of a => evaluate in a scalar context.

http://groups.google.com/groups?threadm=198c873804081906351aebc796@mail.gmail.com

<-> as -> with automatic is rw

Juerd scared me by proposing that <-> be the equivalent of -> with an implicit is rw. Larry declared "It's really sick, and cute, and I love it." but thought that there might already be too many ways to declare a sub.

http://groups.google.com/groups?threadm=20040820200702.GK17296@c4.convolution.nl

Announcements, Apologies, Acknowledgements

Phew! I think I got this finished just before 'press' time for perl.com. Or maybe not.

If you find these summaries useful or enjoyable, please consider contributing to the Perl Foundation to help support the development of Perl. You might also like to send feedback or contributions to a 'getting Piers to OSCON 2005' fund to mailto:pdcawley@bofh.org.uk

http://donate.perl-foundation.org/ -- The Perl Foundation

http://dev.perl.org/perl6/ -- Perl 6 Development site

Oh yes, there's new content on my website for the first time in an age. Enjoy.

http://www.bofh.org.uk/

The State of the Onion

Note: All comments in square brackets are X screensavers that I ran for my slides. If you want to play along at home, start up xscreensaver-demo and click on the screensaver named. By the way, for any screensaver that wants random images (such as VidWhacker), I used a directory full of strange camel pictures (some of which I processed to make even stranger, just for those of you who think the phrase "strange camel" is redundant).

[VidWhacker (camels)]

Good evening. Welcome to my eighth State of the Onion speech. I only have two more speeches to go after this, and I'll be up to 10. You see, 10 is kind of a magical number for speeches. According to Sturgeon's Law, 9 out of 10 speeches are crap. After we get to number 10, we'll know which one of mine wasn't ... Probably number 9 or number 10 ...

So I'm giving you fair warning that this is probably going to be a lousy speech. Those of you who attended Damian Conway's Presentation Aikido seminar yesterday will be sure of it. You'll probably get more out of this speech than anyone else — mostly as a kind of negative example. You can just get out Damian's notes and start ticking off all the rules I've violated.

Now the particular reason this speech is going to be lousy is that I made up all my slides before I knew what I was going to talk about.

Well, OK, that's not quite right. I didn't make up my slides. I was lazy. That's a virtue, right? And I was Impatient. Plus I had the hubris to think that it didn't really matter what my slides say — I can probably wrap a speech around them anyway. Especially since there's only a 10% chance that it has to be a good speech.

So anyway, here's my first real slide. It's a picture of how Damian thinks.

[Maze]

As most of you know, Damian is very clear-headed and determined. He gets where he's going. It doesn't matter what the problem is, he'll find a way to solve it eventually. He may have to backtrack occasionally, but he's very goal-oriented, and knows how to backtrack gracefully. It's very good that we have Damian on the Perl 6 design team, because we need someone who thinks like that.

Here, on the other hand, is a picture of how well I think on Damian's level.

[AntSpotlight (camels)]

Yes, this is the famous Ant Spotlight screensaver. And yes, that is where I got all my slides from. And no, I didn't have a goal in mind when I picked them. Do you see any goals in this picture? Do you see any efficient search strategies? Do you see anything resembling speed here?

That's how well I think on Damian's level. On a different level, I think like this:

[Cloudlife, fast]

On this level, my mind is in a continual ferment. Things bubble up to the surface unbidden, and evolve in unexpected directions. Everything gets compared with everything else because the entire stew pot is bubbling like crazy. Well, maybe it's not like crazy. Maybe it is crazy.

One of the things that bubbled up recently was that the subject of this talk had to be screensavers. I didn't know why. Maybe I still don't know why. But be that as it may, that's what this talk is about. Screensavers, and why I have to talk about them today, and why I have to talk about why I have to talk about them today. It's a kind of recursive problem, you see.

Incidentally, this screensaver is a variant of Conway's Game of Life. No, not our Conway, the other Conway. Unless our Conway is the other Conway. Whatever, we'll keep our Conway. After all, he's TheDamian.

Anyway, the game of Life is sort of the prototypical example of a cellular automaton. A number of screensavers are based on cellular automata. I have great empathy for all of them, because that's how I think... I think...

[Critical]

On the other hand, my mind is like a screensaver that no one can ever look at, except maybe me, and God. People can't see the ferment in my mind. What they see externally has to be filtered through my verbal apparatus, which is actually quite limited. I often think that my verbal processor is a slow interpreter. My wife's verbal processor is a fast compiler. Actually, those of you who know Gloria will realize that she probably does her verbal processing down in the microcode. Or maybe it's just hardwired. She can read out loud faster than I can read silently. Or maybe it's just that she can talk faster than I can think. Or more likely, it's just that I think slower than she talks.

Anyway, where was I? Oh, yeah. This is how other people view my thinking. I spend a certain amount of time bouncing all over the cognitive map, then I'll perseverate in a particular area for a while, and then I'll take a flying mental leap to something that seems to the observer to be totally unrelated. They aren't unrelated, but they are long-range links. You know — all that six degrees of separation stuff. You need the long links as well as the short ones to make your graph work that way. There, my mentioning that is another example of just that sort of mental leap. This screensaver tends to look like a random walk generated by a person with attention deficit disorder. I don't have ADHD. I tend to perseverate and not get distracted when I should get distracted. If anything, I have Asperger's syndrome, or some kind of mild autism. My good friend Tom Christiansen, who does have ADHD, once said jokingly that I have "task-switching deficit" disorder. He's probably right on that. Certainly I seem to be stuck on this Perl thing. I've been stuck there for more than 15 years now. People think I make these long mental leaps all the time, but they're all in the scope of this one picture. In my mind, everything relates to Perl, one way or another. You'll notice this screensaver never jumps off the screen.

Another way to view this screensaver is that the long jumps are indicative of the ability to stay on task a long time. In that view, if you have attention deficit disorder, your thinking looks more like this, because you're changing directions faster than you want to.

[Wander]

People with ADHD have many endearing qualities, spontaneity not the least of them. But it is a disability, and the ADHD approach only gets you so far. More to the point, it tends to get you back where you were. Here we see a screensaver based on a random walk. It's actually rather stultifying if you watch it long enough. It's been shown mathematically that a random walk will eventually return to the place it started if you wait long enough.

Now, just because I say a random walk is stultifying to watch, please don't take that to mean that ADHD people are stultifying to watch. Quite the opposite, in fact. I'm just using these screensavers as talking points, as metaphors of life, but some of my metaphors limp. As we get older we realize that everyone has disabilities. That seems to be true of metaphors as well. They all limp. Except for the ones that are dead. Anyway, please don't anyone take offense at my free associations. Even if they're true.

You know how people are sometimes rude on Usenet or on a mailing list. Sometimes they'll write something that can only be taken as a deadly insult, and then they have the unmitigated gall to put a smiley face on it, as if that makes it all right. It doesn't, you know. Nevertheless, if I insult you with a deadly insult in this talk, please put one of those little smileys after it. :-)

Anyway, where was I. Oh, yes, random walks. And the fact that they're kind of stultifying to watch.

[Rorschach]

You could throw in a little symmetry for interest. In fact, there's already a special screensaver for that, which you can use if you want to find out if you've cracked...

Hmm...

Personally, Rorschach blots always look like butterflies to me. Or pelvis bones, I admit it.

Or Mecha warriors. And such. You could almost swear the designers of Japanese anime must use this program to come up with new ideas for various kinds of monsters. But it's still a random-walk program when you look at it. It's value to psychoanalysis comes from the bilateral symmetry, which psychoanalysts think will remind us of sex, for some reason. Probably has something to do with the fact that people are bilaterally symmetrical.

Pychoanalysts tend to have abstract hang-ups about sex (at least the Freudian ones do), but since we're not psychoanalysts here, why stop at bilateral symmetry? Why stop at random walks? Why not psychoanalyze ourselves with other kinds of free associations?

Which is precisely what I'm doing here. Another way of looking at this talk is that I'm psychoanalyzing myself in front of you, using all these screensavers as Rorschach blots to free associate with. Another way to look at it is that screensavers are sort of a poor man's LSD, without the bad trips.

By the way, I don't think there are any Freudian psychologists in the audience, but if you happen to be a Freudian psychologist, and were insulted by my earlier remarks ... well ... just deal with it ... repress it, or something ....

In honor of Freudian psychology, I should in all fairness point out that I am myself the subject a classical case of repressed memory. I don't remember anything from my fifth grade. It wasn't anything sexual (I don't think!), but I am told that it was one of these experimental open classrooms where you have to decide yourself what you're going to learn. That works well for these kinds of people:

[Maze]

One of the aspects of my Asperger personality is that I don't initiate things like that. I have impaired executive function, in modern terminology. I almost never initiate telephone calls. I almost never initiate anything, in fact. Funny, considering Perl, but nevertheless true.

The most telling example of that is when Deja first put up all the old Usenet news articles for browsing. My good friend Randal Schwartz went in and discovered that of the hundreds of articles I'd posted over the years, only one article was not a follow-up to some else's article. I don't initiate. I have no initiative. I guess that makes me lazy. Oh, well.

Anyway, I don't remember fifth grade at all. I did terribly that year, and completely blocked it out of my memory. I remember fourth grade and sixth grade just fine though. But then, I did well those years. It all fits. Case closed.

[DangerBall]

But now I have this other psychological mystery I'm trying to solve. Maybe it's just some kind of compulsion, but I know deep down that I have to talk about screensavers for this speech. But why? Why, why, why, why, why? It's irrational and illogical.

So that's what the rest of this talk is about. It all ties in with what happened to me last year, and it also all ties in with Perl.

So about what happened to me last year: I had a mutation. That's nothing new — people have mutations all the time. So do screensavers. Many screensavers, such as this one, are based simply on showing you a mutating object, moving around the screen. That's pretty natural for screensavers. After all, the original purpose of screensavers was to save your screen, and that meant not putting the same picture up in the same place for an extended period of time. Of course, a blank screen would serve for that just as well. But, ya know, a blank screen just isn't very interesting. So we get these various mutator objects instead.

[Cubenetic]

This one does interweaving cubes.

[Engine]

Here's a cute mutator. The little engine that could, if you will...

[FlipFlop]

This one does flip flops. Being good at flip-flops is a prerequisite for designing computer languages. At least, I find that I have to do frequent flip-flops in the design of Perl 6. I probably shouldn't over-generalize that to other language designers, who by and large are smarter than I am.

[Gears]

Here's a picture of Perl 5. It's cool.

[Gears (planetary)]

Here's a picture of Perl 6. It's just the same as Perl 5, only cooler.

Planetary gears are very scalable — you can get a large increase or decrease in revolutions out of them. For that reason, planetary gears are often used in the engines of high-performance turboprop aircraft. Definitely industrial-strength stuff.

[Bouboule, 3d]

This one's kind of ugly, but then it's supposed to be viewed in 3D using those red/blue glasses. For some reason it reminds me of my stomach when I'm not feeling so good.

Which reminds me to get back to the subject. Mutations. I had one, in my stomach. It's a pretty well understood mutation, as these things go. It's the sort of mutation that produces a stomach tumor.

[Mirrorblob, color]

As I stood in this exact spot a year ago, I told you that I'd been in the hospital for four days with a bleeding ulcer. What I did not know at that time was that the ulcer was on a tumor the size of my fist toward the lower end of my stomach. I did not know that I would have the lower half of my stomach removed two weeks after OSCON. I did not know that I would have complications, and complications on my complications, recursively. I did not know that I'd be spending a total of two months in the hospital.

I was pretty ignorant back then.

You see, when you have bleeding ulcers on your vacation in Kauai, the doctor there tells you that he saw the ulcers, but he doesn't tell you that he saw them on a tumor. What he does tell you is to see a gastroenterologist the moment you get home. After all, he doesn't want to ruin the rest of your vacation. Never mind that you've spent it in the hospital.

[SpeedMine]

So after last year's OSCON I go in for another gastric endoscopy. That's where they slide a tube down your throat to look at what's down there. This is rather unpleasant, so they use what's called conscious sedation. They spray numbing gunk in the back of your throat, and put you partway under. You can kind of remember it afterwards, but not the bad bits.

[Spotlight (camels)]

Then the doctor looks around, much like our ant spotlight we had earlier. He can't see too much at a time, but he spots the tumor, and takes pictures of it. He can't tell how big it is, because endoscopes are monocular, and you can't really tell how close you are to what you're looking at.

A lot of screensavers are based on the spotlight metaphor. Here's another:

[Bumps (camels)]

And another.

[Zoom, lenses (camels)]

In this case, the size of the spotlight is the whole screen, like one of those useless digital zooms on your digital cameras. But it's still just viewing one portion of the picture, whether that's part of a camel, or part of an elephant. Or part of your stomach. My stomach, in this case.

[Goop]

At this point my gastroenterologist refers me to a surgeon. Since we don't know how big the tumor is, I have to drink a bunch of coconut-flavored white gludge and go in for a CT scan. I don't like coconut. I don't like white gludge. But I do it anyway. It makes some of your body less transparent than other parts. Some screensavers are about transparency. Others are about opacity.

Like the distinction between fermions and bosons, objects in screensavers have to decide whether to bounce off each other or allow overlap. And if they overlap, whether one of them hides the other or not. In this case, we see through the overlap. Many screensavers just pile things on top of each other, like this:

[Cynosure]

I find these screensavers disturbing, because they remind me that with the passage of time, everything old gets covered over by new things. It's a metaphor of past, present, and future.

After my CT scan, the surgeon calls my wife even before I get home, and asks if I could go into surgery the very next day to have the tumor removed. She says yes. So I do. Sometimes the future is closer than you think.

General anesthesia is not like sleeping. My dreams usually kind of look like this:

[Pipes]

But general anesthesia looks like this:

[Blank]

You have no present, just a past, and (hopefully) a future. You don't dream — it's just a big blank until you come out from under.

Then they put you on morphine, so you won't hurt. Instead, you itch. Did you know morphine makes you itch? Boy, does it ever. And you have really weird dreams. Dreams kind of like this:

[Bubbles, fastest, no hide]

Or this:

[Lament]

I had really weird dreams on morphine. Didn't like those screensavers. But a wonderful poem came to me — it started out "In Xanadu did Kubla Khan a stately pleasure dome decree." But I can't remember the rest of it.

Just kidding. But the place I did visit in my dreams was Xanadu, and it wasn't a very nice place to be. I prefer normal dreams.

When I was awake, I thought I was choking to death because of the tube down my nose to my stomach. I wasn't, but I thought I was. It wasn't until I cajoled a nurse into looking down my throat with a flashlight that I was mollified. That nurse became my favorite nurse, in a Florence Nightingale sort of way. I had several other favorite nurses too, for various reasons.

But then I had complications. As some of you know, twenty years ago I went blind in my right eye due to a case of shingles in my cornea. Shingles is just a recurrence of chicken pox virus.

So here's a screensaver called "NerveRot".

[NerveRot]

I love this screensaver, in a perverse sort of way. It's so...so...in your face. It's unnatural in so many ways. It looks like a fractal, but its fractal dimensionality isn't constant.

I don't love real nerverot. And shingles is a form of nerve rot, one of those things that kicks you when you're down. And I was down. I got a shingles infection on both sides of my head, which was unusual. It took me several days to figure it out. Fortunately, they have drugs to suppress it. But instead of getting out of the hospital in five days, it took ten. The good news was that my pathology analysis results came back saying that the excised tumor looked relatively benign in all respects except for its large size.

The bad news was that I was home for only twenty-four hours, and had to go back to emergency. I had never been more nauseous in my life, and to compound that, I found that even if I wanted to, I couldn't upchuck due to spasms in my esophagus. If you've ever had a tube down your nose, you'll know that you never want to have one again, but I was so miserable that I asked for one. It was a great improvement.

[Compass]

This screensaver was written to be nauseating, and I think it succeeds admirably in that. In fact, it really bugs me that I don't know why it has two needles pointing in different directions. I had far too many needles going in various directions when I was in the hospital. I hope that other needle there isn't the altimeter.

Anyway, this reminds us that an open source project needs a leader who has a good sense of direction, who doesn't change his mind continually about things like, say, how double-quoted strings ought to process interpolations, or which bits of the parser should work top down, and which bottom up. If you can find such a leader for Perl 6, that would definitely be an improvement over me. At least in some respects. Of course, I have the advantage of rules one and two. Rule 1: Larry is always right. Rule 2: Larry will still be right even after he changes his mind. Now I'm thinking there should also be a Rule 3, just in case. Rule 3 would say that Larry does not need to continue to be right after he's dead.

[BSOD "Blue Screen of Death"]

I was sure I was dying. I went back into the hospital, and stayed there for weeks. The bad news was that my surgery site had scarred up, and I couldn't eat or drink anything. I got all my nutrients and fluids through an IV line.

The good news was that if I waited long enough, it might open up again of its own accord.

That bad news was that after several weeks, it didn't.

The good news was that they had ways of putting tubes in to bypass the obstruction. So I had more procedures.

The bad news was the procedures didn't work.

The good news was that they had a way to revise the first surgery.

The bad news was that fixing the first surgery meant going through surgery all over again six weeks after my first surgery. Meanwhile, I spent a lot of time idling.

I think I started developing an empathy for screensavers about that time. The poor things just have to sit there and twiddle their thumbs. I was simultaneously bored and unable to concentrate. My friends sent me books that I couldn't read. The only thing I could concentrate on long enough was crossword puzzles. With a crossword puzzle, you can quit after a clue or two, and still make overall progress, even if your brain is crashing every few minutes. As mine was at that point.

This particular screensaver fools me more often than I care to admit. The problem is that the more computers you've used, the more different kinds of crashes you've seen. And mentally, you classify them all in the "Oh, shit!" category, which is a category the brain is very efficient at processing.

On the other hand, the part of your brain that says, "Hey, that's the crash screen for a different operating system, dufus!" — that part operates at a much slower pace. This is actually a profound psychological truth. Back in the heyday of Prolog, everyone was bragging about how many LIPs they were able to process. That's logical inferences per second. But your brain applies many different LIPs ratings depending on how urgent the problem seems to be. The brain is chock full of shortcuts, and orthogonality be screwed. Optimizers cheat, and sometimes they get caught cheating. With this screensaver, you can catch your own brain's optimizer cheating.

[Pedal]

I got to go home for a week before my second surgery. I could even walk around my neighborhood with a portable IV pack on my back. I remember admiring some of the flowers in the neighborhood. They were a welcome sight after the hospital. But, you know, it's really scary getting all your food and water through a tube. Especially the water. I got to be home for my birthday, but I couldn't eat anything. Well, OK, I cheated. I ate one Popsicle, and watched it drain back out of my stomach tube. At least it tasted good.

[Blank]

My second surgery was a success. Eventually. I had to go through the same morphine rigmarole again. At least this time they put in a stomach drain tube so I didn't have to put up with a nose tube. But I had complications again, this time with some internal bleeding. I lost enough blood that they were seriously considering giving me a transfusion. But I squeaked through, and eventually came home. This time I had a feeding tube, which was in some ways an improvement over an IV, and in other ways not. In particular, I was now housebound, because the stomach feeding pump was not as portable as the IV pump. I had to make do with fake foliage on my computer screen.

[Forest]

This screensaver makes use of an ancient technique. If you're working in an opaque medium such as oil paint, draw the background first. Then paint the foreground over that. This may seem like cheating, but we use rules of thumb like this all the time. Every time you do lexical scoping, you're treating the outer lexical scope like a background, and the inner lexical scope like a foreground. That's why it's so natural to talk about an inner variable hiding an outer variable of the same name.

Can you begin to see why I have a special mental relationship with these screensavers? Maybe I'm a little bit crazy, but I can't decide if it's psychotic or neurotic. You know the difference, don't you? A psychotic thinks that 2 + 2 = 5. A neurotic knows that 2 + 2 = 4, but it makes him nervous.

Maybe it's just a simple, everyday obsession.

Eventually, I learned to eat again, and got off my feeding tube. I'll never take eating for granted again. I'll never take tubes for granted again either. Now that I'm out of the hospital, here's what my dreams look like:

[Pipes]

Only they mean something different now.

[Endgame]

I recovered pretty rapidly, physically speaking. But it took months to really get back into gear mentally. Not until this spring did I feel like I was competent to write Apocalypse 12, the one about object-oriented Perl. All in all, I'd estimate that my little medical escapade set the Perl 6 design back six months or so. But Apocalypse 12 was the last big hurdle. With that, the design of Perl 6 can be said to be largely complete.

We are now in the endgame, which is the name of this screensaver. Now that the Parrot engine is in such fine shape, it's time to concentrate on writing a fine Perl 6 compiler to target it.

[Anemone]

Open source projects start out small and grow over time. They send out tendrils in directions you don't expect. Perl started as a text-processing language. Look, now it's a system-administration language. And look over there, now it's a web-programming language, too. Oh, wait, now it's for genomics research.

You'll note sometimes the tendrils withdraw, like a squid's tentacles. That's just the natural process of deciding which things belong in the core. In squid terms, what to eat. Perl has eaten a number of things in the last 15 years. Some of them caused indigestion, but hey, that's life.

You'll notice it's cyclical. All successful open-source projects go through periods of expansion followed by periods of redesign and reintegration. It's a natural cycle. You just have to try and not starve while you're molting. Perl has been molting for a few years now. Or maybe it's been more of a metamorphosis in a cocoon. Anyway, Perl 6 is going to start emerging this year. It's going to be exciting.

[Atlantis]

You might say we're going to have a whale of a time.

The latest National Geographic has an article about squid who change their colors. Often they have reasons for changing, but sometimes I think they just change for the heck of it. A couple of years ago I was snorkeling in the Bahamas, and got to watch a school of cuttlefish swimming along. They weren't hiding or courting or anything like that, but as they swam along they would all change color to brown, then yellow, then red, then green. It's like, "Hey guys, wouldn't it be cool if we all ran the same screensaver at the same time?" Sort of a cultural identity thing, I suppose.

The interesting thing was that while I was watching, they forked. You know, like BSD. One group of cuttlefish went off one way, and the other group went off another. Maybe they had a personality conflict. Maybe they had a fight over licensing. I dunno. But the cool thing was that the moment they forked, they desynchronized their screensavers. This group wanted to stay green, while the other group wanted to go on and try out some purple. Who knows what goes on in the mind of a cuttlefish — it's possible that they split specifically over the color issue. Wouldn't be the first open-source project to split over the color of the bike shed.

I predict that within 10 years, we'll have clothing that runs screensavers, and what's more, we'll have gangs of people running around with synchronized displays to show that they "belong." Schools will then outlaw gang screensavers, and impose uniform screensavers on their students. Someone will hack into your clothes processor just to get you into trouble with the teachers. Norton and McAfee will sell software to make sure your clothes keep saying what you want them to say, and not what someone else wants them to say. Or show...

Or maybe by then your shirt will be able to authenticate all the IPv6 addresses it communicates with. The hard part is going the other way — how are you going to authenticate your shirt to someone else? Are you going to bother to set up an unspoofable identity for every shirt in your closet?

Of course, if your shirt is programmable, you really only need one of them. Or maybe you need two, for when the other one is in the wash. I suppose geeks can get away with owning a single programmable shirt. For some definition of "get away with." Maybe it's more like "get away from," as in "get away from me."

[Molecule (sucrose)]

Anyway, that's another talk. In fact, it's a talk I already gave five years ago. Some of you will recognize this screensaver. It wasn't a screensaver yet when I gave my third State of the Onion talk, but now it is. That's progress. Cool. But watch out for those pheromones. And if you're on a low-carb diet, don't even think about looking at this picture of sugar.

Well, enough about chemistry. I already talked about that once. If I start repeating myself, you'll think I'm getting old. (I am getting old, but I don't want you to think it.) Anyway, you want to hear something fresh. Fresher than a geek's T-shirt, anyway.

In any event, the real geeks will probably just have the screen tattooed on their chest. Or their stomachs. Teletubbies "R" us.

Anyway, back to freshness.

Now, there's two ways one can go about keeping a fresh outlook on life. One way that works, or at least works for some people, is to suddenly change course in midstream. Call it the worms approach.

[Shadebobs]

The problem with worms is that they don't learn much from history. The only history they remember is where they just were, which is where they don't want to be now. I've known some people like that.

The other approach to keeping fresh it to not be quite so, um, random. In other words, learn a little more from history. You can do that either by depth or by breadth. In any case you're keeping more history state around than just a single position.

[Demon, slow]

Software projects have history, and state. Here you see various software projects feeding on the disorder around them. I'd like to think some of them are open-source projects, but doubtless some of the more aggressive ones are closed source.

[Demon, fast]

Over the long term, this is also a view of how dominant species tend to wipe out their smaller competitors. This is also, unfortunately, a picture of where the business world is heading these days. At the rate we're going, we'll end up with just a few large corporate players because right now we have the best government big business can buy. You can see just a few little holdouts that survive in tiny ecological niches only because they're parasitic on the large beasts.

Notice also that nearly all the original information has been destroyed in the name of progress. Archeologists will have to study the leftover crumbs, as they always have. Necessarily, they will over-generalize, just as historians always over-generalize. That's all you can do when too much has been forgotten. Of course, I'm over-generalizing about history here. But screensavers that forget things make me sad.

Speaking of history, I recently got to see Tom Stoppard's play, Arcadia. I should say, I got to see it again. Every time around, I get something a little different from it. It's an iterated algorithm.

For another example, take Perl. Paul Graham has opined (Hi, Paul) that there are a lot of spectacularly original ideas in Perl, but I'd like to correct that impression. There are indeed a few original ideas in Perl, but most of the ideas were stolen. Perl has learned a spectacular number of things from history. Paul was right about one thing, though — some of the things Perl learned from history were spectacularly wrong. That's not to say that some of my original ideas weren't also spectacularly wrong. But hey, that's what iterated algorithms are for. "Release early, release often" is the old phrase. The new catchphrase seems to be "Learning in Public." Same sort of thing.

[At this point I skipped to the final section for lack of time, but you can see the rest of my padding material here.]

[Triangle]

This makes some pretty good-looking mountains. It cheats, of course, compared to how Mother Nature does it. This sort of algorithm doesn't simulate plate tectonics or erosion, so you're not going to get good mountain ranges or river valleys out of it. But our computers are still far too slow to do adequate simulation of all of physics, so we live in an era where "as good as we can do" has to be "good enough." The brute-force approach would often take too long, so our algorithms tend to cheat all over the place. In the case of a fractal landscape like this, that can actually be a psychological advantage, insofar as the artificial landscape comes out with a slightly alien feel, which people seem to like, in moderation.

The problem with exploring oversimplifications, however, is that they're not actually as interesting as real life over the long haul. At least, not individually. Maybe there are enough oversimplifications to explore that they emulate the richness of reality merely by being sufficiently different from each other. Certainly all the books ever written don't add up to the complexity of the universe, since obviously they're a part of it. And yet through the power of imagination, an individual book can give us the impression of worlds beyond our own.

I'm not sure how this relates to Perl, except to say that Perl has always been about being "good enough" rather than "perfect." Good enough is often a lot more interesting than perfect. It's almost as if the imperfections that keep "good enough" from being "perfect" are the very features that make things interesting, because there are a lot more ways for things to go wrong than for them to go right. Even if it's just a little wrong. A lot of these screensavers are a little bit wrong. But they're interestingly wrong.

[Circuit]

I wasn't gonna show this one, but last Wednesday I was suddenly in the state that it looked like I wasn't going to be able to show any of these screensavers. Namely, my laptop completely crapped out. It was too late to send it in for repair and have any hope of getting it back again in time. I didn't have the money to buy a new laptop, nor the time to install Fedora Core 2 on one if I had bought one. I couldn't guarantee that I could find a laptop to borrow that would have Fedora Core 2 on it, at least, not in time to make sure I got these screensavers all lined up in a row. Fortunately, I was pretty sure I knew what was wrong with my laptop, since the power light had been flickering when I wiggled the cord.

So on Thursday I spent all day dismantling my laptop to get at the motherboard. I don't know why they make it so you have to remove everything else before you can remove the motherboard, but that's basically what you have to do. Then I went down to Fry's and bought the teeny-tiniest little soldering iron they sell. I went back home, and I got that motherboard out and I soldered it with the complete expectation that I was probably ruining the motherboard completely. I put it back together again, and only had two extra screws when I was done. I still don't know what they belong to. But it doesn't matter. 'Cause I booted that sucker up, and it worked. And that's the laptop I'm showing you these screensavers on. How many of you have ever tried to solder your motherboard? OK, keep your hands up if the motherboard still worked afterwards. You guys know how I feel right now.

Of course, the joke's kind of on me. It broke again just before I left, and I had to resolder it again last night... I have a great deal of empathy for my computer, having to undergo two surgeries like that...

Many screensavers are based on bouncing balls.

[Pong]

Pong, a classic. The first version didn't even use a computer.

[BouncingCow]

I'm waiting for the version that does a bouncing camel.

[Boxed]

Multiple bouncing balls in a box are a metaphor for community. Notice how the escaping balls explode. This is what happens to people who move from Perl to Ruby.

[Attraction, balls]

Attraction and repulsion. Some people find Perl attractive at a distance and repulsive up-close. Others have just the opposite reaction.

[Eruption]

With small enough balls, you start getting into particle simulations, which are good for flame-like effects. But if you look closely here, you can actually see the little balls bouncing when they hit the ground.

[Euler2d]

Communities are defined by their centers, and often have a fractal quality about them. The people circulating further in are more involved than the people farther out. The insiders say things like, "We need to make Perl 6 the best language for most common tasks." The people further out do not feel absolutely bound to one community or another. They say things like, "Use whatever language is appropriate for the task at hand." The outer people are more likely to drift from one community to another. That's OK. In fact, it's healthy.

When it gets unhealthy is when you start drawing boundaries between communities, and you start being exclusive. Or worse, mandatorily inclusive. Then you start building things like the Berlin wall to keep people inside your community. In anthropological terms, that's tribalism. A tribal Perl programmer might say, "If you leave the Perl tribe to go and join the Python tribe, we will hunt you down, cook you, and eat you." Or if you join the Ruby tribe, you will explode. By and large, I am not in favor of tribalism.

Except for my tribe, of course.

[Here's the ending I skipped to.]

[VidWhacker (camels)]

I could go on and on. There are over 200 screensavers that come with X windows these days. We haven't begun to talk about some of the fancier ones that you can download that do useful work, like searching for extraterrestrial intelligence, or finding new cancer drugs. But the ones I've talked about today are the once I notice in my kitchen when I walk past my Linux box. I notice them, and I think about them, and I think about what they mean. So I hope you're starting to get an appreciation for them.

But I don't think I've really adequately conveyed yet why I wanted to show you these screensavers. Last night, when I tried to explain all this to my family, I suddenly found myself getting rather teary-eyed about it all. It's not so much the fact that the individual screensavers are so interesting. It's really about how they relate to each other, and to the world.

There's been a lot of talk lately about 100-year languages and the like, and while it's fun to speculate on the nature of such long-term enterprises, the history of futurology warns us that the only sure prediction is that all predictions are sure to be inaccurate. The things that are relatively predictable are not fashionable. They're small, but universal. Like screensavers. I predict we'll have screensavers in a 100 years, even if we don't have screens any more, and all our brains take their inputs via neural implants. And those future screensavers will relate to each other just the same way as our screensavers, even if they are different screensavers.

Think about this little program called xscreensaver-demo that I've been using to show you these screensavers. Within this program, all screensavers are considered equal. It's like in a hospital where all the nurses on your floor are considered to be more or less interchangeable. And indeed, they purposefully mix things around so you get different nurses each day. But when they do that, you discover that, in fact, all the nurses are different. All the doctors are different. And they're all wonderful in their own way. Likewise, every screensaver is different, and you can relate to them in different ways.

They are so equal, yet so unequal at the same time. And last night I realized that this was what was important about Perl, and about the Perl community. Not a fancy grammar, or fast engine, or clever optimizer. Those things are all nice, but the heart of Perl the language is all those modules that fit into Perl like interchangeable screensavers, and yet are all so different from each other. And the people who write those modules, and grammars, and engines — they're all equal in the eyes of the Perl community, and yet all so different.

So it was really only last night that I figured out why I had to talk about screensavers tonight. And that reason is you. You're my little flock of screensavers. You're my nurses and my doctors and my patients. You've performed multiple surgeries on my soul, and let me perform surgeries on your souls. We're a hospital of people helping each other, performing random acts of beauty for each other, even when no one is watching but God.

These days I may be missing the bottom of my stomach, but I still have the bottom of my heart. So I would like to thank you from the bottom of my heart for being precisely who you are.

Thank you. Thank you. Thank you.

Perl Command-Line Options

Perl has a large number of command-line options that can help to make your programs more concise and open up many new possibilities for one-off command-line scripts using Perl. In this article we'll look at some of the most useful of these.

Safety Net Options

There are three options I like to think of as a "safety net," as they can stop you from making a fool of yourself when you're doing something particularly clever (or stupid!). And while they aren't ever necessary, it's rare that you'll find an experienced Perl programmer working without them.

The first of these is -c. This option compiles your program without running it. This is a great way to ensure that you haven't introduced any syntax errors while you've been editing a program. When I'm working on a program I never go more than a few minutes without saving the file and running:

  $ perl -c <program>

This makes sure that the program still compiles. It's far easier to fix problems when you've only made a few changes than it is to type in a couple of hundred of lines of code and then try to debug that.

The next safety net is the -w option. This turns on warnings that Perl will then give you if it finds any of a number of problems in your code. Each of these warnings is a potential bug in your program and should be investigated. In modern versions of Perl (since 5.6.0) the -w option has been replaced by the use warnings pragma, which is more flexible than the command-line option so you shouldn't use -w in new code.

The final safety net is the -T option. This option puts Perl into "taint mode." In this mode, Perl inherently distrusts any data that it receives from outside the program's source -- for example, data passed in on the command line, read from a file, or taken from CGI parameters.

Tainted data cannot be used in an expression that interacts with the outside world -- for example, you can't use it in a call to system or as the name of a file to open. The full list of restrictions is given in the perlsec manual page.

In order to use this data in any of these potentially dangerous operations you need to untaint it. You do this by checking it against a regular expression. A detailed discussion of taint mode would fill an article all by itself so I won't go into any more details here, but using taint mode is a very good habit to get into -- particularly if you are writing programs (like CGI programs) that take unknown input from users.

Actually there's one other option that belongs in this set and that's -d. This option puts you into the Perl debugger. This is also a subject that's too big for this article, but I recommend you look at "perldoc perldebug" or Richard Foley's Perl Debugger Pocket Reference.

Command-Line Programs

The next few options I want to look at make it easy to run short Perl programs on the command line. The first one, -e, allows you to define Perl code to be executed by the compiler. For example, it's not necessary to write a "Hello World" program in Perl when you can just type this at the command line.

  $ perl -e 'print "Hello World\n"'

You can have as many -e options as you like and they will be run in the order that they appear on the command line.

  $ perl -e 'print "Hello ";' -e 'print "World\n"'

Notice that like a normal Perl program, all but the last line of code needs to end with a ; character.

Although it is possible to use a -e option to load a module, Perl gives you the -M option to make that easier.

  $ perl -MLWP::Simple -e'print head "http://www.example.com"'

So -Mmodule is the same as use module. If the module has default imports you don't want imported then you can use -m instead. Using -mmodule is the equivalent of use module(), which turns off any default imports. For example, the following command displays nothing as the head function won't have been imported into your main package:

  $ perl -mLWP::Simple -e'print head "http://www.example.com"'

The -M and -m options implement various nice pieces of syntactic sugar to make using them as easy as possible. Any arguments you would normally pass to the use statement can be listed following an = sign.

  $ perl -MCGI=:standard -e'print header'

This command imports the ":standard" export set from CGI.pm and therefore the header function becomes available to your program. Multiple arguments can be listed using quotes and commas as separators.

  $ perl -MCGI='header,start_html' -e'print header, start_html'

In this example we've just imported the two methods header and start_html as those are the only ones we are using.

Implicit Loops

Two other command-line options, -n and -p, add loops around your -e code. They are both very useful for processing files a line at a time. If you type something like:

  $ perl -n -e 'some code' file1

Then Perl will interpret that as:

  LINE:
    while (<>) {
      # your code goes here
    }

Notice the use of the empty file input operator, which will read all of the files given on the command line a line at a time. Each line of the input files will be put, in turn, into $_ so that you can process it. As a example, try:

  $ perl -n -e 'print "$. - $_"' file

This gets converted to:

  LINE:
    while (<>) {
      print "$. - $_"
    }

This code prints each line of the file together with the current line number.

The -p option makes that even easier. This option always prints the contents of $_ each time around the loop. It creates code like this:

  LINE:
    while (<>) {
      # your code goes here
    } continue {
      print or die "-p destination: $!\n";
    }

This uses the little-used continue block on a while loop to ensure that the print statement is always called.

Using this option, our line number generator becomes:

  $ perl -p -e '$_ = "$. - $_"'

In this case there is no need for the explicit call to print as -p calls print for us.

Notice that the LINE: label is there so that you can easily move to the next input record no matter how deep in embedded loops you are. You do this using next LINE.

  $ perl -n -e 'next LINE unless /pattern/; print $_'

Of course, that example would probably be written as:

  $ perl -n -e 'print unless /pattern/'

But in a more complex example, the next LINE construct could potentially make your code easier to understand.

If you need to have processing carried out either before or after the main code loop, you can use a BEGIN or END block. Here's a pretty basic way to count the words in a text file:

  $ perl -ne 'END { print $t } @w = /(\w+)/g; $t += @w' file.txt

Each time round the loop we extract all of the words (defined as contiguous runs of \w characters into @w and add the number of elements in @w to our total variable $t. The END block runs after the loop has completed and prints out the final value in $t.

Of course, people's definition of what constitutes a valid word can vary. The definition used by the Unix wc (word count) program is a string of characters delimited by whitespace. We can simulate that by changing our program slightly, like this:

  $ perl -ne 'END { print $x } @w = split; $x += @w' file.txt

But there are a couple of command-line options that will make that even simpler. Firstly the -a option turns on autosplit mode. In this mode, each input record is split and the resulting list of elements is stored in an array called @F. This means that we can write our word-count program like this:

  $ perl -ane 'END {print $x} $x += @F' file.txt

The default value used to split the record is one or more whitespace characters. It is, of course, possible that you might want to split the input record on another character and you can control this with the -F option. So if we wanted to change our program to split on all non-word characters we could do something like this:

  $ perl -F'\W' -ane 'END {print $x} $x += @F' file.txt

For a more powerful example of what we can do with these options, let's look at the Unix password file. This is a simple, colon-delimited text file with one record per user. The seventh column in this file is the path of the login shell for that user. We can therefore produce a report of the most-used shells on a given system with a command-line script like this:

  $ perl -F':' -ane '$s{$F[6]}++;' \
  > -e 'END { print "$_ : $s{$_}" for keys %s }' /etc/passwd

OK, so it's longer than one line and the output isn't sorted (although it's quite easy to add sorting), but perhaps you can get a sense of the kinds of things that you can do from the command line.

Record Separators

In my previous article I talked a lot about $/ and $\ -- the input and output record separators. $/ defines how much data Perl will read every time you ask it for the next record from a filehandle, and $\ contains a value that is appended to the end of any data that your program prints. The default value of $/ is a new line and the default value of $\ is an empty string (which is why you usually explicity add a new line to your calls to print).

Now in the implicit loops set up by -n and -p it can be useful to define the values of $/ and $\. You could, of course, do this in a BEGIN block, but Perl gives you an easier option with the -0 (that's a zero) and -l (that's an L) command-line options. This can get a little confusing (well, it confuses me) so I'll go slowly.

Using -0 and giving it a hexadecimal or octal number sets $/ to that value. The special value 00 puts Perl in paragraph mode and the special value 0777 puts Perl into file slurp mode. These are the same as setting $/ to an empty string and undef respectively.

Using -l and giving it no value has two effects. Firstly, it automatically chomps the input record, and secondly, it sets $\ equal to $/. If you give -l an octal number (and unlike -0 it doesn't accept hex numbers) it sets $\ to the character represented by that number and also turns on auto-chomping.

To be honest, I rarely use the -0 option and I usually use the -l option without an argument just to add a new line to the end of each line of output. For example, I'd usually write my original "Hello World" example as:

  $ perl -le 'print "Hello World"'

If I'm doing something that requires changing the values of the input and output record separators then I'm probably out of the realm of command-line scripts.

In-Place Editing

With the options that we have already seen, it's very easy to build up some powerful command-line programs. It's very common to see command line programs that use Unix I/O redirection like this:

  $ perl -pe 'some code' < input.txt > output.txt

This takes records from input.txt, carries out some kind of transformation, and writes the transformed record to output.txt. In some cases you don't want to write the changed data to a different file, it's often more convenient if the altered data is written back to the same file.

You can get the appearance of this using the -i option. Actually, Perl renames the input file and reads from this renamed version while writing to a new file with the original name. If -i is given a string argument, then that string is appended to the name of the original version of the file. For example, to change all occurrences of "PHP" to "Perl" in a data file you could write something like this:

  $ perl -i -pe 's/\bPHP\b/Perl/g' file.txt

Perl reads the input file a line at a time, making the substitution, and then writing the results back to a new file that has the same name as the original file -- effectively overwriting it. If you're not so confident of your Perl abilities you might take a backup of the original file, like this:

  $perl -i.bak -pe 's/\bPHP\b/Perl/g' file.txt

You'll end up with the transformed data in file.txt and the original file backed up in file.txt.bak. If you're a fan of vi then you might like to use -i~ instead.

Further Information

Perl has a large number of command-line options. This article has simply listed a few of the most useful. For the full list (and for more information on the ones covered here) see the "perlrun" manual page.

This Week on Perl 6, Week Ending 2004-07-31

As I threatened last week, I'm moving the rollover point for these summaries from midnight on Sunday/Monday to midnight on Friday/Saturday, but rather than do it in one swell foop, I'm doing a couple of six-day weeks. The theory is that once I become a student teacher, I'll be rather busy during the week, but I should still be able to make time to write the summaries on the weekend.

That's the theory, at least; you'll note that this didn't get posted to the mailing lists on a Sunday. Blame my cousin for getting married. It won't happen again.

Pie-thon

Good news! Guido is a gentleman and declined to throw a pie at Dan.

Bad news! The Perl community is a bunch of savages, and they paid $520 to be able to throw pie at Dan.

Good news! There are photos.

http://www.sidhe.org/~dan/blog/archives/000372.html

http://www.oreillynet.com/pub/a/oscon2004/friday/

Notes to Self

  1. American's pronounce "maths" as "math."
  2. Don't make silly cracks about American rectitude.
  3. Oops.

Leo's Proposed Calling Conventions

It's been apparent for a while now that Leo Tötsch isn't happy with Parrot's current calling conventions. This week, he posted a proof-of-concept patch implementing a proposed new scheme. Luke Palmer agreed that it was probably worth consideration. We'll see what Dan has to say when he gets back from OSCON.

http://groups.google.com/groups?threadm=41063ACB.2040208%40toetsch.at

Stack-Based Language

RaghavendraK asked about the difference between stack- and register- based virtual machines. Brent Royal-Gordon gave good advice.

http://groups.google.com/groups?threadm=13d2515bd8.15bd813d25%40huawei.com

ICU Outdated

Joshua Gatcomb noted that the ICU that comes with Parrot is, not to put too fine a point on it, old and buggy. The ICU developers have suggested that Parrot move to version 3.0. Josh proposed various ways of doing this. Leo wants ICU out of the Parrot CVS, but Dan's argued in the past that it should be in there because he doesn't want to force people to chase around fetching a raft of required libraries before they can build Parrot.

http://groups.google.com/groups?threadm=20040730183121.54027.qmail%40web60804.mail.yahoo.com

Jarkko Proposed for CVS Check-In Rights

Following a raft of high-quality patches from Jarkko Hietaniemi, Leo proposed him for membership of the cvs ci club.

http://groups.google.com/groups?threadm=410BE8B4.7030103%40toetsch.at

Meanwhile, in perl6-language

What's Core?

Larry and Dan Hursh discussed what would be going into the standard Perl 6 distribution. Dan argued that we should be concentrating on producing a distribution akin to the current Perl 5 distribution, but with a few fewer kitchen sinks. Larry argued that we should concentrate on two distributions:

  1. Bare bones: just able to build itself and with enough capability to bootstrap everything else.
  2. Extended: The barebones system plus a set of libraries fetchable from CP6AN that constitute the Perl 6 "supported" library; modules that are maintained by the Perl 6 equivalent of perl5-porters, and which will be supported over a long timeframe.

I don't think Dan's been convinced yet. Elsewhere in the thread, Luke Palmer coined the delightful acronym EYEWTIBWATA -- Everything You Ever Wanted To Install But Were Afraid To Ask -- or "eye-witty-bwattle." I'm unsure about whether it's going to rank up there with "tim-toe-tidy," though.

http://groups.google.com/groups?threadm=20040725063231.33578.qmail%40onion.perl.org

Announcements, Apologies, Acknowledgements

I'm getting bored of typing "Palmer" and "Tötsch" once a week, so I'm considering treating Luke and Leo like Larry, Dan, Damian, and, if you insist, chromatic.

So, if you find these summaries useful or enjoyable, please consider contributing to the Perl Foundation to help support the development of Perl. You might also like to send feedback or contributions to a "getting Piers to OSCON 2005" fund to

http://donate.perl-foundation.org/ : The Perl Foundation

http://dev.perl.org/perl6/ : Perl 6 development site

Visit the home of the Perl programming language: Perl.org

Sponsored by

Monthly Archives

Powered by Movable Type 5.13-en