I bought Stephen Fry's book The Ode Less Travelled yesterday, as it gives a thorough but approachable introduction to prosody ("the art of versification"). It contains technical descriptions and exercises to introduce the various elements of poetry: so far, I've been learning about metre, feet, iambs, iambic pentameter, enjambment and caesura. Some of this stuff I covered in my English A Level, but surprisingly little: I think it had gone out of fashion at the time I was studying English. Even in my English Literature degree, I didn't cover the technicalities in any great detail. It's certainly interesting, and I'm hoping it will help me make more informed analyses of other people's poetry, and make me appreciate the benefits of using traditional poetic forms and approaches.
So my creative output today was in response to the first exercise in the book: writing 20 lines or pairs of lines in iambic pentameter (ten syllable lines with a ti-tum ti-tum ti-tum ti-tum ti-tum rhythm, i.e. a stress on every even-numbered syllable). I managed 15, some of which match the requirements, but not all (I always found detection of stresses difficult). It's surprisingly hard to write like this, as it forces you to make certain choices about the first word on a line (it can't have a stressed first syllable). Here are my attempts:
A cough, a sneeze, before we wake for food.
The written word so rarely read this well.
I'm pretty sure the second line is wrong.
The broken record turns about itself.
My mother drinks a glass of bitter beer.
Before the dawn was brighter than we thought.
Perhaps gorillas wander to and fro.
We watch their shiny bottoms come and go.
The crazy cops are seeking someone bad.
A shot, a shout, a scattered crowd of folk
Derides the nonsense spouted by a priest.
The telly always offers us its crap.
Consider if you will the elephant.
More adverts disappear us as we stare.
Aghast, he saw his picture on the floor.
He fell upon them, crying out in fear.
A picture frame is seldom red, it seems.
They borrow chairs to fill the empty hall.
This is a rewrite of a poem I wrote a long time ago. I submitted it to Urbis, and got a couple of comments, and thought I'd take a crack at taking them on-board. Most of the comments centred around it being too verbose, with too many irrelevant details, so I pulled it to pieces for about 30 minutes, and still wasn't happy at the end. I thought it might be interesting to show the two pieces together, which perhaps gives some idea of the process I went through. The new version isn't finished (that's why I'm struggling), but I am happier with it than the original.
With a pad of paper against her knee
(The writing smudged) she looks at the camera.
He inhabited this room for three months
With American footballers on the curtains
(Although he was 21).
She visited twice, once bringing shepherd's pie
He upset her perhaps this day
By not walking her to her car.
She is looking at the camera, seated on the bed,
With him taking the picture in black and white:
Her smile is almost goofy
Above a hint of double chin;
One eye slightly askew, just to the left.
No one saw this but him.
The time spent with her is extrapolated from here,
Her blonde light grey hair untidy,
Her blue green dark grey eyes like wounds,
Her white teeth like half a melon skin.
With these tools, he tries to make rooms
She isn't in.
He captures an image
of her on the bed.
Later,
he sulks;
won't walk her
to the door.
The image
polarises:
sheaves of straw-blonde
light-grey hair;
wounds of blue-green
dark-grey eyes.
This is actually a rewrite of an ancient (1991?) poem. Me, rewriting? I hardly ever used to do this, but am finding that time is giving me objectivity about some of my older stuff, which I can use to make improvements. Hopefully.
the sea is in bed
the sky its sheet
the beach tautens
the sea touches the horizon
it shies
like a touched thigh
we ache for the place
where one
is tucked
into
the other
Pastoralia is a fantastic short story book I finished this morning. Highly recommended - one of the funniest things I've ever read. His writing style really captures the hesistancy, mistakes, bad thoughts that everyone (well, me, anyway) experiences but never articulates. The characters are vibrant, unhinged, but realistic, the ideas slightly off-the-wall but always familiar, the humour black and satirical.
I wrote this on the back of a magazine on the bus this morning. Nothing fully-formed, but a few ideas and images.
By the way, I managed a whole month (31 days) of writing something (nearly) every day. It's been a great experience for me so far, and has really started perking up my creativity. Some of the stuff I produced was even half-decent.
A woman and man about to cross a Pelican crossing, the woman grasping the man as if to say, "Don't leave me, don't ever leave me, I need you."
Girl in herringbone-patterned coat reads a novel. In the margin of one page, she or someone else has written, in capitals the length of the page, "L AND G DREAM".
I had to take out the rubbish. It was about 3 miles to the dustbins, up-hill, along a path with a wire fence running its entire length. In a moonlit playground a child described hesitant white arcs with the swing. When I got to the dustbins, they were overflowing.
A stern woman in long black coat with glasses and purple-grey hair.
The bus driver's son sometimes gets onto the bus when I do. He barely acknowledges his dad. Sometimes his dad will remind him to be home on time, or to ring when football practice finishes, and the boy merely grunts and inclines his head, away from his father.
A story about a cobbler, or someone who works in a computer hardware shop. These are things I know about.
The birds have made shoddy nests, gingerly cradled in the white arms of a birch.
A man like an untidy heap of box files waits for a bus.
The BBC are seeking feedback from the public about how their proposed on-demand services should be structured and regulated. There's a document about it on their website which outlines the original proposals, plus how they were toned down by Ofcom to make them more constrained and less useful to licence-fee paying households. I understand people getting jitters about competing unfairly in the marketplace (e.g. entertainment companies which produce CDs and DVDs losing custom because ITV provides downloads). But in the case of the BBC, I'VE ALREADY PAID FOR THE CONTENT (yes, I feel the need to shout). I pay my licence fee, like most other people in the country, and have already funded production of the BBC's programmes. Why should I pay again for a DVD? Why can't I download dramas etc. which I've missed, for free, forever?
It's really important if you live in the UK that you participate in the BBC's Consultation on On-Demand Services. and make your case. I basically went on about the above in my response, plus highlighted that I didn't want DRM, I wanted everything available forever for free, and I wanted it on my Linux laptop. I tried not to sound like a free software maniac and make reasoned arguments with examples. We need as many people as possible to participate in this, otherwise we'll end up with another crippled, inaccessible on-demand service (4od, anyone?). When are the media going to wake up and give people what they want?
Update: I've toned this down and made it as objective as possible, as I felt I was unfair and perhaps intolerant in the original version.
I remember watching a documentary a few years ago on Scientology, where they attempted to show it up as a money-making scam, and made some convincing arguments, backed-up by evidence. I've never been able to understand its popularity, as L. Ron Hubbard (its originator) was a second-rate science fiction writer at best. I remember reading some critique of his ficion (maybe in Trillion Year Spree by Brian Aldiss?) which pointed out that Mr. Hubbard was an old school sf writer, who got paid by the line: therefore he wrote lots of very short sentences. Bad ones, at that. (By the way, I have attempted reading some of his stuff, and it was so truly awful I gave up.)
Today, I was browsing wikipedia to find out about juche, which Nicola mentioned and we'd never heard of (it's not a religion, as such, but the state ideology of North Korea). While I was there, I looked up Scientology, which Nicola also mentioned. I found a few things which further confirmed my views of Scientology:
Looking objectively at it, maybe few of these ideas are any crazier than Christianity, those of Jehovah's Witnesses, etc.. I also feel uncomfortable criticising other people's beliefs: it would be nice to be better informed about Scientology. However, it's difficult to get at the core texts as they are copyrighted and actively protected; to get at the meat of their ideas you have to pay money; and I don't have the time or the inclination to visit one of their churches, as the ideas seem unbelievable to me (in the same way that those of Christianity, Islam, Judaism etc., in fact any organised religion, do). As Hubbard himself stated in a 1952 lecture: he's "trying to tell you a fairytale" (5203C04B, 1952 Phoenix lecture 2101).
I should qualify all this by saying that, while I am not religious, I defend the rights of anyone else to practice any religion they choose. The thing I'm struggling with at the moment is how far the rights of any religion should be supported when they start to infringe on the freedom of others. I think there is a strong case, supportable by evidence from ex-Scientologists, to show that Scientology (in general, and at its heart) goes too far in terms of extremism, exploitation and intolerance. (Having said that, see the comments for a response from a practicing Scientologist who is actually fairly reasonable.)
How could I get to the age of 36 and never have heard Silver Apples? They are surely marvellous. The lead singer is called Simeon, and he plays an instrument with the same name. Get their first and second LPs on a single CD, it's brilliant stuff.
How come I've been using Linux all this time and never got round to using F-Spot? It's already crashed on me once, but the red-eye reduction tool alone makes it worth using.
A long time ago I posted to Slashdot about The 8 Bit Construction Set distributing software on vinyl. Their music is great and programmed in assembler: you can buy a 12" of their stuff (God knows where) or download it from The Beige Website.
I only mention it because I was listening to their music today. I remember at the time I posted to Slashdot their website fell over for a long time (presumably "slashdotted"). I felt very guilty and wondered whether I had maybe caused them enormous bandwidth bills. Would I be the cause of Beige Records going bankrupt? I looked again today and was relieved to see they survived (arrogant of me to think they wouldn't). I also noticed the 8 Bit Construction Set had added a response to the Slashdot story. They acknowledge they probably weren't the first to do it. Funny, I haven't looked at Slashdot for ages.
No Ruby Tuesday this week, as I've not been Ruby programming. Instead, I've been having a look at the Symfony PHP framework, to see whether it shapes up to Rails. As I've stated previously, Rails is a pain to run on dirt-cheap hosting (though options like Planet Argon are out there, cheap enough, but I haven't tried them yet); plus Ruby is another language to learn for the people I work with at OpenAdvantage, and most of them have got enough to do running small businesses. I wondered whether Symfony is good enough to recommend as an alternative to Rails for programmers who already know PHP.
In short: it is.
It's not perfect, not as concise as Rails, and lacks many of the features. But using it is a damned sight easier than writing a PHP application from scratch. I'm not going to do a thorough feature listing (see the Symfony site for that). Instead, here are some of the notable things about it that improve the life of PHP programmers:
Next, a few specifics and code samples to give an idea of how it works.
I chose a wiki as the project to experiment with, and have spent about a day and a half coding in Symfony. The result (fancifully called Flow My Thoughts, The Policeman Said) is an extremely simple wiki which supports camel-case links, [[]] links and Textile markup.
For the wiki parsing part of it, I borrowed some code from the Drupal freelinking module and from TextilePHP. Along the way I fixed TextilePHP so that it works properly with strict error reporting on (there were lots of references to unset variables and possibly non-existent array indexes which meant I got around 100 error messages the first time I ran it). This means I can write wiki links as well as mix in Textile markup (I am a big fan of Textile). Don't you just love open source?
For the main part of the project I started with the Symfony sandbox download, as this includes all the libraries for Symfony in a tarball. You can also install the dependencies with PEAR, and would want to if using Symfony for several projects. I also went with SQLite for experimenting with.
First off you edit a schema.yml file with details of your data model. This works pretty well, and is a bit like writing a migration. You can either use the sensible Symfony defaults or work with the Propel syntax directly (e.g. if you want specific options or indexes set for fields). My model looks like this:
propel:
page:
_attributes: { phpName: Page }
id:
title: { type: varchar, size: 255, index: unique }
content: longvarchar
created_at:
updated_at:
Nothing too unusual there. Also notice the "magic" Rails-style fields, created_at and updated_at.
To build the model classes from your schema, you run:
php symfony propel-build-all
The symfony file is a Pake build script. The propel-build-all task generates some XML from your YAML files, which gets converted into PHP classes representing your tables. In my case, I got four files: BasePage, BasePagePeer, Page, PagePeer. Then it generates some SQL and builds your database. All very migration-like. However, there's no sense of "up" and "down" in Symfony, and it's probably hard to version the database schema incrementally, like you can in migrations.
As I mentioned above, the PHP classes are chock-full of getter and setter methods. Far more wordy than ActiveRecord's default two-line class definitions, and a consequence of the lack of runtime class extension in PHP. However, only the Base classes (in my case, BasePage and BasePagePeer) are regenerated when you recreate the model using Pake. This means you can add your extensions into the classes which inherit from the Base classes (i.e. Page and PagePeer).
Symfony supports generation of a CRUD interface (i.e. scaffolding) from the model too:
php symfony propel-generate-crud frontend page Page
This actually creates an application called "frontend" inside your app. directory. This is interesting, as it illustrates how Symfony applications can be structured into parent-child relationships, unlike Rails where it's pretty flat.
You can get at your application in development mode by browsing to (e.g.) http://localhost/frontend_dev.php/page. This will use the default views for the CRUD interface.
The scaffolding sits inside the frontend application, and can be used to selectively override the defaults for the application. I added some directories to my page module:
apps
frontend
modules
page
actions
lib
helper
templates
validate
Note here that I can either add helpers for the module, or I can place them under frontend > lib > helper to add them to the whole application. This mirrors the distinction between application level and controller specific helpers in Rails, but is reflected by the directory structure, rather than by file naming. This seems unnecessarily complex, particularly if you're used to Rails. The other directories are fairly obvious, hopefully.
Routing is one area which had me foxed. I wanted to be able to use a URL like this:
http://localhost/wiki/page/NameOfMyPage
to be able to navigate to the page with the title NameOfMyPage. However, I couldn't for the life of me get this to work. In the end I had to settle for:
http://localhost/wiki/page/show/title/NameOfMyPage
Note that the link_to helpers are a bit unwieldy compared to Rails, particularly as you don't have the luxury of symbols and automatic hashes from arguments like you do in Ruby:
echo link_to($page_title, 'page/show?title='.$page->getTitle());
Even though this is only slightly more opaque and verbose than Rails, I think it would wear on me after a while.
The scaffold specifies the actions you'd expect by default: for the page model, they ended up in apps/frontend/modules/page/actions/actions.class.php. Adding my own was simple enough. For example, I wanted to show a page by title. Showing a page by ID was supported by the scaffold already:
public function executeShow() {
$this->page = PagePeer::retrieveByPk($this->getRequestParameter('id'));
$this->forward404Unless($this->page);
}
Mmmm, not quite as succinct as Rails, I was thinking. You can see the Torque-style (Propel) syntax for retrieving records in the first line of this method definition. Note that the template to render is implicit, and maps to apps/frontend/modules/page/templates/showSuccess.php.
First, I added a new method to the PagePeer, to retrieve a record by title. This is located in lib/models/PagePeer.php, outside the application. The idea is you are likely to have multiple applications supporting a single model. On the other hand, it's probably possible to create models specific to individual applications (maybe even modules):
public static function retrieveByTitle($title) {
$c = new Criteria();
$c->add(self::TITLE, $title);
return self::doSelectOne($c);
}
The Criteria class used here is part of Propel, and it works pretty well (again, very Torque-like). Though again, more verbose than ActiveRecord. (Thanks to Scott Meves' comment which cleaned up the above function.)
Then I added an action to frontend/modules/page/actions/actions.class.php:
public function executeShowByTitle() {
$this->page = PagePeer::retrieveByTitle($this->getRequestParameter('title'));
$this->forward404Unless($this->page);
$this->setTemplate('show');
}
Notice that this reuses the 'show' template (setTemplate() specifies the one to use if different from the inferred template).
I created my own helper to show error messages in apps/frontend/lib/helper/ErrorMessagesHelper.php:
<?php
function error_on($field) {
$error = sfContext::getInstance()->getRequest()->getError($field);
$out = '';
if ($error) {
$out = content_tag('div', $error, array('class' => 'error'));
}
return $out;
}
?>
Notice how I had to go round the houses to get at the error messages on the object. For some reason, error messages aren't stored on the object, but in the request. This makes them pretty hard to get at, and you have to use the Symfony context if you are not explicitly within a view. Also notice that there is a content_tag helper.
I can load this my helper into a template with:
<?php use_helper('ErrorMessages') ?>
Nothing special here. Just HTML with PHP, plus some PHP helpers to make life a bit easier. For example, here's my edit form for pages:
<?php use_helper('Object') ?>
<?php use_helper('ErrorMessages') ?>
<?php echo form_tag('page/update') ?>
<?php echo input_hidden_tag('id', $page->getId()) ?>
<p><strong>Title</strong>
<?php echo object_input_tag($page, 'getTitle', array('size' => 80)) ?>
<?php echo error_on('title') ?>
</p>
<p><strong>Content:</strong><br/>
<?php echo object_textarea_tag($page, 'getContent', array('size' => '80x10')) ?>
<?php echo error_on('content') ?>
</p>
<hr />
<?php echo submit_tag('save') ?>
<?php if ($page->getId()): ?>
<?php echo link_to('delete', 'page/delete?id='.$page->getId(), 'post=true&confirm=Are you sure?') ?>
<?php echo link_to('cancel', 'page/show?id='.$page->getId()) ?>
<?php else: ?>
<?php echo link_to('cancel', 'page/index') ?>
<?php endif; ?>
</form>
I could have used the short PHP <?= ?> syntax to make this less verbose, but went with the most portable syntax. Note that there are equivalents for Rails' form_remote_tag etc..
Validation is set up in YAML files (reminds me of Struts). For example, I wanted to make sure that both title and content are set for a wiki page. To validate an action, you have to add a YAML file named after the action: in may case, I wanted to validate the update action, so I added apps/frontend/modules/page/validate/update.yml:
methods:
post: [title, content]
fillin:
enabled: on
names:
title:
required: yes
required_msg: 'Please enter a title for the page'
content:
required: yes
required_msg: 'Please enter some content for the page'
Again, not as nice as Rails, but more declarative, perhaps. The fillin option has to be enabled for auto-form-population to be turned on.
I haven't mentioned the testing framework which is built into Symfony, as I didn't use. Note also that it supports separate development and production environments, like Rails, but they run concurrently: you access the development environment through a modified URL, rather than by running the application in a different mode. That's quite nice.
Another feature I liked is the console you get in development. This shows you log messages pertinent to the page, the SQL queries run, and general stuff about the environment, presented as an AJAX-ified menu across the top of the app.. I'd love to see something like this in Rails.
I started putting Ajax into the application, but in-place editors don't work very well with wiki pages (you need to be able to click on links in the page when a page is displayed, but the in-place editor turns the whole page into a clickable field which displays an edit form, as in Rails). So I abandoned that. I also experimented with using the TITLE field as the primary key instead of ID (use of ID fields is encouraged in Symfony, as in Rails), but this was hard work, so I went back to IDs. I also didn't get round to authentication.
That's as far as I went with the application, and I'm unlikely to go further. I've attached it to this post for anyone who's interested (licence is GPL).
I put these few samples of Symfony code up to give a flavour of the differences and an impression of how it feels for a Rails programmer. It is not a thorough or complete evaluation. Try it for yourself. I have to say that the tutorial on the Symfony website is pretty good; and you can also get a full book on Symfony from the site (or a print version). (Come on DHH and Dave Thomas, when are we likely to see Agile Web Development for Rails given away? I've already bought it twice.)
Symfony has a lot going for it. It's pretty easy to get up and running. But by contrast with Rails, it is very verbose because of how PHP works. On the plus side, it is similar enough to Rails to make it fairly easy to transition to; and you can run it on normal web space at high speed without having to fork out for special hosting. That last point is very important to my mind. Coupled with the fact that there are lots of PHP programmers out there already, or Java programmers looking for a lightweight framework but scared of Ruby, and I can see it growing at a reasonable pace. I would certainly consider it if I needed to write a scalable web application for myself; I've even considered rewriting Flickrlilli using it, to see if it makes a difference and to get a better comparison. You never know...