Blogs about perl

October 16, 2008

Perlbuzz

ActiveState joins the Parrot Foundation advisory board: What does that mean for Parrot and Perl 6?

Allison Randal sent me this press release:

ActiveState, commercial provider of tools and support for dynamic languages, has joined the Parrot Foundation's advisory board.

The Parrot Foundation advisory board is made up of a select group of companies who can offer perspective and experience on the current and future applications of the Parrot virtual machine and related language implementations. The advisory board is a channel for its members to share in the development of the project and contribute feedback on features, languages, and tools to aid in focusing development efforts on areas of greatest impact.

"ActiveState has been working successfully with dynamic languages and the various communities for over 10 years ," said Bart Copeland, CEO of ActiveState. "Our company was built on open source and we're proud to support the Parrot Foundation as a member of the advisory board."

Allison Randal, chairman of the Parrot Foundation, added, "ActiveState has been a steady community partner to open source dynamic languages like Perl, PHP, Python, Ruby, and Tcl. As we prepare for the 1.0 production release of Parrot, we look forward to working with ActiveState, benefiting from their extensive experience supplying enterprise customers with professional solutions for developing and deploying dynamic language applications."

What does this mean for Parrot? Will there be ActiveParrot? Are they going to contribute bodies? I don't know, but I'm going to ask Allison, and if you have questions, I'll round them up and ask her those as well. Ask your questions in the comments and I'll try to get answers within the next week.

by Andy Lester at October 16, 2008 10:03 PM

Write your code like it's going on CPAN

By Chris Prather, from his recent blog entry

One of the things I’ve discovered recently, and wished I’d known years ago is you need to write all your Perl applications like you were gonna be posting them to CPAN, even if you have no intention of ever doing so.

At work we are starting to migrate from a legacy system that was written in the grandest of late 90s CGI (the code is clear, easy to read and for this era of script well documented, but lacks any architectural cohesion and has been patched and re-patched over the years to handle new use cases). This system is absolutely core to our daily business. You might even argue that it is our daily business.

One of my tasks was to add Validation on some of the input parameters. My boss wants to move to something testable so I created a Validation module that contained a bunch of validation functions for the various pieces of data, and when we could easily do so we wrapped CPAN validation modules (Regexp::Common we love you!). This however added a couple of new dependencies to our system. This is where writing it like a CPAN package comes in.

I added a Makefile.PL for the system. We have no intention of ever releasing this code, but the Makefile.PL uses Module::Install and lists the dependencies. The magic of this is that for recent versions of cpan you can just type cpan . and it will automatically install all the dependencies for the current directory. Failing that you can always run perl Makefile.PL && make && make test and it’ll install dependencies and run your test suite.

By treating code we were never going to release to CPAN as if we were, we win the support of all of the CPAN toolchain. A toolchain that is getting better every day.

Chris has worked with Perl for 7 years in 3 time zones. He's responsible for Bender on irc.perl.org, and MooseX::POE. He is happy to be back in Florida where it is warm.

by Andy Lester at October 16, 2008 12:28 AM

October 15, 2008

blogZero

BarCampDC2

barcampdc barcampdc This Saturday, October 18th, 2008 Washington, DC area Web Developers will meet for the 2nd annual BarCampDC "unconference" at the Center for Digital Imaging Arts (CDIA) at Boston University's, Washington, DC Campus (in Georgetown, see the wiki for more information).

Brave souls may opt to drive, but personally I would rather use the Metro. On a recent excursion to Georgetown I took the time to scope out a pleasant (and shorter) walk from the Foggy Bottom station to the Foundry Building. The route takes you around Washington Circle, up Pennsylvania Ave., down to Rock Creek Park and west on the C&O Canal towpath.

If you are attending and plan on bringing your camera, consider joining the BarCampDC Flickr group and tag your photos "BCDC2." For more information on the BarCamp movement, visit the BarCamp wiki.

by Douglas Clifton (dwclifton@gmail.com) at October 15, 2008 07:48 PM

Perlbuzz

Using HTML::Table::FromDatabase

By David Precious

A task I find myself doing reasonably often when programming is producing a HTML table based on the result of a database query.

This often ends up with the same kind of boring code being written again and again, which get tedious.

For example:

print <<TABLESTART;
<table border="1">
<tr><th>id</th><th>foo</th><th>bar</th></tr>
TABLESTART
 
