canspice.org

home about code feeds archives links

Archive for the 'OSCON 2005' Category

OSCON 2006: Day Two Recap

On day two of OSCON 2006 I attended Real World Web Services by Scott Davis and More Perl Best Practices by Damian Conway, both of which were good. In RWWS, I don’t remember seeing how to do authentication and authorization over REST, but it must be possible. Damian’s tutorial was a continuation of last year’s tutorial and was quite good as well.

Tuesday night there was reportedly a BoF named “Beers of a Feather”, where someone was apparently organizing a pub crawl, so some of us from IRC went. The lack of any organization didn’t stop us, and we started off in Kells Irish Restaurant and Pub. It was a good start to the evening, especially when the live talent (one guy with a guitar) played Spirit of the West’s Home For A Rest, whose chorus goes:

You’ll have to excuse me, I’m not at my best
I’ve been gone for a month, I’ve been drunk since I left
These so-called vacations will soon by my death
I’m so sick of the drink, I need home for a rest

The night proceeded from there, including hilights from a guy who rapped for us on the street, Chris forgetting his credit card at one of the bars, and a relatively seedy Russian-ish bar to close out the trek.

All in all, a good day.

Edit: I can’t believe I forgot the Tuesday Night Extravaganza! Larry Wall gave his annual State Of The Onion address, making it the tenth one now. It was a good talk about how Perl is growing up and will be ready to “set out on her own” when Perl 6 comes along. Kathy Sierra gave an engaging talk about creating passion in your users. And as always, Damian Conway was excellent with his parody titled “The Da Vinci Codebase”. A Perl one-liner that downloads an illegal prime and converts it into a gzipped program that can decrypt DVDs? Yes please!

Edit2: Flickr user ptufts uploaded a better picture of Damian Conway’s twisted twisted code.

OSCON 2005: Best Practice Perl, Damian Conway, second half

The second half starts off with a discussion about built-in functions. Damian Conway’s most important recommendation about built-in functions is to use built-in functions, as there’s a lot of them and they’re incredibly useful and generally better than anything you can write yourself. In modern versions of Perl, the values function can be used as an lvalue, something I didn’t know (I think my Perl books are too old). Always use a block with functions like map and grep because the transform/test stands out more clearly.

There are also a load of functions that aren’t core but are in modules that are incredibly useful. Use things like List::Util and Scalar::Util instead of reinventing the wheel.

Subroutines are the single-most important problem decomposition tool available in Perl. They should be used to abstract out behaviour and be short enough to fit in the human brain (Conway says ten to twelve lines). Always unpack @_ first, don’t use things like $_[0] and $_[1]. Named arguments should be used if you have more than three arguments to a subroutine. It’s perfectly okay to mix positional and named arguments, and use a hash reference to pass in named (or optional) arguments. Don’t use prototypes. Always return with an explicit return. Use a bare return to return failure, don’t return undef because it doesn’t work properly in list context.

Moving to I/O, input and output are especially important. Don’t use bareword filehandles. Ever. They’re a bad bad idea because they clobber any other filehandle opened to the same name anywhere else in the same package. Use lexical filehandles instead. Use three-argument open because it doesn’t get subverted by bizarre filenames (say, filenames that start with a >). Putting braces around your lexical filehandle makes it stand out in print statements.

Regular expressions: always use the /x flag on every regex you write (it allows you to break up regexes onto multiple lines, and it allows you to put comments in them). It makes regexes more maintainable and readable. Always use the /m flag (it turns ^ and $ into matching the start and end of a line, instead of the start and end of a string). If you want to match the start and end of the string, use \A and \Z (or \z). Always use the /s flag (it modifies . to match any character instead of any character but newline). If you want to bundle all of these together, use the Regexp::DefaultFlags module. If you want to group, use (?: … ). Don’t use $1, $2, etc., use something like my ($statement) = $source =~ m{\G ([^;]+) ;}gcxs;.

Error handling is necessary because programs are built by humans and operated by humans. When you detect an error the only safe thing to do is to go up-scope. Prefer exceptions over special return values, because it’s incredibly easy in Perl to ignore return values. Throw an exception as soon as you have the chance. Use croak instead of die. Write your error messages in English so that the user can understand what’s gone wrong.

Use CPAN.

When writing a module, design the interface first. When refactoring code, it’s always okay to cut, it’s never okay to paste. Perl 5.10 will come with a core module called version that will handle versioning much easier than before. Consider the Perl6::Export::Attrs module for exporting subroutines from modules. Have a standard module template for any modules you write.

That’s the end of the tutorial.

[link to first half]

