Perl geekery: building hashes

Say we’re writing a program in Perl, and we need to pass a lot of data back and forth between subroutines. Using global variables is bad practice, and we often use the slightly-less-bad method of passing around a big hash variable. But it’s a pain to always use the values in the hash, so a lot of our code uses individual scalar variables, and stick them into (and pull them out of) the hash as needed. But when you have a lot of values to move around, it’s a pain in the neck. You don’t want a big, ugly block of code like this:


#...assume that we declared %hash, 
#   $foo, $bar, $baz, etc previously...
$hash{'foo'} = $foo;
$hash{'bar'} = $bar;
$hash{'baz'} = $baz;
# ...ad nauseum...

Surely, there’s a more elegant way to do this, right? Of course there is. The mantra of perl programmers is TMTOWTDI (There’s More Than One Way To Do It)! The first and most obvious approach that comes to mind is to use “variable variables”, technically known as “symbolic references”:


my %hash;
my @vars = qw(foo bar baz);
foreach my $var (@vars) {
  # This uses a symbolic reference. When $var is 'foo',
  # then saying $$var is like saying $foo.
  $hash{$var} = $$var;
}

The problem is that symbolic references are frowned upon, and will cause perl to get angry with you if you’re running with use strict (as you should be). You can get around this by declaring the scope of $foo and friends as ‘our’ instead of ‘my’, and by using no strict 'refs' inside the foreach loop. I’m pretty sure that this wouldn’t cause any memory leaks, but it’s still an iffy solution because you have to change the scope of a bunch of your variables to ‘our’, which might have undesired side-effects.

The next refactoring is a nice improvement. The main difference is that it requires you to stick your list of values into a temporary array. Just keep in mind that this array will be modified (emptied) in the process:


my %hash;
my @keys = qw(foo bar baz);
my @values = ($foo, $bar, $baz);
foreach my $key (@keys) {
  $hash{$key} = shift @values;
}

Ah, much better! No problems running strict, and not too ugly. A final improvement, suggested to me by David Narayan, is to use a hash slice:


my %hash;
my @keys = qw(foo bar baz);
my @values = ($foo, $bar, $baz);
@hash{@keys} = @values;

That’s about as succinct as it’s going to get. The only disadvantage here might be if your list of key/value pairs was large, this would probably use a lot of memory. In that case, you’d probably want to use the foreach loop, as in the previous example.

WP-Cache fix for Content-Type in feeds

If you run a busy WordPress site, or even if your site just has a lot of processor-intensive plugins, then you probably already run the WP-Cache plugin (plugin directory, original announcment, recent security update info). Even though my site isn’t super busy, my server is a little light in the RAM department, and using WP-Cache helps the box keep up with requests better.

One minor annoyance, however, is that with WP-Cache enabled, my syndication feeds aren’t delivered with the correct Content-Type. They are all cached with a “text/html” type. Again, this is only a minor annoyance, since I haven’t run across a feed reader yet that cares very much about the Content-Type header. But the Feed Validator does. If it sees an Atom feed delivered with content type “text/html” instead of “application/atom+xml”, it gives you a warning. It still checks the validity of the actual feed content, but there’s that big ugly warning at the top.

But not any more. I dug a little bit into the WP Cache plugin to try to figure out what was going on. The plugin does attempt to preserve the correct content type of pages when it caches them, but the output buffering that it uses to capture the content gets in the way. You can’t get to the generated headers until after you flush the buffer. But you don’t want to flush the buffer until you’ve got all of the data to write into the cache meta files. It’s a catch-22. (Actually, it might be okay to flush the buffer at the point where you need the headers, but I’m not sure without further analysis, and I just don’t have the time right now. I’ll leave that as an exercise for someone else. 😉 )

So, if you’re a stickler about minor things like the Content-Type of your feeds, and you’re using WP-Cache, feel free to check out my patch: WP-Cache Feed Content Type Patch. Note that the changes to the wp_cache_get_response_headers() function don’t actually work for me. But I left them in the patch in case anybody else wants to examine that section more closely. It might just be something that works in some combinations of Apache/PHP versions and not others.

Update 2007-10-12: This problem was officially fixed in wp-cache version 2.1.2.

Another new start

Free IQ - The Marketplace for Ideas

About two weeks ago, I started a new job (which explains at least part of my blogging lull, you see). I’m working on Free IQ, which is a streaming media site for entrepreneurs. There’s more to it than just the streaming media (you can upload video, audio, PDF files, PowerPoint presentations, etc.), but I’m still learning the ins and outs, so I don’t know the full scope yet.