my $sth = $dbh->prepare(
    "select id, foo, bar from mytable where something = ... "
);
$sth->execute() or die "Failed to query";
 
while (my $row = $sth->fetchrow_hashref) {
    print '<tr><td>';
    print join '</td><td>', @$row{qw(id foo bar)};
    print "</td></tr>\n";
}
print "</table>\n";
$sth->finish;

Not hard, but it does get tedious.

HTML::Table makes things better by taking out most of the HTML drudgery, but you still need to loop through adding rows to your table.

This is where my HTML::Table::FromDatabase comes in - it’s a subclass of HTML::Table which accepts an executed DBI statement handle, and automatically produces the table for you.

For instance:

my $sth = $dbh->prepare(
    "select id, foo, bar from mytable where something = ..."
);
$sth->execute() or die "Failed to query";
 
my $table = HTML::Table::FromDatabase->new( -sth => $sth );
$table->print;

Much easier, and HTML::Table::FromDatabase does all the tedious work.

Sometimes that won’t be quite flexible enough though; you might have something you want to do to certain columns or values before outputting them.

That’s where HTML::Table::FromDatabase’s callbacks come in handy. For a basic example, let’s say that one of the columns you’re fetching contains URLs, and you want to wrap them in anchor tags to make them clickable links. Simply done with:

 my $table = HTML::Table::FromDatabase->new(
    -sth => $sth,
    -callbacks => [
        {
            column => 'url',
            transform =>
sub { $_ = shift; qq[<a href="$_">$_</a>]; },
        },
    ],
 );

Another example - looking for all cells whose value is a number, and formatting them to two decimal places:

 my $table = HTML::Table::FromDatabase->new(
    -sth => $sth,
    -callbacks => [
        {
            value => qr/\d+/,
            transform => sub { return sprintf '%.2f', shift },
        },
    ],
 );

You can apply as many callbacks as you need.

As HTML::Table::FromDatabase is a subclass of HTML::Table, all of HTML::Table’s options can still be used to control how the generated table appears, for example:

  • -class => ‘classname’ to give the table a specific class to help you apply CSS styling
  • -border => 1 to apply borders, -padding => 3 to set cell padding
  • -evenrowclass and -oddrowclass if you want to have different styling for even and odd rows (e.g. alternating row backgrounds).

The full list of options can be found in the HTML::Table documentation, I’m not going to duplicate it all here.

Currently, the row headings used in the generated table are taken from the column names in the query, but I plan to release a new version sometime soon which allows you to alias them, if you want to do so.

(The code samples in this post are intentionally kept relatively simple, omitting obvious things like connecting to the database first, error checking etc).

David Precious is a professional Perl developer, currently working for a UK web hosting company. He has released several modules on CPAN, and contributed to a number of other Open Source projects. He's also a keen motorcyclist, and has a fondness for beer.

by Andy Lester at October 15, 2008 12:57 PM

October 14, 2008

blog.mignault.net

Perlbuzz

Plain Black puts five years of conference video online as WebGUI TV

Plain Black, the guys that put out WebGUI and give out the purple octopi at YAPC and OSCON, have put five years of WebGUI conference videos online at www.webgui.tv.

Tavis Parker of Plain Black writes:

WebGUI TV (WGTV) is a free video library containing archival footage of past WebGUI Users Conference presentations, as well as videos from other training resources. Close to 150 videos on all topics related to WebGUI are currently available, and the collection will continue to grow!

Perl developers will be pleased to hear that WebGUI TV includes several presentations on topics such as basic Perl programming, object-oriented Perl, WWW::Mechanize, Test::More, and mod_perl development. These topics are very relevant given that WebGUI is the most comprehensive and widely used Perl content management system available. Aside from being a popular CMS, WebGUI has also become a widely used application framework for building web apps.

To learn more about WebGUI TV, read JT Smith's announcement in The Black Blog.

Most of the videos seem to include the slides for download, too. Many of the talks are about WebGUI itself, but there's Perl-specific content, like Chris Dolan talking about Perl::Critic, Writing with YUI and so on.

Thanks to JT & co. for making this available. I've been to so many conferences where there are cameras around, and you just hope that the video will get uploaded, and it rarely does, and certainly not as complete as this archive.

by Andy Lester at October 14, 2008 05:00 AM

October 13, 2008

