Blessed are the CPAN Testers

I was doing a lot of work on Dancer lately. We've been experiencing a few test failures on Windows with the upcoming big release. I'll admit we are usually reluctant to go to Windows-land and fix issues, but Alias sure made it clear how important it really is, so it was something that had to be done at some point.

While investigating this situation, I've noticed Cwd's realpath() function was complaining a path for a test did not exist. The path did not exist for Linux or BSD either but the test wasn't failing there.

After checking out Cwd more closely, I've noticed it had an XS version for Linux, BSD and other operating systems and a few Pure-Perl implementations of realpath() for some (OS2, MSWin32, DOS, VMS, for example). Upon inspecting the XS code and the Pure-Perl code it was apparent that the versions were not exactly the same. On Windows if a path does not exist, it will croak but on Linux it will continue running.

Blessed are the CPAN Testers, for they show us the bugs!

Dear LazyPerl

I'm looking for a Catalyst or other Perl based application framework that will do standard CRUDS (CReate, Update, Delete, Search) functions. I've seen a few of the online writeups about how different people put these together in as few lines as possible, but I'm more looking for one that I can just install via CPAN, configure a database connection, and start the server.

Any suggestions?

Ubic - multiservices

(This is a long time overdue post in Ubic series. Previous posts can be found here.)

Last time I explained how any kind of service start/stop/status behavior can be encapsulated in an Ubic::Service subclass. But what if you have many similar services, and want to generate the service list dynamically?

For example, sometimes you already have a directory with daemon configs, and want to run them all without creating additional "service description" file per daemon.
Or you may wish to start ten instances of one processing script.
Or maybe you keep the list of your services in SQL database on another host.

In all these cases, multiservices come to the rescue.
Multiservice is a container object which provides part of the service tree.

For example, let's assume you have a dir /usr/share/psgi-apps/ with some psgi apps in it:

Playing games and fixing bugs

Playing games can be useful too. While playing "Lacuna Expanse" and using a bot to find a good asteroid to mine, I found a bug in YAML and fixed it. Later I found out that this bug was already reported 4 years ago.

DancerJukebox - Dancer-based music queuing webapp

David Precious (A.K.A. bigpresh) recently wrote a nifty little webapp for MPD (Music Player Daemon) using Dancer, available here.

He also wrote an article about it which you can read here.

Props!

new things in Kephra

as the next release 0.4.4 is about basic editing, I filles there several feature holes.

like e.g. inserting rectangular selections properly, making the brace nav more consistant (jumping from inside to inside matching braces or from outside to outside). then i also added left and right to moving text(line/block) to indend/dedend tabwise which makes refactoring easier. Now im working on the proper DND of rectangular selections, which isnt delt properly even in kommodo 5.

here on austrian perl workshop the friendly guys helped me to fixe an issue with Module::Install and thanks to jizef kutej the debian package is also ready (jejky!).

but there is much more to come but i want to sanatize the basics first befor we start next bigger chapters like plugins and extentions ....

Performance hacks

http://corehackers.perl.org/wiki/index.php5?title=Main_Page#Performance_Hacks lists some perl5 Performance hacks.
Most ideas are from me.

There's another Raw Array idea from Leon, for which I wrote Tie::CArray ages ago, but this can be made better of course. Tie::CArray does not need to do its own memory management.
That's what we have magic for. The array of I32/U32/NV/char[12]/.. can reside in the PVX and the getters/setters/... are just magic callbacks as in Tie::Array.

I just talked about some obvious illguts observations at the vienna perl workshop and was asked to eloborate.

Leave off xpv* structs

If you don't need any xpv struct, e.g. for short strings, you can leave it off. This will need a flag bit and can be set if MAGIC and STASH is empty.

svpv-14.png
http://cpansearch.perl.org/src/RURBAN/illguts-0.35/index.html#svpv

Tainting traps

I ran into some trouble when combining tainting with the Encode module. Recently, I've been using the Encode module to decode from binary to text as soon as possible and encode back to binary as late as possible. Unfortunately, this completely kills the protection that -T grants, presumably b/c the Encode module uses a regular expression to do it's work.

#! /usr/bin/perl -T

use strict;
use warnings;
use Encode();