When I interviewed, they were favorably impressed by the fact that I’m a WordPress developer. This is something that our industry is seeing more and more of — involvement in open source projects is often a good selling point in your resume. Several people have come by to ask me WordPress questions, and more than once I’ve been asked, “you’re the WordPress guy, right?” I haven’t actually done anything WP-related, yet, but I think that might come down the pipe one day.

WordPress 2.2 Released

WordPress 2.2 “Getz” is now official. I’ve listed some of the changes previously, but here’s another quick rundown:

  • Atom feeds updated to Atom 1.0
  • Preliminary support for Atom Publishing Protocol
  • Widgets are now supported in core
  • Protection against activating broken plugins
  • “Deactivate All Plugins” button. Sadly, my “Reactivate All Plugins” patch didn’t make it into this release. Hopefully you’ll see it in WP 2.3.
  • Improvements to comment management
  • Code optimizations and speedups
  • Future WYSIWYG support for the Safari browser
  • Post Preview moved into a popup window, rather than an iframe on the Write page
  • WordPress-specific XML-RPC API
  • JQuery support

You can find a list of changes for version 2.2 on the WordPress Trac site. Ready to sample the new hotness? Start downloading!

WordPress 2.2 Release Candidate 2 Now Available

There have been some more bugfixes applied, and there is now a second RC available. Details are in Ryan Boren’s announcement.

WordPress 2.2 RC2 — You’re soaking in it! (In other words, I’m running it here 😉 )

By the way, one other change in this version that I don’t think has been mentioned in the previous announcements: In the “Write Post” screen, the post preview is no longer displayed directly in the page. Instead, you’ll find a “Preview” link near the title area which will pop up the post preview in a separate window. This speeds up page loads and reduces bandwidth consumption during post editing.

See also: the Release Candidate 1 announcement.

WordPress 2.2 Release Candidate 1 Now Available

Last night, rob1n tagged WordPress 2.2 RC1 in the svn repository, and Ryan Boren posted an announcement on his blog. That means that at this point, there shouldn’t be any major feature changes going into this branch, just bugfixes. It also means that it’s almost ready for official release. If you know what you’re doing, and you are willing to help test for and report bugs, download it from the Release Archives and give it a whirl!

Benefits of Blogging

My brother-in-law, Bob, has been keeping a blog on wordpress.com for a while now called Arcane Code. He mostly writes about software development using Microsoft tools, because that’s what he does for a living. He’s also had some interesting posts lately about installing various flavors of Linux under Virtual PC, and a long series digging deeply into SQL Server. But one of his most recent posts caught my eye and I wanted to share it: Arcane Thoughts: Benefits of Blogging.

In this article, Bob briefly outlines six benefits that he gets from writing on his blog: Meet and Greet, Self Documenting, Self Promotion, Mentoring, Education, and Giving Back. Even though I don’t make time to post something new every day (I wish I could), I have some of the same thoughts and feelings about why I keep a blog. Click on over, read his post, tell Bob why you blog. And tell him that Dougal sent you. 🙂

Plugin Management

One of the new features in the upcoming WordPress 2.2 release is an option to “Deactivate All Plugins” with one click. Our standard advice is to deactivate all your plugins before upgrading so that out-of-date plugins won’t break your system mid-upgrade. But in the past, you had to deactivate plugins one at a time. Thus the new “Deactivate All Plugins” button to make this easier.

While testing some things on my development system, I was frustrated that after an upgrade, I still had to reactivate my plugins one by one. So I threw together a “Reactivate All Plugins” feature, which I hope will be implemented for the release of WordPress 2.2.

With this patch, when you use “Deactivate All Plugins”, your current active plugins list is saved. Then later, when you attempt to “Reactivate All Plugins”, it will check each plugin one-by-one. The worst that could happen is if one of your old plugins throws a PHP fatal error, then the reactivation is aborted, and no plugins are reactivated. Simpler errors, like a plugin being deleted from disk between the deactivation and reactivation, are handled more gracefully — the valid plugins will be reactivated, and the missing ones will be reported to you.

WP Tags: Perhaps I spoke too soon…

Doh. I should have caught up on my wp-hackers reading before I made that last post. It appears that we’re going to delay the tags support until version 2.3 in order to have more time to flesh out all the details properly. Instead, it appears that sidebar widgets may become an official core addition in WP 2.2. Stay tuned for more details…