blog.mignault.net

Recent twits

  • Back at the office. Yay. #

Powered by Twitter Tools.

by jbm at October 13, 2008 03:59 AM

blogZero

So What Else is New?

totem icon This blog isn't the only thing that has been languishing around here. After adding a new category to my resource index and populating it with 30 new resources I realized I had finally reached the 1000 review milestone.

Time to break out a bottle of the bubbly? Actually, I prefer San Pellegrino, especially the citrus flavored varieties like Aranciata (orange) and Limonata (lemon). Alas, I digress.

dcphp Last week we had large turnout for the October DC PHP Developers Group meeting, which featured a presentation on optimizing MySQL by Barry Austin of doBoard. Below I list some comments and my own suggestions on the topic.

MySQL Rules of Thumb
  • Keep your columns as small as possible and always use an unsigned (tiny,small,int,...) AUTO_INCREMENTing primary key on your main tables.
  • Foreign keys on secondary and ternary tables must match the PK size and type.
  • Avoid text and blob columns when possible and consider using the filesystem instead.
  • Fixed length character fields are faster, at the expense of storage space. Disk space is cheap folks! However, smaller tables fit better in the buffer pool and reduce disk I/O.
  • You cannot mix fixed and variable length (varchar, text, etc.) fields in MyISAM tables.
  • Use the appropriate storage engine for the data you're storing/manipulating. For example, InnoDB tables are faster at FULLTEXT searches than MyISAM.
  • Careful indexing pays big dividends.
  • Columns in your WHERE, GROUP BY or ORDER BY clauses are good candidates for indexing, not the ones you SELECT.
  • EXPLAIN is your friend. Learn it, understand it.
  • Columns with a high cardinality in relation to the number of rows in the table are also good candidates for indexing.
  • Whenever possible, use MySQL query functions to sort, filter and manipulate your data rather than using PHP (or whatever language you prefer).
  • Although the MySQL optimizer will do this for you, I always try to code my queries to eliminate as many rows as possible as soon as possible.
  • If you're running MySQL 5.0.37 or above, the MySQL Query Profiler is a cool new tool.
  • Subqueries are powerful, but proceed with caution and consider rewriting slow subqueries as joins.
  • The slow query log can help isolate problems you when your application seems sluggish, but enable it on a development server under a simulated load rather than on a live production server.
  • I disagree with the assertion that enum types should be avoided. They are handy for mnemonic reasons and are actually stored internally as unsigned integers. A enum column with 256 or fewer members occupies only one byte of storage. However, they should be carefully thought through during the design phase to avoid changes later. Example, a five star rating system: enum('fail','poor','fair','good','best').
  • Every RDBMS course hammers home data normalization. I agree with avoiding redundant data, but queries with multiple nested JOINs can bog down your application.
  • Remember, denormalization involves flattening out your tables only after they are in 3NF. Also consider vertical or horizontal table partitioning.
  • Writes (INSERT, UPDATE, REPLACE) normally have a higher priority than SELECTs. For tables (like hit counters) that involve frequent updates, consider using the DELAYED keyword to place those requests into a queue. Doing so allows the client to proceed before any write takes place. The downside, of course, to this is your reads are not necessarily real time.
  • Of all the skills a Web developer must face, your DB and the backend are easily the most critical and complex. Taking the time to educate yourself is vital and well worth the effort, especially for large-scale applications.
  • Finally, the MySQL online reference manual has a wealth of information on optimization. Spend some time with Optimizing SELECT and Other Statements.

by Douglas Clifton (dwclifton@gmail.com) at October 13, 2008 03:54 AM

October 11, 2008

Perlbuzz

Pittsburgh Perl Workshop 2008 is underway

John Cappiello writes:

So far I am enjoying the hallway track as always. Buglabs was semi interesting, but the business / product seems impractical, Rx talk by Ricardo Signes was both entertaining as always, and hopefully an informative piece to some, as it's quite an interesting product.

There's only one track today, so talks are limited. I'll send more info as it comes along, and I have more conference photos to be uploaded to Flickr already. They're all tagged ppw2008.

Any other reports from the field? Link to them in the comments!

by Andy Lester at October 11, 2008 06:04 PM

October 09, 2008

Perlbuzz

What's up with SPF?

