It looks like something didn't go quite as planned in the migration yesterday and now we seem to have lost some of the most recent posts. It looks like we're missing stuff from about midnight on 8th December to just before midday today.
Sorry about that. We now have a database back-up strategy in place that means we'll always have far more recent backups available. I'm sure this was a migration glitch and nothing more serious.
My fabulous new nook arrived today. The packaging was atrocious, as can be expected for any new electronic gizmo, but once I broke out the Jaws of Life and freed the nook from its captivity, I was very pleased indeed. The first thing I did was to load it up with my PDF copy of Mark Jason Dominus's Higher Order Perl, which is now available for free and which every Perl programmer should read once a year or so.
On all released 5.10.* versions of Perl to date, the smart match operator can segfault if passed recursive data structures (like arrays that contain a reference to themselves).
I fixed that. The fix was pretty trivial: basically, the C code in the implementation of smart match was creating two hashes, called seen_this and seen_other; however, a typo made it so only seen_this was actually created. Segfaults ensued if the code was trying to use seen_other.
Do you see the language problem here? The code to create seen_this was copied and pasted to the code to create seen_other, but not all occurrences of the variable were renamed. Because in C, it's difficult to factorize this code without much programming overhead. (In that case, pointers to pointers.)
But in Perl, we have foreach and aliasing to $_. That's a great tool to avoid cut and paste, and reducing cut and paste will always improve maintainability. And that's why I prefer writing stuff like
It's a lot of fun to contribute to other people's code (especially code you're using) and it's very fulfilling. Some people say it's a downer when your code isn't accepted, and I can understand that. However, the serious downer is when your code gets ignored.
When I go over a module, I go over the ticket list. When I see a ticket from over a year and it's still "new", it disappoints me and when I contribute to a project and it takes six months to get a reply, it disappoints me.
The following is ongoing on my private branch of the CPAN dist Net::RackSpace::CloudServers, in which I'm creating an App::Cmd interface to the module:
So I finally managed to attend a Perl workshop over the weekend and it was awesome! I saw some excellent talks and even got a goddie bag ... I was not expecting that. Some personal highlights:
Most entertaining talk
For me it was Piers Crawleys lightening talk/song "don't care how you young people talk to one another but don't take that tone with your mother". Can I have the lyrics please ;)
Most useful/relevant talk
Plack/PSGI by Miyagawa. It's great to see that folk much smarter than myself are solving issues that directly influence my work. More of stuff like this and I won't be forced to use Ruby any time soon ;)
Most "what the hell was he on about" talk
Definitely Matt Trout's BEGINing Perl talk. Something about compilation units, Moose, antlers, Damian Conway, black magic, e.t.c. I understood about 30% of that ... about 20% more than I anticipated ;)
I left with a satisfying feeling that I am somewhat better than I give myself credit for (mostly because I understood any of Matt Trout's talk). I missed most of the conference including the trip to the pub and did not socialize as much as I would have liked. Perhaps in my next conference I'll be more friendly :)
All in all a great experience that I would recommend to any one!
My editor of choice is Emacs. Like Perl, one of its strengths is its flexibility. (some would argue this a weakness. to each their own) Here's just one example I recently found... you can extend Emacs to change the cursor based on what mode you are in (normal, read-only, overwrite)
Rapidshare deletes illegal files, so instead of sharing Rapidshare links, sites nowadays apparently started sharing .dlc files (or so I've heard). DLC is an encrypted container format. It is very very stupid. I'll elaborate.
Let's break it down:
Only one server decrypts - single point of failure.
Disregarding the necessity for internet, this binds you to specific programs that have the keys hardcoded in them to be able to access the server.
The protocol is secret, the key is secret, the programs are closed source (at least the part that matters).
One program is for Windows only. The main one is written in Java. Stupid Java. I've gone over the parts of it that are open source and it's horrible (really really horrible).
I have not managed to get the program running on three different computers, and on Windows as well.
Apparently they change the key every once in a while so you always have to stay updated with the program.
So I have a module that exports some functions that each take a single hashref as an argument, and I want to be sure that:
I really have got a single hashref
The contents of the hashref conform to my specification
I'd never used Params::Validate before now, so this looked like an ideal opportunity.
Here's what I came up with:
sub _validate_me {
# Raise exception if we don't have exactly one hashref
validate_pos( @_
, sub { TYPE => HASHREF } );
# P::V only tests lists.
my(@test) = %{$_[0]};
# Now we have our validation specs for the hashref. We accept :
# keys foo,bar and baz, each with defined scalar values of length > 1
# keys qux and tla with defined scalars as values.
# Anything else is a fatal error.
validate( @test
, { foo => { type => SCALAR
, callbacks =>
{ 'foo set' => sub { length($_[0])>1 } } }
, bar => { type => SCALAR
, callbacks =>
{ 'bar set' => sub { length($_[0])>1 } } }
, baz => { type => SCALAR
, callbacks =>
{ 'baz set' => sub { length($_[0])>1 } } }
, qux => { type => SCALAR }
, tla => { type => SCALAR } } );
}
And in the calling code :
sub do_stuff {
_validate_me(@_);
# Invalid? BOOM
my($args) = shift;
#Continue processing.
#..
}
We could obviously push quite a lot of validation logic into the callbacks, which has the benefit of making the actual application code much cleaner.
In November we reached the 6 million reports submitted mark. It's quite staggering how many reports are being submitted these days. It's now roughly 1 million reports every 3 months! So expect a 10 million reports post some time in August 2010 :)
If you have uploaded a distribution to CPAN via Pause recently you may have noticed a link to Mike Schilli's blog where he explains how to publish directly from GitHub.
It only works if your git working copy is structured the same way as the tarball that you want to upload to CPAN. So, if you are making heavy use of MANIFEST.SKIP this probably won't work for you (unless you are also git-ignoring those files). You will also have to ensure that the version number in META.yml in incremented (I've generally rely on ExtUtils::MakeMaker to do this when using make dist).
The only problem that I encountered was that the top level directory in the tarball follows GitHub's conventions rather than the usual module name + version directory created by make dist. So for instance you would get something like /jmcnamara-mymodule-ce15c1e instead of /My-Module-0.01.
Anyway, I uploaded a recent distribution using this method and it worked out well. If you are using GitHub as your repo you should try it.
I Love ALL the Perl Advent Calendars!! The Perl6 calendar has got me SO excited for Perl6, I can't wait to finish a couple of my projects so I can get a new version of pugs installed. The last time I installed pugs was 11 months ago and most/many of the examples don't complie on my buildout. :(
I have gradually been drifting towards Python in recent months due to my fright of what will happen to Perl5 when Perl6 comes along. But with the advent of the advent calendars, it's been a rejuvenation or even a renaissance in my interest in Perl and programming all together.
So THANKS to all who have put the time in to prepare all of this wonderful content. It really underscores the quality of people we have in the Perl community.
Here is a compact way of writing a multi-value if statement.
Lets say you have a scalar string variable and need to see if it matches a number of possible values. You want it not case-sensitive and the comparisons must match exactly.
Source code:
#Search word
$pet = "rabbit";
#Regular Expression: / ^=beginning of string, $pet variable, $=end of string / i=ignore case
#Using Anonymous Array: ("cat", "dog", "...as-many-as-you-like...", "horse")
if ( grep /^$pet$/i, ("cat","dog","hamster","RABBIT","Raccoon","Monkey","horse") ) {
printf("A %s is a Mammal.\n", ucfirst($pet) );
}
elsif ( grep /^$pet$/i, ("Alligator", "frog", "salamander", "Snake", "toad") ) {
printf("A %s is an Amphibian.\n", ucfirst($pet) );
}
else {
printf("What is a %s ?\n", ucfirst($pet) );
}
#- - - end - - -
One of the first posts on my old journal (which I still don't know if I want to copy the entries here) was entitled Tests are Heavenly. In that post I wrote about how I started adopting TDD for administration purposes.
Recently I've been getting CPANTS reports (<3 CPANTS!) on my WWW::FMyLife module. At first I thought my tests were off. Yesterday I finally got down to take a closer look at the reports and code. I tried some variable dumps (my favorite debugging method) of the data I was receiving from FMyLife.com in the module. Then I noticed that FMyLife were sending me different data than they are suppose to. They aren't following their API correctly.
I've uploaded the first release of App::Pod2CpanHtml to CPAN. The main purpose of this module is to install a pod2cpanhtml executable for converting Pod to search.cpan style HTML.
pod2cpanhtml SomeModule.pm > some_module.html
I initially wrote the executable in response to a question on PerlMonks. It is just a very thin wrapper around Pod::Simple::HTML combined with the search.cpan CSS.
I find that I use this utility all the time, for generating HTML docs and for proof reading documentation prior to uploading it to CPAN, so I thought that I may as well make a module out of it.
This also serves as an answer to the frequently asked question "How do I create HTML docs like on CPAN".
The main reason that the module produces HTML output that looks like search.cpan is that it uses the same CSS style sheet. I'm not sure who wrote that but they deserve some praise for achieving a clear, uncluttered and appealing layout.
I've been thinking about how to make an application I'm currently designing more REST-like. (You'll forgive me if I avoid the atrocious neologism "RESTful.") The HTML forms specification only supports the GET and POST methods for form submission, but if you've ever designed a web service for other HTTP clients, you've probably had a good reason to use PUT and DELETE as well. PUT is an idempotent create operation; sending the same PUT twice will cause the same resource to be created at the same URI, whereas a duplicate POST could have unknown, possibly disastrous side-effects. And HTML forms have no support at all for anything resembling DELETE -- how often have you designed an application that requires a POST to delete an object? That doesn't make sense.
Sometimes I forget to run Perl base tests for my modules, before committing changes. As to what happens, I end up committing something that doesn't quite compile ;)
Luckily Git has a pre-commit hook one can use to run at least the "compile" tests.
The following aborts the commit if the t/00*.t tests (usually the "do all modules compile?" tests) in the repository don't run correctly; stick it in
.git/hooks/pre-commit
:
#!/usr/bin/perl
# Runs modules' "compiles" tests before committing
# Dies (halting commit) if they don't compile
print "pre-commit => testing..\n";
do {qx{
prove -Ilib t/00*.t
}} or die <<'DIEMSG';
pre-commit => ERRORS:
$@
DIEMSG
print "pre-commit => test OK\n";
This is an example of a 00-load.t file, that can literally be dropped-in the t/ directory:
use strict;
use warnings;
use Test::More;
use File::Find::Rule;
my @files = File::Find::Rule->name('*.pm')->in('lib');
plan tests => ~ ~ @files;
for (@files) {
s/^lib.//;
s/.pm$//;
s{[\\/]}{::}g;
ok(
eval "require $_; 1",
"loaded $_ with no problems",
);
}
File::Find::Rule
is one of the golden gems found on CPAN, rclamp++!
Are you a sysadmin and you're running servers with a lot of Perl code and Perl modules installed? You are a Perl hacker, who wish to access the complete CPAN repository on his notebook even when not connected to the internet?
Why not set-up your own CPAN-Mirror then? It's really easy.