OSCON 2005: Best Practice Perl, Damian Conway, first half

Is there actually a right way to do things in Perl? Of course not, but Damian Conway just wants to give his impressions of what the best practices might be. “Best practices” refers to writing code that is maintainable, robust, efficient and concise. Best practices is a set of rules to combat “Intuitive Programmer Syndrome,” where a programmer programs by using The Force instead of following some standard set of rules.

Damian Conway wants us to become lady and gentlemen programmers who, six months down the line, don’t hurt anybody unintentionally. That’s what best practices are about, not hurting the person who’s going to have to maintain the code we write today.

Uhoh. “Nobody wants Perl programs more than 10,000 lines long.” ORAC-DR sits at over 300,000 lines of code, but a lot of that is documentation.

None (or at least, very few) of the rules Conway will be presenting are absolute. Consider them guidelines. Use them as a starting point, not a finishing point. Negotiate the rules with your fellow developers, and enforce them strictly and rigidly once they’ve been established.

Starting with the most controversial part of coding standards: layout. It doesn’t matter which style you choose, as long as when you pick a style you stick to it. Conway suggests bracketing and parenthesizing in K&R style, separating control keywords from the following opening bracket, not separating subroutines or variable names from the following opening bracket, and separating complex key/index computations from the surrounding brackets. Semicolon after every statement, comma after every list element, 4-column tabs. Code in paragraphs, meaning put an empty line between distinct chunks of code that do one thing. Each one thing might have a few lines of code, but if you separate these things by blank lines, the code becomes easier to read. If you’re breaking up long expressions into multiple lines, Conway suggests breaking before the operator (which is something I don’t do).

Only slightly less controversial: naming. Conway claims that a consistent naming convention will make your code at least twice as maintainable. Using underscores_in_variable_names insteadOfInterCaps is considered easier to read, as is abbreviating names by prefix instead of removing vowels. Name hashes in the singular and arrays in the plural.

“Thinking causes problems.” So don’t think, use templates for forming identifiers.

Moving on to variables, watch out for the so-called “punctuation variables” — nobody is comfortable with all of them. Don’t use package variables unless you absolutely have to. One thing I didn’t know is that $a and $b (variables used for sorting) are completely immune to use strict. Lexical variables should be used within modules, and subroutines used to modify those variables. Watch out for modifying $_.

Conway doesn’t like postfix-style control structures (do this if that), and prefers it the other way around (if that do this). He doesn’t like the C-like three-statement for loop, prefering the more Perlish for loop (for my $n ( 4..$max )), because he doesn’t have to think. Don’t subscript within loops; if you’re going through values in an array then ideally do something like for my $client ( @clients ) { … }, or at worst take a copy of that value within the loop (suppose you need the iterator variable to print out client numbers), then do operations on it. Same for the values of a hash, as long as you’re using Perl 5.6 or higher. (Note for self for when I get back to work: look into Data::Alias)

When you write a for loop, don’t use explicit $_, use an explicit iterator instead (i.e. for my $candidate (@candidates) { … }). Never leave off the my when naming an explicit iterator. Also, don’t trust use strict. Use it, but don’t trust it. “Perl will shoot you in the head if it possibly can. Doesn’t believe in the body shot.”

This coming section would be Tim’s favourite: when to use map instead of for (I always use for and Tim always changes them to map). You get more compact code, use less memory, and it’s probably going to be faster. Use map when you want to generate a new list from an old one, and use for to transform a list in-place.

When producing a value that depends on a series of tests, use the ternary operator, and line things up so the question marks line up in a column and the colons line up in another column.

Documentation! Development programmers hate documentation, maintenance programmers love it. Since we’re both, just do documentation. “Documentation is a love letter we write to our future self.” Create a standard POD template and just fill it in — h2xs -X, ExtUtils::ModuleMaker and Module::Starter (or Module::Starter::PBP) can do this for you. The DIAGNOSTICS section should be pulled directly from every die, croak, and carp statement in your module, as long as every output to STDERR. Document what’s already broken. Remember: “the primary use of user documentation is so you don’t have to interact with the user.” A disclaimer of warranty is probably the most important thing to put in these days. Acknowledgements are a good thing to put in as well, because it makes people happy.

Develop a consistent commenting system and use it. I was the only person to stick their hand up when Conway asked who has colleagues who write good comments (I’m thinking primarily of Malcolm’s code here, although most of the Starlink code is extremely well-commented). Use =for sections comments for larger discussions. A comment belongs anywhere something has puzzled you or tricked you. “If it fooled you once, it will fool you, or whoever comes after you, again.”

Thus ends the first half.

[link to second half]