Writing about Pobox reminded me of Meng Wong's SPF anti-spam system. I've heard nothing about it recently, and a check of openspf.org shows Latest News from June 2008 and April 2007.

What's the health of the project? Are people using SPF? Is it effective? Should I bother updating (fixing, really) the SPF records I added years ago?

by Andy Lester at October 09, 2008 02:54 AM

Flash in the pan, Internet scale

The lovely & talented Ricardo SIGNES on his employer:

I work for Pobox. We provide identity management. For the most part, it's about email. You register an email address with us and we handle the mail for you. We send it to an IMAP store, or your current ISP, or some flash in the pan webmail provider like Google.

by Andy Lester at October 09, 2008 02:44 AM

October 08, 2008

blog.mignault.net

October 07, 2008

blog.mignault.net

Jabbering Giraffe

mod_perl 1 blows chunks

At $WORK, I’m looking at a web service built on mod_perl 1 / Apache 1. The service takes XML as input and returns XML as output. So far, so good.

Unfortunately, whilst I was testing with curl, I found something odd:

  curl -s -v -T- -H'Content-Type: text/xml;charset=UTF-8' http://localhost/api < input.xml

That -T- says to do a PUT request from stdin. It fails and my code returned “no input”.

But when I did this, things worked:

  curl -s -v -Tinput.xml -H'Content-Type: text/xml;charset=UTF-8' http://localhost/api

That reads directly from the file. The only difference between the two requests is that the latter includes a Content-Length header whilst the former has Transfer-Encoding: chunked instead.

This is the code that was reading the request.

    my $content;
    if ( $r->header_in( 'Content-Type' ) ) {
        $r->read( $content, $r->header_in( 'Content-Length' ) );
    }
    return $content;

So, if there’s no Content-Length, what should we do? My first stop is always the venerable eagle book. There’s a little footnote next to read():

At the time of this writing, HTTP/1.1 requests which do not have a Content-Length header, such as one that uses chunked encoding, are not properly handled by this API.

Marvellous. Now, I had a look around in the source code and noticed a function called new_read(). Unfortunately, that failed to work. It stopped chunked reads, but failed to work for ordinary ones.

I did see a post on the mod_perl mailing list which reckoned you could loop and read all input. But I was unable to get that to work either.

So I just decided to disallow chunked input. That’s fairly easy to do, and HTTP has a special status code for it: 411 Length Required. It’s not ideal, but unless this project gets upgraded to Apache 2 (unlikely, quite frankly), it seems to be the best option.

by dom at October 07, 2008 11:37 AM

October 06, 2008

blog.mignault.net

Recent twits

Powered by Twitter Tools.

by jbm at October 06, 2008 03:59 AM

Perlbuzz

What's the state of Perl web frameworks?

Joshua Hoblitt pounced on me in AIM this morning as soon as I opened my laptop.

Joshua Hoblitt: Here's something to put on Perlbuzz.

JH: WTF MVC framework is working this week?

Andy Lester: Sounds like an editorial in the making?

JH: Maypole is dead, Catalyst is um, well, I've never managed to finish a project with it.

JH: The documentation is SHIIITTT.

JH: And the book is one of the most crapped-on books I've ever seen on Amazon.

JH: So Catalyst is a no go for me.

JH: So what's left? Roll your own with Mason?

AL: CGI::Application?

JH: Ya, I've used it for small stuff.

JH: The kind of stuff you put in one monster .pm file so it's trivial to install.

JH: Hmm, there's MasonX::MiniMVC.

JH: And this egg thing.

AL: Can I post this chat as an article?

JH: Please do.

I've gone through a similar thought process recently. I've started looking at CGI::Application, but the work project where I was starting to use it has been derailed for a weeks.

I welcome your ideas on the state of frameworks, either in comments below, or as a guest editorial.

by Andy Lester at October 06, 2008 02:45 AM

October 05, 2008

Perlbuzz

Is learning Perl the hard way the easy way?

Bruce Momjian, guru of PostgreSQL, has discovered the joys of Perl.

I have converted two of my most complex shell scripts to Perl; as shell scripts, they were slow and hard to maintain. The rewritten Perl scripts are 200-400 lines long (about the same length the original shell scripts) and 15-25 times faster because of the improved algorithms possible in Perl and reduced subprocess creation.

What was surprising to me was how he'd learned, via a book I'd never heard of before, Learning Perl The Hard Way. Has anyone in the Perl Buzz readership read it? Comments?