$ENV{'PATH'} = '/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

my ($home) = Encode::encode('UTF-8', $ENV{'HOME'});
system("echo $home");

This can be beaten by wrapping calls to the Encode module (and others such as Getopt::Long with calls to the Taint module to make sure that if a variable is tainted before it goes through the Encode module, it stays tainted after it comes out of the Encode module.

However, for me, an unexpected result of combining two great parts of Perl

Perl101: Simplified Abstract Methods

In my previous post (you should read it if you haven't), I eventually arrived at this:

Get real random numbers from Perl's rand()

On Stackoverflow, someone asks how to get 100 random numbers without a loop. It's one of those dumb homework problems that tries to forbid only one of many things instead of specifying the technique it really wants the student to practice. In Perl land, that leaves the door open for the sick and twisted minds of people such as Tom Christiansen and Sinan Ünür. I wonder if the teacher would even understand their solutions, much less accept them.

Many of the answers went to great pains to avoid certain Perl keywords while still creating loops. Some people debated if map is a loop. Some people used recursion, forgetting that every time you recurse in Perl, God kills a kitten. Maybe someday people will realize that recursion in Perl isn't the same kung fu they see in other languages. Perl actually must recurse because it has no way of knowing if it's going to call the same function definition.

Most of the solutions used Perl's built-in rand, which I think ignores half of the problem, the random numbers themselves. I use rand too, but I replace its definition to use the random.org web service to get lists of random numbers generated from atmospheric noise. Not only that, but I change rand in very sick and twisted ways, adding a list context.

Javascript scoping != Perl's

I'm doing a lot of jQuery of one of my current clients. Along the way I'm learning fun Javascript gotchas. Here's a demonstration of one scoping difference. Below the .change() event tied to bar works as I expected, but baz is a global variable.

function addARow() {
   var i = $('#next_id').val();
   var d = $("div"),                                      //COMMA then foo
   foo = $("<input>",{id:"foo" + i,size:"3"}).appendTo(d)
   .change(function() { bar.val($(this).val() * 2); })
   .change(function() { baz.val($(this).val() * 2); }),   //COMMA then bar
   bar = $("<input>",{id:"bar" + i,size:"3"}).appendTo(d);//SEMICOLON then baz
   baz = $("<input>",{id:"baz" + i,size:"3"}).appendTo(d);
   $("<br>").appendTo(d);
   $('#next_id').val(i - 1 + 2);   // + 1 would concat 1 onto the string  :)
};

See it in action here. jQuery creates a set of 3 input fields (foo, bar, baz) on each click of "add". When foo is changed by the user, bar and baz are updated. But the wrong baz gets the update.

Live and learn. :)

PgWest 2010

PgWest 2010

Day one was good. I learned about GUCS, sharding, backups and recovery. We met at Cafe Royale last night for a drink, courtesy of PostgreSQL Experts Inc and the San Francisco PostgreSQL Users Group.

Day 2 just came to a close. I got to hear Scott McNealy speak about a variety of topics. I learned about performance pitfalls, Node.js/Postgres.js, database-driven cache invalidation and the system tables. Lots of good info.

This evening EnterpriseDB is providing dinner and drinks at Harry Denton's Starlight Room this evening.

Help name my code! I am terrible at it.

I write a lot of apps that need a simple database. I tend to use SQLite, but I found I was implementing the same things over and over again. I finally started wrapping it up in a role that I can reuse, but now I'm stuck on a name. The role provides the following:

  • Database connect/disconnect
  • Automatic creation of db if it doesn't already exist
  • Transactions
  • Blocking locks (SQLite's locking kept biting me, so I worked around it using flock)


The name I picked out of the blue was DBIx::Cradle. It sort of makes sense, but I don't really like it. It is hardly an extension of DBI, so DBIx doesn't feel right, even though it does provide some general purpose database goodness. The Cradle part is supposed to mean it makes life easy and comfortable, but again, doesn't feel quite right.

Any suggestions? Any other similar modules I should look at?

PS: In case anyone remembers my earlier post about database abstraction, you might notice I'm backtracking a bit. These things happen. The comments pushed me away from that course of action, and this role has simplified things enough that I'm a lot happier now.

Perl101: Encapsulation via Protected Abstract Methods

Imagine you have an employee base class, but you know that the salary calculation will be different per employee type. You might decide to do this:

package Employee;

use strict;
use warnings;
use Carp 'croak';

sub new { bless {} => shift }

sub salary { croak 'You must override salary() in a subclass' }

1;

Listing All Installed Programs in Windows XP

I wanted to get a list of all the programs installed on my computer listed in 'Add or Remove Programs' in the Control Panel in Windows XP. Win32::TieRegistry provided a nice way to do this.

CPAN Testers Summary - October 2010 - Nine In A Pond Is Here

Back in January 2008 we were celebrating the one millionth post submitted to CPAN Testers. Although that article proclaimed it to be the one millionth report, many initial posts to the mailing list also included discussions and announcements of uploads. It wasn't until I created the Interesting Stats page that we started to see the true picture. However, we only had to wait until March 2008 for the real one millionth report to be posted. Now some 2 years and 7 months later we've had the nine millionth report submitted. It took 9 years to produce 1 million reports, but only a further 2½ years to produce another 8 million reports. The rate at which CPAN Testers has been able to get people involved in the project has been phenomenal. We are now submitting over 500,000 reports a month, so I have no doubt we will pass the 10 millionth mark before the end of the year .. probably just before Christmas :)

Marpa's Sudden Portability Adventure

I've made bold claims for the portability of Marpa. [ Marpa is a general BNF parser generator -- it parses from any grammar that you can write in BNF. If the grammar is of one of the kinds currently in practical use (yacc, LR(k), LALR, LL, recursive descent, etc.), this parsing is in linear time. ]

The boldness of my claims evinced no ambition to test them under fire. But, when my main development box (a 2-year Dell laptop running Ubuntu) suddenly died, my only other choice for a development platform was a MacBook G4 running Mac OS Tiger. So test my portability claims is what I had to do.

Not that my brags about portability had been without foundation. I upload development versions for cpantesters regularly. (By the way, to all of you at cpantesters: a big "thank you".) As far as the configuration, build and runtime environments went, I had a lot of reason to be confident.

My Programming-Related Todo List

Dave Rolsky posted his Programming-Related Todo List, and here's mine:

  • Make a proper programming-related to-do list
  • Write that new CPAN client I was talking about
  • I've been indexing BackPAN just fine, but I have to figure out a way to make all of the data available to people in a sane way. The plain text uncompressed data for about 140,000 distros is several gigabytes. I have half of a web service written, and even have mycpan.com to host it. I just need the tuits.
  • Get my CPAN stats and trending project going again. It used to be part of The Perl Review, but I just need to set up the cron jobs again and maybe use some prettier charting tools.

There are some modules that I want to write, or fool someone else into writing:

Internal redirects in Dancer

I really like the forward function in Catalyst. It lets you chain actions together and create a clean flow. I decided I want that in Dancer. We now have it.

Some background:
I was working with my brother on a project with Dancer. We wanted a client to be able to go to a personal demo page of the website to be able to try out editing features without destroying the actual website. The original (awful) code did this by copying all the (CGI) code into a different folder and making that available.

Our idea was to have a demo database that starts as a replication of the existing one and then can be mutated and twisted with editing tests. The data is no longer important, just that there's something to play with.

Using Plack to "Like" a Module on Facebook

We've made a couple of fun changes to cpan-mangler. First off, you can now "like" modules on Facebook:

mangler-facebook.png

Now, up and downvoting of modules would be a lot more useful, but this can be fun (and confusing for your friends):

mangler-facebook-like.png

Secondly, Lee Aylward added support for HTML::Highlighter:

mangler-highlighter.png

Thirdly, we've added a tweaked version of Jesse Thompson's CPAN Dependents Greasemonkey script.

mangler-search.png

If you've already got cpan-mangler installed, a "git pull" should get you going (you'll likely need to install some additional modules). If you haven't, you can clone the repo and get yourself started in just a couple of minutes. Have fun with it!

About blogs.perl.org

blogs.perl.org is a common blogging platform for the Perl community. Written in Perl with a graphic design donated by Six Apart, Ltd.