by Andy Lester at October 05, 2008 02:25 PM

October 04, 2008

Perlbuzz

Please enjoy the new design

I like the new design so much more. Less yellowy and blocky. Thanks to Kelli Forbes for doing the logo. If you need design stuff, email her at kjfwsd-hotmail-com. Thanks also to Chris Larkee here at Barcamp Milwaukee 3 for helping me override the Movable Type templates, and showing me slick stuff in Firebug that I didn't know it could do.

by Andy Lester at October 04, 2008 11:36 PM

October 02, 2008

blog.mignault.net

CR Sunday Feature: The 50 Things That Every Comics Collection Truly Needs [del.icio.us]

Another canon-type list. Closer to my tastes, though I can only take small doses of men in tights these days. I do retain Bat- and Spider- man nostalgia, though.

by jmignault at October 02, 2008 03:41 PM

Perlbuzz

Hidden features of Perl

There's an interesting little thread at Stack Overflow on Hidden features of Perl. Go on over and add your favorites.

by Andy Lester at October 02, 2008 03:05 PM

Developer optimization redux

Users are crucial to open source projects. Without them we have no reason to release publicly, and without refreshing the ranks of developers with users who join the fold, our projects die. Users are our customers, and we can't afford to treat them poorly. When a user wants to go the extra mile to help us as developers, turning him or her away is a grave misstep.

Here's an example. Andrea discovers a problem in PHP's database handling, where calling a certain function incorrectly causes a segfault. The bug isn't a work-stopper for her, and the fix is simple: Call the function correctly. Still, it's a segfault, and she figures the PHP folks will want to know about it. It also doesn't help her confidence in the tool that calling a function incorrectly segfaults. Being a good open source citizen, she decides to report the bug.

She's already spent the time figuring out the problem, and she reduces the code to a single, repeatable example, that shows exactly how to make the code segfault. "This should help them track it down," she thinks. She's spent an hour on this detour in the middle of a project for work, but knows that open source relies on bug reports to get things fixed.

She dutifully checks bugs.php.net, and finds nothing that matches, so she goes to submit the bug. Unfortunately, the PHP site will only accept bugs against 5.2.6, instead of 5.2.5 that she is running. This leaves her with three choices:

  • Upgrade to 5.2.6 on a test machine, and test out her problem. She knows not to upgrade a production box so cavalierly.
  • Find someone using a similar install to see if that person will test it for her.
  • Submit the bug against 5.2.6, effectively lying but not spending any more of her time.
  • Throw up her hands and say "Screw it, I've got work to do."

That's what happened to me, "Andrea", the other day. I wrote about it in a frothier Perlbuzz article the other day. I wish that my frustrations with PHP hadn't overshadowed my point about community building, so I'm trying again here.

What about the users?

My frustration in PHP's approach, and they're certainly not the only community to do this, is that the emphasis is in optimizing the time of the PHP developer who has to deal with bugs. "Who wants to deal with bugs that have already been fixed?" goes the logic. I imagine someone setting up the PHP bug database saying "We need to put something up to make sure that we don't get annoyed by bugs that have already been fixed." I can understand that motivation. As someone who answers questions in #perl about WWW::Mechanize all day, I can certainly empathize with not wanting to deal with pointless comments.

And yet...

Nowhere do I see any discussion of how the user sees the interaction. I doubt anyone considered the reaction of the user who is told "Sorry, you're not able to submit your bug report that you worked to get together to send to us." Instead, debate about the original article is from the point of view of the beleaguered developer, having to deal with those darn users, contributing their bug fixes.

Yes, I understand that plenty of people submit bugs that aren't bugs, or that have already been fixed. Perl's bug reporting system is wide open, and I've closed my share of tickets in RT that weren't really bugs. But I'm OK with that.

How long does it take to close tickets that aren't right? Compare that cost to the cost of losing a valid bug report. Or worse, alienating a potential friend of your project.

In everything we do when working on projects, we need to remember there are real users, real people at the other end that are the core of what we do.

by Andy Lester at October 02, 2008 04:51 AM

October 01, 2008

blog.mignault.net

The Crib Sheet: My Comics Canon [del.icio.us]

Interesting choices from a European critic, Los Bros Hernandez being the most obvious and surprising omission.

by jmignault at October 01, 2008 01:58 PM