このページは大阪弁化フィルタによって翻訳生成されたんですわ。

翻訳前ページへ


Perlsphere - the Perl blog aggregator
The Wayback Machine - http://web.archive.org/web/20090714110838/http://perlsphere.net:80/

patspam.com: Ode to wgd and the command line

Doug just posted an ode to the Linux command line over at the Plain Black staff blog.

I've been getting a lot of joy out of the command line today too thanks to Graham's ridiculously useful WGDev. One wgd command that I only started using in earnest today is the ls command. In its most basic form, it lets you print out a list of assets on your site:


$ wgd ls /home

getting_started
your_next_step
the_latest_news
tell_a_friend
documentation
site_map

I added a bunch of extensions to ls today, the first one being a -r option that tells ls to recursively list assets. Given that this prints to STDOUT, you can pipe this into any other command line tool to manipulate the output. For example, to list all assets that have the word "you" in their menu title:


$ wgd ls /root -f "%menuTitle%" -r | grep -i you
Profile Account Layout
Inbox Account Layout
Friends Layout Template
Account Layout
Shop Account Layout
Contributions Layout
Default Account Layout
Layout
Your Next Step

(the -f "%menuTitle%" option above tells the command to output only the menuTitle property of each asset).

Under the hood ls is calling asset->getLineage(), so I exposed a few of the getLineage API options to ls.

For example, this is one way of getting a sorted list of Survey templates on your site:


$ wgd ls root -r --includeOnlyClass WebGUI::Asset::Template -f "%url% %namespace%" | perl -ane 'print "$F[0] ($F[1])\n" if $F[1] =~ m/survey/i' | sort
root/import/expireincompletesurveyresponses/expireincompletesurveyresponses (ExpireIncompleteSurveyResponses)
root/import/survey/default-answer-edit (Survey/Edit)
root/import/survey/default-feedback (Survey/Feedback)
root/import/survey/default-gradebook-report (Survey/Gradebook)
root/import/survey/default-overview-report (Survey/Overview)
root/import/survey/default-question-edit (Survey/Edit)
root/import/survey/default-questions (Survey/Take)
root/import/survey/default-section-edit (Survey/Edit)
root/import/survey/default-survey-edit (Survey/Edit)
root/import/survey/default-survey-summary (Survey/Summary)
root/import/survey/default-survey (Survey)
root/import/survey/default-survey-take (Survey/Take)
root/import/survey/default-test-results (Survey/TestResults)

While I was writing this post, Andy asked me to provide him with a list of all Carousel wobjects on a site we're working on. That's as easy as:


$ wgd ls -r root --includeOnlyClass WebGUI::Asset::Wobject::Carousel

The most useful option I added to ls is the ?filter smartmatch filter option. This option filters the results using an asset property of your choosing. Format looks like "%url% ~~ smartmatch", where "url" is the field to filter against, and "smartmatch" is either a Perl regular expression such as "/(?i:partial_match)/" or a string such as "my_exact_match".

For example, the following command lists all templates that include absolute urls. We generate the output to an html file so that someone can easily open all the links and manually review/remove the absolute urls:


$ wgd ls -r /root --filter "%template% ~~ /http:///" --includeOnlyClass WebGUI::Asset::Template --format "<a href=http://dev.localhost.localdomain/%url%?func=edit>%url%</a><br>" > links.html

links.html then contains:

<a href=http://dev.localhost.localdomain/style_01?func=edit>style_01</a><br>
<a href=http://dev.localhost.localdomain/style_02?func=edit>style_02</a><br>
<a href=http://dev.localhost.localdomain/style_03?func=edit>style_03</a><br>

...

One type of command that I can see myself using a lot in the future is the following, which displays all assets that are viewable to a specific group (in this case the "Turn Admin On" group, which has an id of "12″):


$ wgd ls -r root --format "%groupIdView% %url%" --filter "%groupIdView% ~~ 12"
12 root/import/newsletter
12 root/import/projectmanager/resource
12 root/import/wiki

Alternatively, you can use a variation of the above to list all assets that are NOT viewable to a certain group (or groups). This is great for finding assets that have accidentally been set to say, Admins, when you want them viewable by Registered Users. For example, the following command lists assets that are not viewable to the default "Visitors", "Everyone", or "Registered Users" groups:


$ wgd ls -r root --format "%groupIdView% %url%" | perl -ane 'print "$F[0] $F[1]\n" if !grep {$F[0] eq $_} qw(1 2 7)'
12 root/import/newsletter
12 root/import/projectmanager/resource
12 root/import/wiki

All of these commands take in the order of 1 second to run, which is a lot less time consuming than manually reviewing your site asset-by-asset. And if you incorporate them into your test suite, you can re-verify their output against your site policy/expectations whenever you like.

Alias's Journal: The email rules I've decided to go with for the Top 100

Alias's Journal

Thanks for everybody's input on my previous post.

In addition to the comments, I received another very interesting data point from an email with Tom Hughes, the IO::Zlib maintainer (currently holding #1 on the FAIL 100 list).

> It's showing up on my graph-weighted FAIL tracker as the number one
> source of problems at the moment.
 
Well if nobody tells me about these things I can't possibly do anything about them...

This email response is great, because it demonstrates an important factor in maintainership.

The people that don't talk to you are just as important as those that do.

It's very common in Open Source technical flame wars to see comments like the following.

"How can we possibly be expected to support people that never talk to us"

And it's true, you certainly can't provide a truly personal level of support, and fix the bugs that are specific to them.

But when it comes to specific design decisions where you need to choose one way or the other, it's still extremely important to weight the benefits and costs to your entire user base equally, especially the people that are too busy, too low-skilled or just too shy to speak for themselves.

People that respond are going to be skewed to the people with the highest level of interest, and decisions on the level of control and freedom you allow for those people needs to be treated orthogonally to decisions you make on the DEFAULT behaviours that people without enough time or knowledge to contribute will have forced on them.

So in light of the mixed responses from the comments, and the note from Tom, I'm planning on going with the following email rules.

1. Only the owners of the top 10 FAIL modules will even be emailed.

2. Initially, I'll be emailing weekly. That might be too often, we'll see.

3. I shall attempt to track your position in the Top 10 and ONLY send a new mail if your position on the list increases. I'm not sure how useful this will be in practice, but we'll see how it goes.

4. I'll look into sucking in the email preferences from CPAN Testers, so if you have set emails to be ignored there, you'll also be ignored here.

5. If you make it all the way to #1, I'm going to ignore your preferences and email you anyway (once of course, since you can't get a position any higher).

I'll kick this off in a few weeks, and we'll see how it goes.

Perlbuzz: Test::Pod 1.40 now checks for illegal L<> constructs

It will be interesting to see what, if anything, barfs because of the new Test::Pod.

This POD construct is illegal according to perlpodspec, and will not be formatted correctly on search.cpan.org, either:

L<perlbuzz|http://perlbuzz.com>

Test::Pod catches it now. My wonder is how many people are using it.

Test::Pod also requires Perl 5.8 now, and I'd like to think that pretty much every module on CPAN could use modern Perl versions at this point.

Alias's Journal: Is it right to auto-notify authors, if there aren't many?

Alias's Journal

Dear LazyWeb.

The FAIL 100 list has been working reasonably well, but one crucial downside at the moment is the need for people to actively monitor it (both those that are aware that it exists, and those that don't know it exists).

While I certainly agree that it is a bad idea to spam authors in general (I'm certainly for opt-in CPAN Testers summaries and emails) does this still hold true when you are identifying only a small number of authors.

Would it be ok to auto-email the Top 10 positions on the FAIL 100 list, say, each week to let them know their module is considered to be important to fix quickly?

What if it's just the first time it appears, and on subsequent sequential appearances we don't email you.

What if it was the top 5? Or the top 2? Or top 1? Or only if you met a certain threshhold of FAILure score? Or it was at a wider interval, say, monthly?

When is it ok for a whole-CPAN process to judge that an author needs to be nudged?

Shlomi Fish: ????? ???????? ???? ?????? ???????? 2009

????? ???, ????? ?????? ??????? ???? ????? ????? ???? ????? ????? ????? ?????? ?? ??? ?????? ????????. ???? ?????? ???? ???? ????, ?-7 ??????? (2009), ??? ?????-08:30 ????? ?????? ???? ?? ???? ?????. ?????? ???? ???? 30 ????? ???? ???? ?????? ????? ????? ?????? ???????? ??????? ?? ?????? ????.

?? ?? ???? ?????

The Onion Stand: View your templates' structure as a graph

View your templates' structure as a graph
Some very nice visualization tools have emerged on CPAN lately, such as melo++'s MojoX::Routes::AsGraph and franckc++'s CatalystX::Dispatcher::AsGraph. Now, be it Catalyst, Mojolicious, Titanium, Jifty or whatever Perl web framework you use, you most likely use abw++'s amazing Template Toolkit for rendering your site. So I really missed something that would help visualize and untangle the usually complex template structure on a complex website. If you feel that way too, wait no more! :)

use Template::AsGraph

my $graph = Template::AsGraph->graph('mytemplate.tt2');


That's about it. You can also pass TT's configurations and even variables that might mangle with template flow:

Template::AsGraph->graph('template.tt2', \%config, \%vars);

This even lets you get the actual output of the template processing in case you want it as well (you do this with the OUTPUT setting on your config hash, btw).

The result? See for yourself:



Dev code's on github, and the first release should arrive at your local CPAN mirror anytime now.

Let me know what you think!

Sebastian Riedel - Perl and the Web: Graphs!

Pascal Gaudette has done some very cool graphs about the finite state machines we used in Mojo to implement the HTTP 1.1 protocol.

Perlbuzz: Perlbuzz news roundup for 2009-07-11

These links are collected from the Perlbuzz Twitter feed. If you have suggestions for news bits, please mail me at andy@perlbuzz.com.

  • Tim Bunce surveys customer relationship management systems in Perl (blog.timbunce.org)
  • Sending mail through Gmail with Perl (nixtutor.com)
  • From the DarkPAN: "The Perl community should move forward without worrying overly much about us that have to drive in the slow lane." (use.perl.org)
  • rgs's blog post about his resignation as bleadperl pumpking (consttype.blogspot.com)
  • How we should address the DarkPAN problem (perl-toddr.blogspot.com)
  • I think chromatic's points boil down to TAGNI: They Ain't Gonna Need It, where They is the unknown DarkPAN. I'm inclined to (agree.)
  • Patrick Michaud is looking for Rakudo release managers (use.perl.org)
  • perl/vendor/site explained (use.perl.org)
  • Top five non-technical mistakes made by programmers (makinggoodsoftware.com)
  • Six modules to help with complexity management (use.perl.org)
  • Test::Pod is now on github. Bug fixes welcome! (github.com)
  • CPAN Explorer gets props in Visual Complexity (visualcomplexity.com)
  • Upgrading Debian packages with newer CPAN releases (use.perl.org)

Ricardo Signes: current project status braindump

Lately, I have a lot going on. I think I need to recalibrate my "very busy" alert, because I feel like it's been going off for months, now. Still, things are okay. Here's a bit of a dump on some things I'm working on or should be working on.

Data::GUID

I'm definitely behind schedule on getting Data::GUID refactored to allow different generators and objects, which will allow a pure-perl backend (currently UUID::Generator::PurePerl) when XS isn't available. This is mostly done work, but it needs testing, polish, and some design thinking.

Email::MIME::Kit

I'm really not happy with the way the standard Assembler class works. It does too much and is too hard to extend without reading its source. I need to refactor it, document how it works, and maybe break it into a few pieces. So far, I've avoided this by writing all my extensions as around method modifiers. This has been quite effective, actually.

META.json

I started to do some work on PAUSE to get it to respect META.json, but I need to work on getting some things integrated, and other things coded and committed. Once that's done, the indexer will be able to index based on META.json, which is huge. Next up will be CPAN.pm and CPANPLUS.pm, which I hope will not be to hard to work with. Once those parts of the toolchain can all consume META.json, I can start working on getting my hacks to emit META.json into all the dist building tools -- preferably after making them not be hacks.

At some point in all this, we'll get to "make JSON.pm part of core perl5."

Other Email Stuff

I really need to fix Email::Valid's tests to skip the DNS tests when coping with obnoxious ISPs that provide "helpful" lies to DNS resolvers. will-never-exist.pobox.com does not exist, and if there's an A record for it, then the DNS resolver is lying. (Of course, this also means that anyone using the "domain part must have A or MX record" rule is going to have false positives on validity checks.)

Honestly, I can't think of any more irritating change in basic ISP policies in the last few years.

There are some other bugs with Email::Valid, too, regarding how it uses Mail::Address. I'm pondering writing a new Email::Valid that does all the same stuff, a little better, and with a less unusual interface. It would be nice to be able to easily subclass it to add more checks, like is_address_in_use or contains_forbidden_characters for application-specific use.

Heck, maybe I can use Classifier for this, since the new bounce parser is still on the back burner, four years later.

Pod::Weaver and Friends

Basically, I've decided I don't have the time to think about them this week. This is disappointing, but I'd rather put it off a week than make bad decisions because I'm brain-fried.

OSCON starts next week, and I'm hoping to have plenty of down time to work on ideas and implementations. OSCON is generally, for me, much lower-stress than YAPC. I think I will get a lot of hacking done, and if I don't, I will get a lot of flowcharting done, and for me that's half the battle.

Finally...

I've also been thinking a lot about structured data storage, ultra-easy git helpers for small companies, portable testing, pluggable testing, and Rx. I keep improving our little git scripts to keep track of our internal git repos, and I think at some point I might have something I can describe as a reproduceable ecosystem. Rx really needs me to finish the structured failures branch, which will be phenomenally useful. A lot of that work will be related to the testing stuff I'm thinking about. (I would love to write up a comprehensive appraisal of Ingy's TestML, which I talked to him about quite a bit during his development of it.) The structured wiki stuff is largely about my desire to use something better than Obsidian Portal for my D&D game. I should probably write up both what I want and why I don't care much for Obsidian Portal!

For now, this has just been an exercise in collecting my own thoughts. Maybe tonight or tomorrow I'll actually do a little work on some code. Then again, maybe I'll do some yard work instead.

Alias's Journal: Help needed from Germans and Solaris users

Alias's Journal

In taking over IPC::Run, my goal was not to make it a better module, refactor it, or otherwise dramatically improve it. I'm just trying to fix the module packaging, and get it passing tests (fixing either specific bugs, or correcting the tests).

I've now managed to flush out all the Windows problems, and all the bugs on platforms I can replicate.

Now I'm stuck, and can't make any further progress. I don't have access to the platforms on which the problems occur.

So I'd like to ask for any volunteers that can help fix the two big failure cases.

The first is a bug specifically related to Solaris. You can see details of the failure here.

http://www.nntp.perl.org/group/perl.cpan.testers/2009/07/msg4535302.html

The second is something related to locale, with all the current failure reports occurring on Linux machines set to the German UTF8 locale.

http://www.nntp.perl.org/group/perl.cpan.testers/2009/07/msg4534455.html.

RT has bugs reported properly for the latter one, but I can't fix it.

What I need for both these bugs is either a patch for the code to fix the bug, or a patch for the tests if you can confirm the test is invalid.

Or even better, I'm happy to hand out commit rights for people to apply the fixes directly.

dagolden: If I were (pump)king

It’s fun to speculate “what if” on all the radical changes I’d want to make, but really, if I suddenly became pumpking, my first thought would probably be “Oh, sh*t… I better not f*ck this up!”

That’s right.  All my JFDI inclinations would probably change overnight into DFIU.

What If I released a horribly broken Perl?  Do I want to be known as “worst pumpking EVAR!”?  Do I want that hanging over my head for all time?  Do I want to go to a Perl event and be pointed out to newbies as “the guy who screwed up Perl”?  Do I want it on Wikipedia or Yahoo or Google when I apply for jobs?  Hell, no!

If I were pumpking, I’d be so conservative I’d make Newt Gingritch look like the mayor of San Francisco.

But I’m not pumpking and so I advocate for change and faster progress. Still, I have a lot of empathy for the reality of the situation that pumpkings are in.1  I think it’s a situation that is probably unavoidable when one individual signs up to be accountable for the success or failure of a large, public project.

I think the answer ― to the extent there is one ― is that Perl needs to find ways to spread the potential blame beyond a single figurehead and also lower the public penalty for failure.

That means fragmenting accountabilities in constructive ways that don’t jeopardize overall progress.  It means having more explicit sandboxes for experimentation.  It means taking smaller steps.  It means having better risk management.  And, frankly, I think it means having better management as a whole.

That’s hard to contemplate for a consensus-driven community of volunteers. But I think it’s a necessary step to achieve what appear to be some consensus goals. I’m not saying we need a constitutional convention (though it’s an interesting thought exercise), but I think the current model passed a tipping point long ago.

In some future posts, I’m going to come back to these themes from a number of angles and try to put some structure around what I see as the fundamental issues and options.  While I don’t think there should be changes until 5.10.1 is released, I think it’s wise to start laying out the framework for a constructive dialog in the future.

  1. Volunteered to be in, no less

Blog of G?bor Szab?: Padre standalone installer for Windows - first beta version

Curtis Jewell has already announced it on his own blog but as he said his blog is hardly read and is not included in the various Perl blog aggregators I promised to also write about it and link to his post.

so the first beta version of the stand-alone Padre msi installer is ready. It still is only an enlarged version of Strawberry Perl so it install in c:\strawberry but it is a huge step in the direction of making it easily available to the general public of Windows users.

So if you have a windows box, go ahead, download Padre and tell us about it via the standard channels of Padre, the Perl IDE

Hinrik's blog: Half way there

With Summer of Code’s mid-term evaluations coming up, some interesting things are about to happen to grok. I was contacted by Herbert Breunung, author of Perl6::Doc (formerly Perl6::Bible), which is a project that shares some of grok’s goals.

He told me that he doesn’t have enough time to maintain his project anymore and would like some sort of merge to happen. I said I’d look into it. His project bundles all the Synopses, Apocalypses, Exegeses, and some other Perl 6 documentation, and ships with a perldoc wrapper for reading them. What I would like to do is to move all documentation out of the grok distribution and update/add more to Perl6::Doc while eliminating the perldoc wrapper (in favor of grok).

He also brought to my attention the Perl Table Index, a sort of Perl 6 glossary. Ahmad Zawawi has just patched his Padre::Plugin::Perl6 to feed this index to grok. I will probably port the Perl Table Index to the Perl6::Doc distribution and make grok look things up in it.

I’ve started writing a Pod::Text subclass as well as amending Perl6::Perldoc::To::Ansi to conform to a consistent color scheme when using the default ANSI-colored output.

Something which grok should eventually be able to do is recognize arbitrary Perl 6 syntax (at very fine level of granularity, that is) and tell you what it means. A first stab at this will be to simply include a table of some common ones and look those up. Stuff like ‘my‘, ‘+‘, and so on. Doing this reliably is the original inspiration for the u4x project (Userdocs for Christmas), of which grok is a part.

I hope to make a release of grok and Perl6::Doc shortly which will include all of the above.

Ovid's Journal: Empty Classes

Ovid's Journal

We have many objects with common attributes like titles, synopses, versions, created/modified, etc. Due to business requirements, every exposed object must have a searchable unique ID called a "pid". Thus, we've been forced to do a rather unfortunate denormalization where every pid is placed in an entity table. This table also lists the object types (brands, series, episodes, etc.) and you can look up any pid and get the object it stands for from the appropriate object type. One benefit of this is that it was (relatively) trivial to strip all titles off of objects, put them in a central "title" table, and allow arbitrary title searches and get back all objects, regardless of type, which have matching titles.

We're now doing this with versions. We'll probably do this with synopses at some point. Because every object links into the entity table, we have standard searches available for many things. If we were to take this to the logical extreme, we could do something rather interesting. We could create an object called a "preview" (we have no plans to do so), which has titles, synopses, promotions, tags and parent (the thing we're previewing) and do this:

package BBC::ResultSource::Preview;
use Moose;

extends 'BBC::ResultSource::Role::ResultSource';
with qw(
    BBC::ResultSource::Role::Titles
    BBC::ResultSource::Role::Synopses
    BBC::ResultSource::Role::Promotions
    BBC::ResultSource::Role::Tags
    BBC::ResultSource::Role::Parent
);

And with that, have a new object. Effectively, you could have a completely empty class aside from the roles being listed. The preview table might only have an id and nothing else. How would we build the XML for this? Pseudo-code:

package BBC::Builder;

use Moose;
with 'BBC::Builder::Role::DoesBuilder;

sub build {
    my $self = shift;
    my @build_data
    foreach my $role ($self->resultsource_roles) {

        # following a predefined sort order
        next unless $self->meta->does_role($behavior);
        push $build_data => $self->build_data_for($role);
    }
    return \@build_data;
}

No longer would we need to explain how separate objects are built as XML and we'd have greater consistency in our XML building. Of course, this is still "blue sky thinking", but it would tremendously simplify a lot of our code.

(Note: I know I can just ask the metaclass directly what roles that instance does, but I thought the does_role() method call would show readers more clearly what would happen under the hood.)

J?r?me Quelin: prettyfying tk apps

prettyfying tk apps
one of the main griefs people have against tk is the fact that it looks ugly. however, it's possible to tremendously enhance tk with only one line. indeed, tk by default uses a 2 pixels wide border, which does look fugly.

here's a snapshot of config::model (used as an example):


now, try to insert the following line in your code:
$mw->optionAdd('*BorderWidth' => 1);



here's the result, still using config-model as guinea pig:


look at how the buttons are crisper... now that's better, uh? :-)

thanks to ala qumsieh who first reported this tip on perltk.org - but the site seems to be down nowadays.

note: i'm told that tk 8.5 can be themed and looks native. but i'm still using perl/tk which is build against tk 8.4

Modern Perl Books, a Modern Perl Blog: A Stupid Experiment in Reliability and Maintainability

Advocates of strict typing systems often tell the reliability bedtime story when explaining why looser type systems give them the howling fantods. They're not entirely wrong, either.

Quick, what's the problem with this Perl code?

no strict 'refs';

*{ $classname . '::' . $subname } = sub { ... };

Don't worry if you don't get it immediately. It's subtle: within the body of the anonymous sub, you have to enable strict reference checking or Perl will silently ignore any symbolic references.

Maybe that's not a problem for the person who first wrote that code. He or she knew exactly what to write and made no typos. Great! I wish I were that careful and fortunate.

I can think of very few reliable, maintained Perl 5 programs which don't have strict enabled in the broadest scope. Our community practices and our tooling and our default idioms (whether enabled by language or convention) shape the way we think and behave.

Now imagine what might happen six months later when someone else (or the original developer) needs to make a change to that code. Would you remember that strict 'refs' is off in that code? (I believe I owe credit to Joshua ben Jore for first mentioning this problem; it's an example of a poorly recognized problem from the Tower of Defaults.)

The solution in this case is to ensure that loosening strictures occurs in the smallest sufficient possible scope. A similar principle exists for both physical and virtual security. A better version of that code might be:

my $subref = sub { ... };
{
    no strict 'refs';
    *{ $classname . '::' . $subname } = $subref;
}

Not only does the tight scoping limit the effects of disabling strict references, it gives visual cues to maintainers that something different is happening. Proceed with mindfulness. This is even a user interface principle: make exceptions obvious.

Rafael believes that strictperl is a broken idea, so immediately obviously bad that it's suitable only for a source filter. One of his gripes is that it does not run the vars pragma nor Exporter unmodified.

He's right. It unrepentently does not.

Rafael says that the "very purpose [of vars and Exporter] is to manipulate symbols by name, which is exactly the kind of thing that strict prevents." He's right about that too.

Follow those links, though. Look at the implementations of Exporter and vars. Count the lines of each that absolutely cannot run with all strictures enabled. Count the remaining lines.

Done? Great. Now tell me with a straight face that foundational core libraries that have been in Perl 5 for fifteen years are paranoid enough.

These modules do not have to break under strictperl. They could run unchanged (as far as everything else which uses them notices). There are no backwards-incompatible changes by modifying them to disable strictures in the smallest necessary scopes.

If strict is useful enough that you use it in all programs you expect to maintain, if you believe it protects you against problems you didn't expect, even if you have a copious test suite, tell me that it's not worth even asking if it's useful for the more than 90% of code in vars and Exporter (just as examples) that does not need to disable strictures.

You may believe that this is a silly, dumb, useless experiment I've wasted my time writing C and portable Make rules when I could have written a frivolous little source filter. You may be right. Feel free to ignore it, mock it, file bug reports about it, whatever you like.

Yet I believe this stupid little experiment may be useful -- not just for people who want to practice exception-based strictures (strict by default: exceptions as necessary) but also for people who would like to make future problems even less likely to occur, especially in Perl 5's core library itself. (Isn't that one great way to measure maintainability?)

Limiting the scope of loosened strictures is by no means the only way to improve the reliability and maintainability of serious programs, but why not take advantage of the possibility to do so?

Modern Perl Books, a Modern Perl Blog: strictperl

As I mentioned in Why corehackers Matters, the ability to fork and modify your own version of bleadperl -- and perhaps get it merged back into Chip's staging tree -- opens a lot of room for experimentation.

I alluded to a minor feature branch I've worked on for a couple of days: unilaterally enabling strict for all code not run through -e. This is available from my strict_by_default bleadperl tree on GitHub. You're welcome to download it, play with it, fork it, submit patches, or do whatever you want.

If Perl is a Shinto shrine, forking is an act of love... provided there's a merge sometime in the future.

Playing with strictperl

To build strictperl, first clone my bleadperl tree from GitHub. Check out the strict_by_default branch:

$ git clone git://github.com/chromatic/perl.git
$ cd perl
$ git checkout origin/strict_by_default

Then configure and build Perl as normal:

$ sh Configure -de -Dusedevel
$ make

This will build the familiar perl binary. Now build strictperl:

$ make strictperl

This will build a separate binary named strictperl. If I've written the code (and especially the Makefile rules) correctly, these will be two completely separate binaries with different behaviors:

$ ./perl       -e 'print $c' # no error
$ ./strictperl -e 'print $c' # no error

$ echo 'print $c' > printc.pl
$ ./perl       printc.pl  # no error
$ ./strictperl printc.pl
Global symbol "$c" requires explicit package name at printc.pl line 1.
Execution of printc.pl aborted due to compilation errors.

You can use strictperl in place of regular perl any place you like... except that several core modules are not strict safe. In particular, Exporter and vars are the first two problematic core libraries.

Similarly, any module which does not use strict may have strictness errors when running under strictperl.

I don't think that's a bad thing, however; think of it as an opportunity to make lots of code strict safe even if it doesn't use strict right now. (You could argue "Why in the world would you ever want to touch all of that code for no benefit?" You can also argue why you'd want to make your C code lint-safe, or run Perl::Critic on a codebase.) These "errors" may not be errors in practice, but if we evaluate them all, we can note declaratively in our source code that we've considered each one carefully and avoid further potential maintenance problems. Right now strictperl is an experiment and a tool to help us identify these situations.

Patches and pull requests very welcome to help patch up the core modules for strict safety.

How it Works

strictperl works by changing the default hintset of nextstate nodes in the Perl 5 optree.

Don't be scared. The implementation is slightly ugly (thanks to the way strict itself works), but it's much less invasive or difficult than rewriting optrees as something like Devel::Declare must do.

If you look in the strict pragma, you'll see several auspicious lines:

my %bitmask = (
    refs => 0x00000002,
    subs => 0x00000200,
    vars => 0x00000400
);

# ...

sub import {
    shift;
    $^H |= @_ ? bits(@_) : $default_bits;
}

This code ORs together a bitmask of all of the strict features you've requested and toggles them on in the magic $^H pseudo global variable. These constants correspond to three constants #defined in perl.h:

#define HINT_STRICT_REFS    0x00000002 /* strict pragma */
/* ... */
#define HINT_STRICT_SUBS    0x00000200 /* strict pragma */
#define HINT_STRICT_VARS    0x00000400 /* strict pragma */

These hints are part of a particular type of node in the optree called a COP (control op, I presume). These are always nodes of type nextstate; you see them often when you use B::Concise, for example:

$ perl -MO=Concise
print "Hello, world!"
6  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -:1) v:{ ->3
5     <@> print vK ->6
3        <0> pushmark s ->4
4        <$> const[PV "Hello, world!"] s ->5
- syntax OK

Each COP contains information about the package and line number of the Perl code the next ops represent, as well as hint information such as which strict pragma features are in effect. (They contain more information as well.)

When you modify the hints through $^H, you modify the flags in the previously-executed nextstate op. (If you're very curious, see the cop_hints member of the cop struct in cop.h.

There's a complicating factor. nextstate hints nest in a similar way that lexical scopes nest. If you enable strict in an outer scope, its effect remains in place in inner scopes unless they explicitly disable it.

That's actually fortunate, in this case.

I knew that enabling strict meant setting the appropriate hints flags when building COP nodes in the optree. That meant modifying Perl's parser. My original approach was to modify the function used to create new COP nodes, a function named newSTATEOP. That's where I discovered the pseudo-inheritance scheme which allows strict nesting. (I admit that I don't understand all of its implications).

After a couple of blind alleys, I realized that the only way to enable strict pervasively was to find the creation point of the parentmost COP node in the optree and set these hint flags there.

Perl 5 uses a top-down parser; it starts by matching the most general rule and descending into subrules to try to build a whole program. The topmost rule is prog; a program matches the progstart and lineseq rules. progstart is simple:

progstart:  { PL_parser->expect = XSTATE; $$ = block_start(TRUE); };

You can ignore the contents of this rule. The important point is that this is the first rule matched in a program -- a file, actually.

There's one more piece of the puzzle. If you look in the implementation of the newSTATEOP function, you'll see that it uses a globalish (interpreter-local, anyhow) variable PL_hints to set the hints flags on the newly-created COP:

    CopHINTS_set(cop, PL_hints);

Thus my patch is very simple; progstart now reads:

progstart:
        {
            PL_hints |= PL_e_script ? DEFAULT_CLI_HINTS : DEFAULT_PROGRAM_HINTS;
            PL_parser->expect = XSTATE; $$ = block_start(TRUE);
        }
    ;

PL_e_script is another interpreter-local variable which contains the text of code run with -e. It's empty unless the invoking command line used the -e flag. DEFAULT_CLI_HINTS and DEFAULT_PROGRAM_HINTS are new constants I added to perl.h:

/* which hints are in $^H by default */
#define DEFAULT_CLI_HINTS 0
#ifdef STRICTPERL
#   define DEFAULT_PROGRAM_HINTS \
               HINT_STRICT_REFS | HINT_STRICT_VARS | HINT_STRICT_SUBS
#else
#   define DEFAULT_PROGRAM_HINTS 0
#endif

I made them conditional on the STRICTPERL symbol for one specific reason: the compilation rules I added to the Makefile to build strictperl define -DSTRICTPERL and rebuild the Perl 5 parser. Thus the DEFAULT_PROGRAM_HINTS constant enables all strictures only when building strictperl.

(Yes, cautious Makefile hackers, those rules clean up after themselves so that the relevant files always get rebuilt when building strictperl and get removed after building strictperl so that any subsequent non-strictperl builds do not use object files with the wrong constants defined.)

The hardest part of this whole process was getting the Makefile rules right. I'm not quite sure they're cross-platform enough, but they work with my testing.

The Value of strictperl

Was this process worthwhile? It was entertaining. It gave me the chance to write code to implement a feature I believe is worth considering. It helped me understand the optree in a bit more detail. It gave me a good opportunity to explain some of that here.

Perhaps the best result of this process is that we now do have a Perl with strictures enabled by default. We can experiment with that to see how writing code works in this case. Admittedly there's a lot of work necessary to make core libraries play nicely with strictperl, but we can do that in pieces because this is an optional feature you have to enable by default, one which does not interfere with regular perl.

Those are the kinds of experiments I want to encourage.

Blog of G?bor Szab?: The Success of Ubuntu

In a previous post I wrote about The Ubuntu Business model and Perl. This is the second part of that post trying to look at what made Ubuntu successful, how can that be mapped to Perl and what can the Perl community learn from there.

The success of Ubuntu

We can understand from the previous post that the Perl community cannot copy the business model of Canonical, the company behind Ubuntu so let's look at how did Ubuntu succeed in becoming one of the leading GNU/Linux distributions in such a short period of time. I searched a bit and found a couple of explanations. I am sure some people will say they are not true or that they are not the reasons for the success of Ubuntu and I am sure there are others who will point at other explanations. So let's take this as my subjective list with my subjective explanations.

I'll go over the points and try to relate them to Perl and the Perl community.

On Ubuntu Innovations the author points to the following reasons:

  • Simple install
  • Regular release schedule
  • Live-CD that you can install from
  • One application for each purpose
  • Secure by default
  • Over 20,000 applications can easily be installed
  • Include non-free hardware drivers
  • Made the color brown sexy
  • Get an Ubuntu CD for FREE
  • The Ubuntu Community
  • Simple install: Perl comes built in on almost all the Unix like Operating systems. ActivePerl and now Strawberry Perl provide easy installation on Windows as well. What IMHO Perl is missing is a set of distributions for some some of the operating systems based on the idea of Strawberry Perl. Similar to how ActiveState has distributions to several platforms but with the Strawberry philosophy and with a lot more juice.
  • Regular release schedule: Here Perl clearly has a problem. I hope it will be fixed now that the development moved to Git. It does not have to have exactly time based nor do the releases need to be earth shattering but a minor update every 3-6 months could help improve both the image and the level of real users testing perl.
  • Live-CD that you can install from: This is mostly irrelevant as Perl does not replace the Operating system. It can be installed on any major Operating system. Actually the Portable Strawberry that can be installed on a disk-on-key might provide a nice demo-ing kit.
  • One application for each purpose: That's another problematic area of Perl and more specifically of CPAN. In my opinion people like to have choices but don't want to choose. We should improve the situation as people waste a lot of time searching CPAN and I am sure in many cases find a module that is far from the preferred modules of any of the active CPAN authors. There are many partial projects that are trying to address this problem.
  • Secure by default: I don't know about any issues in this regard.
  • Over 20,000 applications can easily be installed: There are 17,000 modules on CPAN. Many of them are easily installable but many others have problems. I think this areas is both a success (as CPAN has so many packages) but also needs improving such as perl version and platform aware installing tools and allowing several possibly incompatible trees of the same distribution 1.x, 2.x etc versions)
  • Include non-free hardware drivers. That's ok, there are modules on CPAN to many proprietary systems. (e.g DBD::Oracle) What might be interesting is to include them in Strawberry Perl or the other future Linux/Unix Perl
  • Made the color brown sexy Camel ? Onion ? I don't know what to say.
  • Get an Ubuntu CD for FREE IMHO that's quite irrelevant to Perl and actually that is one of the only places where Canonical invested money. Though I am not sure that was a large chunk of their investment.
  • The Ubuntu Community - The Perl community is quite awesome though there are places to improve. Let's discuss this a bit further

Perl Community

The Ubuntu project has written directions on how to behave. While many of the entries are obvious it is worth to take a look at both the Code of Conduct and the Leadership Code of Conduct.. The points are:

  • Be considerate.
  • Be respectful.
  • Be collaborative.
  • When you disagree, consult others.
  • When you are unsure, ask for help.
  • Step down considerately.

I'd especially point out the last entry. We have tons of code out there, application and modules on CPAN and in many other places. Some of this code, actually quite a large part of it is more or less abandoned. The original developer or last maintainer has mostly disappeared and there was no real process of handing over the code to others. There is a process in which others can take over a module even when the author is gone but I think it would be much better if the authors took it as their responsibility to transfer the modules they don't want to maintain any more.

I know the way this usually happens is that the person slowly has less and less time and keeps telling himself, that soon he will return to that code... so its not easy. We as the community should work on it.

7 reasons of In another article called The 7 reasons why Ubuntu is so successful I found the following reasons:

  1. A good start (vision ?)
  2. Easy and straightforward installation
  3. ShipIt
  4. Synaptic
  5. Ubuntu forums/Community
  6. User promotion
  7. Fragmented competitors

with the following comments I would highlight:

  • Promotion of Ubuntu through media and freeCDs
  • Synaptic was really impressive, and not having to download package information from the net every time i do a search was good

These are mostly the same reasons as we read earlier. Let me point out a few issues:

For those who don't use Ubuntu or don't know what it is, the Synaptic Package Manager is basically a graphical version of CPAN.pm for all the packages distributed by Ubuntu.

It would be probably better if Perl also had a graphical tool to install CPAN packages. (In Padre we are going to have one.)

User promotion. Perl got into many places by enthusiastic people who started to use it to solve problems. We should help these people more.

So what do you think, what does Perl need to be more successful in companies and how can we achieve that?

Just another lambdabananacamel: A brief note on technical translation: Jay Kuri’s Gentle Introduction to Moose

While we were discussing how to promote the Italian Perl Workshop, and the planned training on Moose, I noted that there weren't any articles on Moose (Perl's modern OO implementation, inspired by CLOS, Smalltalk and Ruby) on perl.it. Lordarthas of course told me "well volunteered!"... oops.

I pointed out that I don't really know Moose, and we eventually agreed that I would "just" translate Jay Kuri's nice new Gentle Introduction.

Now, there is a reason why translators almost always translate into their native language. I can write in Italian reasonably well, but translating into it was a much harder task. While you're writing something yourself, you tend to route around phrases you don't know how to express, choose different words, simplify structures, etc. But translation implies some degree of fidelity to the source, and I found this incredibly hard going. I whined on #perl.it and, in true Open Source JFDI style, larsen asked "Huh? Why are you translating that?" and did it himself! Yay, larsen++!

So my volunteering ended up being limited to making a few corrections/suggestions, along with lordarthas, dree, and dada. Opensource translation and review (using wiki/email in this case, but a git repo or similar could work just as well) can have a fast turnaround, and pick up many errors/nuances that a lone translator would have to work really hard on to do by themselves.

An interesting problem with the technical translation was deciding which phrases to leave in English, and which to translate. Looks like "coercion" is staying in English (followed by an explanation) instead of using the Italian "coercizione". And the title is surprisingly hard to translate, as none of the words for "gentle" map well into Italian. Though it's less cute than the original, the least awful alternative seems to be "Una breve introduzione" (a brief introduction).

The final translated article is now on perl.it!.

Blog of G?bor Szab?: Padre 0.39 released

I am happy to announce the release of v0.39 of Padre, the Perl IDE.

The list of changes as taken from the Changes file.

  • Some of the refactoring code was moved to PPIx-EditorTools (MGRIMES)
  • Detection of Moose attributes in Outline view (JQUELIN)
  • Detection of MooseX::POE events in Outline view (JQUELIN)
  • Added keywords to META.yml (via Makefile.PL.) (SHLOMIF)
  • Bumped the required Test::More version to 0.88 - needed for note(). (SHLOMIF)
  • Open Selection (ctrl-Shift-O) now displays all the files it finds and lets the user select (SZABGAB)
  • Eliminate crash when pressing F3/F4 while there are no open files (#421) (SZABGAB)
  • Enable/Disable Window menu options when there are (no) open files. (#417) (SZABGAB)
  • For Cut/Copy/Paste/Select All, use the focused textctrl instead of the editor textctrl (RSN)
  • Autoupgrade ascii files to be utf-8 on save if user types in wide characters (#304) (SZABGAB)
  • Allow the user to use external (xterm) to run the scrips. (SZABGAB)
  • Add menu option to show selection as hexa or as decimal. (#36) (SZABGAB)
  • Switch to Locale::Msgfmt and generate the .mo files at install time (RSN)
  • Add number of lines to GoTo line dialog (#439) (SZABGAB)

Soon it should arrive to a CPAN mirror near you.

Enjoy and thanks to all the people who put effort in Padre!

Alias's Journal: The CPAN Top 100 website has been upgraded to CPANDB

Alias's Journal

Completing 2 weeks of fairly heavy refactoring, rewriting and debugging of various toolchain elements, I'm happy to report that I have now removed the (faulty) CPANTS dependency graph from the CPAN Top 100 website and replaced it with the highly accurate CPANDB dependency graph.

This is huge relief for me, because all the highly visible bugs that were preventing the concept from progressing to full maturity.

The change to reliable data has meant a few major changes to the results.

1. The falsely inflated scores go away.

CPANTS seemed to have an issue misattributing modules to the correct distribution they came from. For example, it thinks that DBD::SQLite lives in the DBD-SQLite-Aggregation distribution.

Fixing this has caused a big shuffle at the top. "perl" now sits proudly at the top of the table, all the hardcoded exceptions are gone, the counts have zoomed up 10% as better linking was able to be made, and a very surprising #2 position that I originally thought was a bug is confirmed to be correct.

Yes, a text wrapping module is the most depended on thing in the CPAN! :/

2. Author attribution is now correct.

The CPANTS implementation appears not to understand the concept of changing maintainers. As a result, many CPAN modules that had changed hands were showing as being maintained by the original author.

With this corrected, you should now be able to accurately see who you need to annoy to take over a failing module.

3. DBD::mysql is no longer an OMGIBROKECPAN event.

Granted, the PASS vs FAIL counts for DBD::mysql are horrible. But the graph now does NOT consider the mysql driver to be as important as it previously did, which has dropped the FAILure score for it down to a lower one.

4. A new module appears at the top of the FAIL 100

I don't know where it was hiding (presumably as an embedded copy in someone else's distribution), but IO::Zlib has made a surprise jump to the top of the FAIL 100 table.

Please commence the poking and prodding of the author to take it over or fix it :)

What's next?

With the underlying data now correctly in place, I can start to address the extremely simple nature of the website itself. I wanted to delay any more work on creating new metrics until the current ones were no longer broken.

So hopefully I can now begin adding new Top 100 tables, and start to move the website towards something that will work better as a standalone site.

Alias's Journal: CPANDB Tricks: Your personal version of the FAIL 100

Alias's Journal

You may have seen my FAIL 100 list of modules, the 100 modules who's failure in CPAN Testers cause the most pain to other people.

Now that I have support for CPAN Testers results in the CPANDB schema, it's now easy to replicate the math I was doing on that website in one SQL script.

Here's a quickie report of all the modules that I maintain that have failures causing problems for other people (which is a pretty decent clue to the order in which I need to fix them).

Please excuse the weird indenting, I have no idea how Slashcode managed to achieve that...

use CPANDB;
 
print map {
    sprintf("%4s %s\n", $_->[1], $_->[0])
} @{
    CPANDB->selectall_arrayref(
        'select distribution, (fail + unknown) * volatility as FAILure
         from distribution
         where author = "ADAMK"
         and
         FAILure > 0
         order by FAILure desc'
    )
}
 
9460 PPI
4389 DBD-SQLite
3237 IPC-Run
1407 File-HomeDir
  484 Test-ClassAPI
  396 prefork
  345 SMS-Send
  334 File-Remove
  289 Config-Tiny
  240 Class-Autouse
  217 File-ShareDir
  150 LWP-Online
  74 Devel-Dumpvar
  73 Test-Script
  68 Test-Inline
  60 Perl-Squish
  58 PITA-POE-SupportServer
  53 Module-CGI-Install
  38 ORLite-Migrate
  37 Module-Extract
  36 Module-Inspector
  28 Chart-Math-Axis
  24 Test-File-Cleaner
  20 PITA-XML
  15 PITA-Scheme
  15 Portable-Dist
  14 Xtract
  10 CSS-Tiny
  10 JSAN-Client
  10 PPI-HTML
   8 CPAN-Inject
   8 File-UserConfig
   7 PITA
   6 PITA-Test-Dummy-Perl5-Build
   6 Perl-Metrics
   4 Method-Alias
   4 Test-NeedsDisplay
   3 Algorithm-Dependency-Source-DBI
   3 Archive-Builder
   3 Data-Package
   3 JavaScript-Librarian
   2 CGI-Capture
   2 PITA-Image
   1 PITA-Test-Dummy-Perl5-MI
   1 PITA-Test-Dummy-Perl5-Make
   1 POE-Declare
   1 Parse-CPAN-MirroredBy
   1 Perl-Signature

Modern Perl Books, a Modern Perl Blog: Why Corehackers Matters

At YAPC::NA 2009, Chip and sungo announced the corehackers project.

I believe this project is important to the future of Perl 5. It has several parts:

  • To encourage new developers to work on the Perl 5 core (internals, ecosystem, and libraries).
  • To improve documentation and processes to make improvements to the Perl 5 core.
  • To experiment with new features and design decisions.
  • To clean up the internals.
  • To mentor new and recurring contributors.
  • To take some of the burden off of the overworked, underappreciated pumpkings.

I see corehackers as the other side of the important perl5i project; important features perl5i identifies and stabilizes can come into the corehackers tree (or forest, I suppose) for further experimentation without destabilizing the main development trees for Perl 5.

This is a huge benefit of Perl 5's switch to Git last year, and I'm glad to see Perl 5 development take advantage of it.

One of the obvious inspirations is the Linux Kernel Janitors project, which has performed similar functions for the Linux kernel.

The project is in its early stages. You can fork Chip's own bleadperl repository on GitHub and experiment with making changes. The IRC channel is active (if a little bit scattered; it's not clear exactly what's happening when, so you have a chance to guide it to your desires and expectations), and there are plenty of people interested in experimenting with all sorts of pent-up ideas.

In particular, I'm most interested in cleaning up some of the internals to make them more readable, more optimizable, and more amenable to further extensions and enhancements such as compiling Perl 5 to LLVM. A 30% performance improvement is likely, with few changes.

I've personally forked an experimental Perl which enables strict unilaterally, unless running with the -e flag, without having to use any module. I'll write more about that soon.

Ovid's Journal: Promises, promises

Ovid's Journal

This seems like such a useful little function. Can you guess what it does and why?

sub promise($) {
    my $subname = shift;
    my $package = caller;
    unless ($package->can('AUTOLOAD') ) {
        # this should be in import()
        require Carp;
        Carp::confess("Package ($package) does not implement AUTOLOAD");
    }
    my $fq_name  = "$package\::$subname";
    my $autoload = "$package\::AUTOLOAD";
    no strict 'refs';
    *$fq_name = sub {
        $$autoload = $fq_name;
        goto &$autoload;
    };
}

In fact, unless there's something else which does this and there's a fatal flaw, I think I might just upload this to the CPAN.

Alias's Journal: CPANDB Tricks: Tarballs that fail under Win32

Alias's Journal

OK, this isn't a CPANDB trick as such.

But the build process in CPANDB::Generator now reports tarballs that fail to extract. The list is just short enough that I can past it below.

Many are the sort of random stuff that you'd expect, but a couple stand out for me, especially INGY/YAML-0.39.tar.gz?

[Thu Jul  9 04:13:51 2009] Generating META.yml Data...
  Failed: AKSTE/Term-Query-2.0.tar.gz
  Failed: AQUMSIEH/Tk-ToolBar-0.09.tar.gz
  Failed: ARYEH/Net-AIM-1.22.tar.gz
  Failed: ASHLEY/Catalyst-Plugin-ReferingKeyword-0.01.tar.gz
  Failed: BRTEAM/Batch-Batchrun-1.03.tar.gz
  Failed: BRUMLEVE/autobless-1.0.1.tar.gz
  Failed: BRUMLEVE/ddb-1.3.1.tar.gz
  Failed: BRUMLEVE/vm-1.0.1.tar.gz
  Failed: BRUMLEVE/wildproto-1.0.1.tar.gz
  Failed: COG/Acme-AsciiArt2HtmlTable-0.01.tar.gz
  Failed: DCLEE/ponfish-0.03.tar.gz
  Failed: DIVEC/Lingua-ZH-HanConvert-0.12.tgz
  Failed: DMEGG/SGMLSpm-1.03ii.tar.gz
  Failed: DMR/CookBookB-19960430.tar.gz
  Failed: DOKSNER/MPE-IMAGE-0.98a.tar.gz
  Failed: DPATES/IPTables-IPv4-0.97b.tar.gz
  Failed: DPATES/IPTables-IPv4-0.98.tar.gz
  Failed: DREWF/Cmenu-1.1.tgz
  Failed: EDLIU/DBD-NET-0.1.tgz
  Failed: EDMONSON/Games-Rezrov-0.15.tar.gz
  Failed: EIM/WWW-SMS/WWW-SMS-0.09.tar.gz
  Failed: ENOOR/TaskForest/TaskForest-1.33.tar.gz
  Failed: FCO/perltugues/perltugues-0.15.tar.gz
  Failed: FLUFFY/Archive-Par-1.01.tar.gz
  Failed: FLUFFY/Getopt-Plus-0.98.tar.gz
  Failed: FOOF/libvorbis-perl-0.05.tar.gz
  Failed: FRAJULAC/Fwctl-0.28.tar.gz
  Failed: GAM/Test-CheckChanges-0.07.tar.gz
  Failed: GAVINC/Config-Directory-0.04.tar.gz
  Failed: GAVINC/File-DirCompare-0.5.tar.gz
  Failed: GAVINC/URI-Query-0.06.tar.gz
  Failed: GSCHLOSS/Math-Stat-0.1.tar.gz
  Failed: GSLONDON/Devel-AutoProfiler-1.200.tar.gz
  Failed: GSLONDON/Hardware-Vhdl-Parser-0.12.tar.gz
  Failed: GSLONDON/Parse-Nibbler-1.10.tar.gz
  Failed: GUIMARD/Lemonldap-NG-Portal-0.87.tar.gz
  Failed: GYEPI/Ovid-0.12.tar.gz
  Failed: HARDAKER/Makerelease-0.1.tar.gz
  Failed: HBIERSMA/MQSeries-1.24.tar.gz
  Failed: HOCHSTEN/XML-Tape-0.22.tar.gz
  Failed: INGY/YAML-0.39.tar.gz
  Failed: IZI/pake-0.21.tar.gz
  Failed: JEFF/CGISession.tar.gz
  Failed: JHIVER/MKDoc-Auth-0.5.tar.gz
  Failed: JOHNSCA/Syntax-Highlight-Perl-1.0.tar.gz
  Failed: JONO/Statistics-Table-F-0.02.tar.gz
  Failed: JOSTEN/XML-XSLT-0.20.tar.gz
  Failed: JOSTEN/xslt-parser-0.13.tar.gz
  Failed: JPRIT/ObjStore-1.53.tar.gz
  Failed: JPRIT/ObjStore-1.59.tar.gz
  Failed: JV/mmds-1.902.tar.gz
  Failed: KNASSAR/Activator-0.10.tar.gz
  Failed: LBOTTEL/Apache-FormatLog-0.02.tar.gz
  Failed: LUKKA/FreeWRL-0.14.tar.gz
  Failed: MACGYVER/SMTP-Server-1.1.tar.gz
  Failed: MASACCIO/Finance-Bank-Cahoot-1.04.tar.gz
  Failed: MCRAWFOR/Solstice-1440.tar.gz
  Failed: MEYERCJM/Harvey-1.02.1.tar.gz
  Failed: MICHEL/Business-KontoCheck-2.98.tar.gz
  Failed: MIGO/Games-Checkers-0.1.0.tar.gz
  Failed: MIKEDLR/Link_Controller-0.037.tar.gz
  Failed: MLFISHER/pmtools-1.10.tar.gz
  Failed: MPG/POD-Credentials-0.04.tgz
  Failed: MRDVT/GPS-PRN-0.05.tar.gz
  Failed: MSILVA/Language-Tea-0.03.tar.gz
  Failed: MSIMERSON/Mail-Toaster-5.09.tar.gz
  Failed: PAULG/Logfile-Radius-1.14.tar.gz
  Failed: PAYERLE/Net-Hesiod-1.11.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-Base-0.08.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-Base-0.092.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-Client-Echo-0.09.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-Client-LS-Remote-0.09.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-DB-File-0.09.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-DB-RRD-0.09.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-Services-PingER-0.08.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-Services-PingER-0.09.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-Status-Common-0.09.tar.gz
  Failed: PERFSONAR/perfSONAR_PS-Topology-Common-0.09.tar.gz
  Failed: PHENSON/DFS-Perl-0.50.tar.gz
  Failed: PLIAM/Apache-SecSess-0.09.tgz
  Failed: PSIONIC/tic/tic.tar.gz
  Failed: RFOLEY/File-Content-0.01.tar.gz
  Failed: RSAVAGE/Module-Metadata-Changes-1.04.tgz
  Failed: SAMPO/zxid-0.27.tgz
  Failed: SARTAK/Bot-Applebot-0.01.tar.gz
  Failed: SIMONW/Tanker-0.021.tar.gz
  Failed: SJSZ/BSD-arc4random-1.3.tar.gz
  Failed: STBEY/Bit-ShiftReg-2.0.tar.gz
  Failed: STBEY/Graph-Kruskal-2.0.tar.gz
  Failed: STBEY/Math-MatrixBool-5.7.tar.gz
  Failed: TURNERJW/Tk-JFileDialog-1.4.tar.gz
  Failed: TURNERJW/Tk-TextHighlight-1.0.4.tar.gz
  Failed: WARD/WeSQL-0.53.tar.gz
  Failed: WILL/Array-Sort-0.02.tar.gz
  Failed: WILL/Math-Systems-0.01.tar.gz
  Failed: WPMOORE/AFS-Command-1.7.tar.gz
  Failed: YAK/Time-Compare-0.01b.tar.gz
  Failed: YEWENBIN/Emacs-PDE-0.2.16.tar.gz
  Failed: YUMPY/Shell-POSIX-Select-0.05.tar.gz
  Failed: ZAG/HTML-WebDAO-0.91.tar.gz
  Failed: ZAG/WebDAO-1.02.tar.gz
  Failed: ZAG/XML-ExtOn-0.09.tar.gz
  Failed: ZAG/XML-Handler-ExtOn-0.06.tar.gz

Ovid's Journal: Complexity Management

Ovid's Journal

For some reason, I tend to get hired to work on large code bases, even though I've met many people who seem to have those perfect memories and instant analytic abilities which make them a natural for said code. Ultimately, as your code grows, complexity management skills become extremely important. This is why I have a number of modules I've written or contributed to heavily in order to make this easier:

Test::Harness
Complexity mangement starts with tests
Class::Sniff
When your OO hierarchy becomes unwieldy, take a closer look at it.
Class::Trait
Traits (roles) usually provide better OO complexity management than inheritance. (I should deprecate this in favor or Moose::Role)
Devel::Deprecate
You're going to forget to remove that out-of-date feature. This module won't let you forget.
Test::Most and Test::Kit
Stop duplicating test boilerplate in your tests and just get your work done.

Seriously, folks. As you move through your programming career, start paying attention to complexity management. When something is overly complex, figure out how to automate or simplify it. You'll usually gain flexibility and comprehensibility. Complexity management is your real job.

Blog of G?bor Szab?: The Corporate CPAN II

More than a month ago I wrote about The Corporate CPAN and posted the question also on the CPAN.pm developer list. I got a few responses that are still waiting in my inbox to act on. I don't see that I'll have the tuits for that any time soon so I better share with you the answers as they were.

Ricardo SIGNES also mentioned he is working on some internal system with HDP but did not point to any publicly available code.

Andreas J. Koenig pointed me to the doc/README file of the PAUSE source code on Github. We could look around there but he does not plan to release it to CPAN.

brian d foy pointed me to his work on MyCPAN. See MyCPAN::App::DPAN and MyCPAN::Indexer.

I know it's not much of an analysis on my side but at least now I can file the messages in another folder...

Alias's Journal: CPANDB Tricks: Smoking the Top 100

Alias's Journal

David Golden writes:

I'd like to be able to easily smoke test at least the volatile 100
list for the 5.10.1 RC's. Is there an easy way I can get a list in
the form:

DAGOLDEN/Sub-Uplevel-0.2002.tar.gz

Just a text file would be fine, or JSON or whatever. Just something
with AUTHOR/DISTNAME-VERSION.SUFFIX.

The Volatile 100 is my replacement for the Phalanx 100. Where the Phalanx 100 represented major functional modules that people might depend on directly the most and was curated by humans, the Volatile 100 in a graph-weighted list of the 100 most depended on distributions and is continuously updated automatically.

Finding information of the kind David needs is exactly why I created the CPANDB module. His query can be boiled down to just a single line of code.

use CPANDB;
 
my @releases = map { $_->release }
               CPANDB::Distribution->select('order by volatility desc limit 100');

PJF's Journal: Saudi Arabian Adventures - Days 3-5

These events happened during my recent trip to Saudi Arabia.

Saudi Arabian Adventures - Days 3-4
On the third day of teaching my class swapped over to new students at lunchtime. Included in this group was Abdulaziz, who I had spoken to on the phone a few times, and who formally introduced me to the class on the first day. Abdulaziz spoke English with an American accent, and I was later to learn that he gone to college in America.

Lunch on the second last day Abdulaziz took me to the golf course. Saudi Aramco has a huge golf course, with beautifully kept grass, and is in stark contrast to the surrounding desert. Here they serve a variety of meals, cooked to order. Since it was the middle of a business day, nobody was actually playing golf.

There have been a few things that I've noticed over here. Business attire is very much traditional western or traditional Arabic, with both being very common. Teenage girls can be often seen wearing flowing black over-robes that were very Harry Potter-esque. Lawns and garden beds are covered with a huge number of very fine mist sprinklers, and they run during the day. These sorts of sprinklers are practically outlawed in Australia, with most states suffering from severe water shortages.

At the food hall, I learnt an important lesson. If I was asked if I wanted something to "take away", then that actually meant the food serving would feed a football team, and my answer to such questions should always be in the affirmative. The first time I foolishly said no, and found myself wondering what to do with the incredible amount of food in front of me.

Having wireless access in my room is a real blessing. I don't know where I'd get it otherwise.

Saudi Arabian Adventures - Day 5
Today was my second-last day of teaching, and Abdulaziz informed me that I needed to make sure the class finished early (3pm) as a meeting had been arranged between myself and management.

To make my day more interesting, we had a trainer who wanted to install software for her course next week. Her name was Tina, and her opening line was "Hi, you're a software developer, aren't you?" When I asked how she knew, she claimed "It's the look. You're all trendy, with long hair." That's the first time I've ever heard developers get called trendy, so I can only assume that I mis-heard.

At 3pm we finished early so that I could meet with EDMD management. For some reason, whenever anyone said "EDMD" I would hear "AD&D", my mind would fill with images of dungeon-crawling geologists in flowing black robes fighting an onslaught of umber hulks.

The meeting with management was made more interesting because I didn't have my Aramco ID, which meant Abdulaziz had to make a couple of bluff checks at the security checkpoints to get me through.

The meeting itself was very management-focused. What does Perl do, who uses it, what's its future, and so on? I honestly don't know how I fared with these questions, and in hindsight I fear my answers may have been a little too much on the technical side, but everyone seemed happy.

Afterwards I met Omar, who I had spoken to on the phone a number of times before my trip, but who wasn't enrolled in the course. Omar is a dual-classed geo/developer, and already knows Perl. It also rapidly became apparent that he was very open-source friendly. "We have a program that parses $horrible_file_format, and would like to bundle it into a module and release it to the CPAN. Is that something you can help with?"

That night, Fuad, Abdulaziz, Omar and Mohammed took me out to a traditional Arabic restaurant. The trip getting there was an adventure in itself. Saudi Arabia seemed to lack anything resembling road rules, or if they existed, they were ignored by most of the drivers on the road. Lane-changes happened at random, and cars would speed down the road at breakneck velocity. The primary form of communication between drivers was a brief flash of high-beams, which meant "I am going 40km/hr faster than you, and I'm not changing lanes. You should." This was in stark contrast to driving inside the Aramco campus, where everyone was slow, careful, and polite. Somehow, Omar drove through all this without breaking a sweat or losing his cool.

In the car we talked about content management systems, web technologies, AJAX, Catalyst, Jifty, PHP, package management and deployment, virtual worlds, and a variety of other FOSS-oriented technical subjects. This was good, as it distracted me from the traffic around us.

At the restaurant I was treated to Arabic coffee, which apparently is made from the unroasted beans, and is very good. It also rapidly became apparent that this was a restaurant/museum, with many historical photos and items on the upper floors. There was a large water feature in the middle of the building, and a large lantern feature. It was explained to me that these sorts of lanterns were traditionally lit and placed outside houses at the start of the month of Ramadan.

After a tour of the historical section, we were given quite a banquet of food, some items which I have had before (such as the dips), and some which I had not. One of the most memorable (and most tasty) dishes was a thick paste made of a variety of grains. This was eaten with a thin broth, and stuck to one's teeth almost immediately.

After dinner, and tea, and dates, and more talking, we drove back to the camp, with discussions mostly focusing around virtual worlds, 3D web interfaces, and tunnelling procedure calls from Second Life to Perl.

Sleep was an immediate priority when I returned to my room, as it had become quite late, and I was certain I'd need an extra cup of coffee to get me up in the morning.

Posted: 8th July 2009.

Tags:

Bookmark:

Digg this Digg this

Webquills.net: I Replaced Movable Type with HTML::Mason

I Replaced Movable Type with HTML::Mason

I Replaced Movable Type with HTML::Mason

A few weeks ago I wrote about some of the things I love and hate about Movable Type as a content management system. I still think Movable Type is a great blogging tool, but as I tried to adapt it to my own need for a more general content management system, I kept running into road blocks. For web sites not laid out in the traditional blog format, Movable Type just didn't seem the best fit.

Being a Perl developer myself, I naturally started thinking about what I would do differently. I realized that many of the things I loved about Movable Type had to do with its potential rather than the way I wanted to use it in practice. The subset of functionality I used was pretty small. In real life, MT was too much code for me, and solved too many problems I didn't have. With the hubris of a Perl programmer, I decided I could re-implement just the parts I needed, and thereby achieve better customization for Webquills using less code.

While I'm still using MT for some other projects, Webquills.net is now running a custom code base that I have built using HTML::Mason. Switching to Mason made my redesign of the site much easier to deal with. Incremental changes could be done quickly in a standard text editor rather than through the web with MT's interface. Also, I can now easily use source control for both the code that runs my website, and the content I publish. On the other hand, MT's microformats and fine metadata are missing (I will rebuild them eventually), and there is no web interface for editing or publishing content at all. It works for me, but not for anyone else!

Over the next few weeks I'll write in the tech section about some of the details of that implementation. I'll also write about the reasoning behind some of my decisions in the strategy section. I will also be bringing up a lot shortcomings of the current implementation (and hopefully how I fix them). Of course, some the back end is just way too ugly to talk about, but I'll be trying to clean that up too.

If you're interested in seeing how a new Perl-powered web site gets built from the beginning, then follow along via the Webquills RSS Feed, or get updates via email.

schwern's Journal: perl/vendor/site explained

schwern's Journal

As part of answering a MakeMaker ticket I wrote out a fairly solid explanation of what the three different install locations mean for CPAN modules.

> (Personally I've always found the perl/site/vendor distinction and the
> triplicated set of directories to be fairly impenetrable :-), beyond
> that only 1 of the 3 at various times did something like I thought I
> wanted!)

Part of the problem is the whole philosophy is never fully explained. Part of it is that until 5.12 the default look up order is wrong.

Its pretty simple. Think of it like MacPorts or fink which doesn't control the entire operating system. You effectively have three managers working at the same time. You have the user installing things by hand. You have the package manager. And then there's the operating system.

In a flat layout they'll stomp all over each other. You might install an upgraded program from MacPorts and then have the next OS upgrade downgrade it again. The user might install the latest version from a tarball and then MacPorts installs an older version on top of it next upgrade.

"site" is what gets installed by the user, like /usr/local.

"vendor" is what gets installed by the package manager. /opt/local for MacPorts, /sw for fink.

"core" is what originally shipped with the operating system (or in Perl's case with Perl itself), like /usr.

You look in /usr/local first, then /opt/local, then /usr. In fact, that's how my PATH is set up. Unfortunately Perl itself incorrectly puts "core" first. Fortunately Debian (and I think Redhat now) fixes that. And 5.12 will finally fix it for all.

Packagers should be setting INSTALLDIRS=vendor. The CPAN shell should be using INSTALLDIRS=site. Nothing should be using perl/core. The broken lookup order complicates this because upgrades to dual-life CPAN modules have to go into core else they're not found, but Debian users don't have to worry about that.

transfixed but not dead!: Moose Singleton Method: Now without roles!

transfixed but not dead! ? perl

So instead of using roles wouldn’t it be nice if we could just do the following to an instantiated object:


$baz->add_singleton_method( legs => sub { 2 } );

 

Well if we define our Animal class like so then we can!


use MooseX::Declare;

class Animal {
    method walk { "unknown" }
    method wild { "wild?... I'm bliming livid!" }

    method add_singleton_method( $method_name, $method ) {
        my $singleton = $self->meta->create_anon_class(
            superclasses => [ $self->meta->name ],
            methods      => { $method_name => $method },
        );
        $singleton->add_method( meta => sub { $singleton } );
        $singleton->rebless_instance( $self );
    }
}

This add_singleton_method does all the dirty work that applying a role to an object did in previous post.

To break this down:


my $singleton = $self->meta->create_anon_class(
    superclasses => [ $self->meta->name ],
    methods      => { $method_name => $method },
);

This creates our anonymous class ($singleton). The “superclasses” part makes it a subclass of Animal and the “methods” part is where we add predefined methods (which we provide as args in add_singleton_methods)


$singleton->add_method( meta => sub { $singleton } );

Above adds the all important meta method. Without this then things can get a bit hairy!


$singleton->rebless_instance( $self );

This now reblesses the instance with this new anonymous class.

Now we can produce that singleton method like so:


my $baz = Animal-&gt;;new;
$baz->add_singleton_method( legs => sub { 2 } );
say $baz-&gt;legs;   # =&gt; 2

And it all works in exactly same way as with role examples previously mentioned.

Now we can keep creating further anonymous subclasses by using add_singleton_method or you can just use Moose meta method to add more methods to current anonymous class:


$baz->meta->add_method( walk => sub { "when not drunk!" } );

 

Now if we tidy up the mechanics of all this into a Moose role with some extra fancy API:

NB. Think I’m safe from the Trade Description Act for my blog title over this role usage!)


package DoesSingletonMethod;
use Moose::Role;

our $singleton = sub {
    my $self    = shift;
    my $methods = shift || {};

    my $meta = $self->meta->create_anon_class(
        superclasses => [ $self->meta->name ],
        methods      => $methods,
    );

    $meta->add_method( meta => sub { $meta } );
    $meta->rebless_instance( $self );
};

sub become_singleton      { $_[0]->$singleton }

sub add_singleton_method  { $_[0]->$singleton({ $_[1] => $_[2] }) }

sub add_singleton_methods {
    my $self = shift;
    $self->$singleton({ @_ });
}

no Moose::Role;
1;

This nows means we can do the following:


use MooseX::Declare;

class Animal with DoesSingletonMethod {
    method walk { "unknown" }
    method wild { "wild?... I'm bliming livid!" }
}

# one way to create singleton method....
my $baz = Animal->new;
$baz->become_singleton;                   # make $baz a singleton
$baz->meta->add_method( baz => 'baz!' );  # add method "baz" using meta

# and another.....
my $foo = Animal->new;
$foo->add_singleton_method( foo => sub { 'foo!' } );

# and finally multiple methods....
my $bar = Animal->new;
$bar->add_singleton_methods(
    bar1 => sub { 'bar1!' },
    bar2 => sub { 'bar2!' },
);

Hmmm this is nice. Perhaps I’ll wrap this up as MooseX::SingletonMethod and upload to CPAN ;-)

Perlbuzz: mod_perlite helps Perl gain ground in the PHP arena

Michele Beltrame wrote in about the mod_perlite project, which I'd love to see take off. mod_perl has never been easy to install, and ISPs and webhosts are loathe to use it for security reasons. mod_perlite would provide easy access to Perl without the weight of CGI.

mod_perlite is an interesting Apache module currently under development. I'd say it's the equivalent of what mod_php is for PHP: a fast, easy to use, and relatively safe way to use Perl scripts for the development of small and medium web applications.

A project like this brings Perl back into play as a good choice in a field currently dominated by PHP. In particular, PHP is great when you need to run a lot of different small applications on the same web server, and you want all of them to run fast enough. CGI is slow compared to mod_php because both the interpreter and the application need to be loaded for every single request. Solutions like mod_perl and mod_fastcgi are the best solution when you have a few big applications, but they're not a good choice in this scenario, because they keep the application resident: when you've got so many small applications (which, in most cases, are invoked infrequently) you end up with enormous memory footprint.

mod_perlite is the winner here: only the interpreter is kept resident (there's also the idea to keep some modules loaded, which might speed up things further) and applications are loaded at request time. This also helps avoid problems with memory leaks. Using mod_perlite is simple: just configure Apache and all the .pl files will run without modification taking full advantage of mod_perlite and therefore reducing execution time to a fraction.

Unfortunately the module is not yet stable, as there's still work to do. My installation on Gentoo Linux x86_64 went smoothly. mod_perlite works but still suffers some major issues. In fact, at present it's only usable for very simple applications because of a bug in how query parameters passed by Apache are handled.

To make mod_perlite fully usable, the project web site has a three point TODO list:

  • Fix form POST processing ('read' does not work reliably)
  • Limit Perl running time.
  • Find ways to cache code.

The project is looking for help, so if you are interested and know something about mod_perl, writing Apache modules in C, and about overriding system calls in Perl - and if the project seems interesting to you - please shout!

And... if someone argues "we're 10 years late compared to PHP", I'd reply "better late than never". ;-)

Michele Beltrame lives in North-Eastern Italy, where he has been developing web applications in Perl since 1996. He is an active member of the Italian Perl community and of the Italian Perl Workshop organizational committee. In his free time he publishes guidebooks on the mountains surrounding his area.

Ovid's Journal: Perl 6 Roles Question

Ovid's Journal

Imagine a PracticalJoke class. It needs a non-lethal explode() from a Spouse role and a timed fuse() from a Bomb role. Unfortunately, each role provides the both methods. With Moose, this is trivial to resolve:

package PracticalJoke;
use Moose;
with 'Bomb'  => { excludes => 'explode' };
    'Spouse' => { excludes => 'fuse' };

How the heck do I do that with Perl 6? No matter how many times I read Synopsis 14, I can't figure out how that would work.

role Bomb {
    method fuse ()    { say '3 .. 2 .. 1 ..' }
    method explode () { say 'Rock falls. Everybody dies!' }
}

role Spouse {
    method fuse ()    { sleep rand(20); say "Now!" }
    method explode () { say 'You worthless piece of junk! Why I should ...' }
}

class PracticalJoke does Bomb does Spouse {
    ???
}

What have I missed?

dagolden: Iron Man ideas backlog

There are so many topics I want to write about and so little time to write.  Since I’m on vacation and supposedly relaxing and enjoying myself, I’m just going to list out some things that I might write about soon.  If any are particularly appealing, let me know and I’ll bump it towards the top of the todo stack.

  • Capture::Tiny, the last capturing module you’ll ever need
  • Version numbering lessons and pitfalls
  • Re-imagining PAUSE/CPAN
  • Perl’s punctuated equilibrium
  • Disagreeing agreeably
  • p5p: Wizards, leaders, managers and coaches
  • How to regression test CPAN modules
  • Changing Perl 5 development: to what end?

I can see the appeal of microblogging ― perhaps I’ll try to compose a 140 character summary of each one and see which are actually worth expanding on to any length.

Shlomi Fish: A Perlbuzz Feature by Me about CPANHQ

W00t! Andy Lester published a feature I wrote about CPANHQ on Perlbuzz. This is in continuation to my previous blog entry about the topic, but much more focused.

This publicity seemed to have work, because we've been visited by two new Perl people on #cpanhq, who tore my hacky Catalyst code to pieces. Anyway, check the article out, and if you like it, upvote it on reddit.

Modern Perl Books, a Modern Perl Blog: The Tower of Defaults

In Take Advantage of Modern Perl I digressed to discuss a hierarchy of defaults. I use this concept to help make design decisions about where to fix problems. (I admit to borrowing concepts from Joshua Bloch's How to Design a Good API and Why it Matters (PDF link)).

As you progress from the top of the tower to the base, you solve the problem for more people.

  • Unknown Problem
  • Poorly Recognized Problem
  • Infrequently Asked Question
  • Frequently Asked Question
  • Frequently Reinvented Module
  • Available Module
  • Community Idiom
  • Popular Module
  • Bundled Module
  • Core Module
  • Core Language

Please note that this post does not address the difficulty of fixing a problem at any one of these locations, nor does it consider the costs of compatibility, testing, or maintenance. Those are important concerns, but they're not the important point for this post.

Institutional Knowledge Locations

The least effective way to address a problem is by ignoring it. Of course, that assumes you know it's already a problem. A problem you haven't even identified is worse. A problem only a few people acknowledge is bad.

(By "good" and "bad" I refer to the efficacy of addressing the problem. Again, the severity and reach of a problem are important to consider when deciding how to fix it.)

Documentation Locations

Documenting a problem is an improvement. Moving down the tower even to institutional knowledge, where occasionally someone ask for and receives a workaround helps more people avoid the problem. Documenting the problem and any workarounds in a FAQ is even better.

External Code Locations

If users know enough to reinvent the wheel to solve the problem, this can be better than a FAQ. (It can be worse, too; some problems are difficult to solve even with domain-specific knowledge and good test cases.)

It's better to have a decent solution available, though that's generally only useful to people who know it's available.

Widespread community knowledge helps even more people, at least if they have contact with the appropriate parts of the community. There's an overlap here with FAQs and IAQs, but not all FAQs become idioms and vice versa. The ability to look at code and recognize such an idiom -- or to recognize the need for an idiom -- is useful.

The best solution in this category is a popular, well-recognized, well-understood module. Its existence does not preclude other options, but its efficacy and applicability makes it the default solution.

Internal Code Locations

A project such as perl5i or Strawberry Perl can address problems (bugs, missing features, useful enhancements) by bundling modules. They're available by default to everyone who uses the distribution. People need to know that they're available, so other parts of the tower apply, but the barrier to use is much smaller.

The core library is even more effective, provided that users know which parts exist.

As you might expect, the most effective way to address a problem is often to address it in the language itself.

Caveats

I glossed over the importance of design on purpose. I bring it up now because I don't want to give the impression that I believe that pushing all potential fixes into the language itself is either desirable or good. It's not.

An XML parser may be a good bundled module, but it's likely a mistake to put XML parsing in the language itself. A garbage collector tweak tuned for a specific processor may be sufficient as an infrequently asked question, as the people who can best take advantage of it need to analyze its benefits and drawbacks appropriately.

Yet it's also important to remember that the further up the tower a solution exists, the fewer people can take advantage of it.

Ovid's Journal: Reputations

Ovid's Journal

As many of you know, Rafael has stepped down as the P5P pumpking. He's done a great job and I'm sad to see him go, but he couldn't take the mud-flinging any more. I can't say I blame him.

Regarding mud-flinging -- and not just in regards to this particular debacle -- I won't name names (many will guess and many guesses will be wrong), but I have some observations about reputation:

  • I've been quietly told by several that they're disgusted with one particular individual who should know better than to be rude.
  • I know of at least one individual who has, unbeknownst to him, not been offered a rather nice consulting gig because of his online behavior.
  • There is one person I once objected to hiring because of comments he made on a mailing list (the owner saw those comments and rejected the applicant).

I suppose if people aren't concerned about work, they may not be concerned with how they come across online. On the other hand, wouldn't it at least be good to be known as someone who can find ways of getting things done nicely? I struggle with this myself at times and I hate seeing it in others.

Perlbuzz: Introducing CPANHQ

By Shlomi Fish

Most people who are actively developing using Perl are familiar with sites for searching CPAN (the Comprehensive Perl Archive Network) such as search.cpan.org and kobesearch.cpan.org. These sites provide a simple search bar where users can search for keywords or key phrases, and find a list of results. These sites also feature pages for the various CPAN distributions, the various authors, and the individual pages of documentation inside the modules.

Recently, Andy Lester started the "Rethinking CPAN" mailing list and wrote a Perlbuzz post titled "Rethinking the interface to CPAN", where he gave the case that the current resources may be inadequate for the process of selecting a module on CPAN. For a long time, there was an intermittent discussion and some brain-storming, but very little code (if any) has been written. This has all changed with CPANHQ.

So what is CPANHQ? As documented in the first and only wiki page it has so far (which I wrote a few days ago), "CPANHQ aims to be a community-driven, meta-data-enhanced alternative to such sites as http://search.cpan.org/ and http://kobesearch.cpan.org/. Currently, the functionality is very basic, but we have great ambitions."

I learned about CPANHQ by overhearing a conversation on Freenode's #perl channel. I joined the effort, and made several enhancements to the Catalyst and DBIx-Class-based code. The functionality is still very basic.

Some of the plans and ideas we have for CPANHQ, which may be translated into code in the future are:

  1. The code is and will remain open-source, which makes it easy for people to contribute to.

  2. We plan to have most of the current features of search.cpan.org and kobesearch.cpan.org including pages for authors, distributions, and individual modules and their documentation.

  3. CPANHQ was already enhanced with some jQuery and jQuery UI JavaScript goodness, and we plan to add more of it to make the user experience better.

  4. The site aims to be more integrated than the many separate CPAN-related sites today: search.cpan.org, CPAN Forum, AnnoCPAN, CPAN Ratings, CPANTS, CPAN Dependencies, etc. By putting everything under one roof, we can provide a better user experience than the many sites with very loose integration.

  5. We plan to enhance the site based on meta-data as provided by both the module authors (in the META.yml file and the users of the site.

    For example, we have already added support for the META.yml's keywords which allow authors to tag modules, and we plan to support user-tags too.

  6. CPANHQ will be very community-driven. People would be able to open user accounts there, which will allow them to contribute content to the site, such as tags/labels, comments, wiki pages, chatter, etc.

The CPANHQ wiki page contains more ideas and insights. Like I said, the current functionality is incredibly basic, but we hope that with enough help, time and dedication, we can create an attractive and engaging interface to CPAN, to make finding a module on CPAN faster, easier and more fun.

In the meantime, you can look at the screenshots we have of the interface so far, or clone the github repositories, and set up a local web-interface.

Shlomi Fish has been writing using Perl, about Perl and for Perl, since 1996, when he started working for a web-design shop, and discovered Perl and UNIX, which he's been in love with ever since. He initiated and is maintaining many CPAN modules and contributed to many other Perl and non-Perl related projects.

nothingmuch's perl blog: Holy crap, I suck at coding

Every so often I look back at old code and think to myself WTF was I on when I was writing it. Just take a look at my Perl module releases in chronological order[1].

Usually it's small things I find annoying, when just looking at the code it with fresh eyes is enough to unveil small idiocies. It's easy to judge because I don't need to sugar coat any criticism I have when I'm the one under the lens. This stuff is usually the result of refactoring too quickly, and not rounding off all the corners, especially if the code I was refactoring was new code.

More embarrassing is when I find flaws in my assumptions or thought process: things that are more complicated than they should be, or inability to separate an idea from the engineering context it emerged from. This is usually the result of rushing through something (often towards the end of a project) and not thinking things through, being ignorant of a better approach, or just plain old lack of insight.

This process used to make me feel bad, but now it makes me feel good. I used to be concerned with how fast I learned things, eager to understand ideas that would propel me towards finding the ultimate paradigm [singular. ugh!] of the future.

When your goals are as laughable as that failure makes you feel bad.

I think now I'm much more relaxed about everything. I'm not looking for a silver bullet at all anymore. I'm looking for fun ideas to "spice up my routine" as they say. If I remain interested I usually produce dramatically better results than if I need to force myself to work.

Leisure has replaced ambition as the primary purpose of my learning efforts.

However, without ambition to drive me forward, I occasionally feel like I'm not trying hard enough to better myself. Seeing past failures (especially recent ones) is an great way of reassuring myself that my brain has not in fact crawled under a cupboard and died.

Recognition of past failure was always evidence that I am still learning, but in the past I thought it meant that I was not yet any good. Now it just means that I'm still having enough fun to stay curious, and I'm also learning what I should be unlearning.

So now that I am old and wise, I know that when I grow up I want to still be having fun, or at least to realize why this blog post is full of shit.

[1] Unfortunately the backpan directory listing doesn't seem to have the dates right, so the linked listing doesn't contain mistakes that have been superseded with new module uploads, only ones big enough to completely give up on, or that have been fixed by other people ;-)

Alias's Journal: CPANDB should now be synchronised and up to date

Alias's Journal

Update:

The CPANDB now also contains the data for CPAN Ratings

In my previous announcements for CPANDB, I mentioned that while it was generating the database the correct way, the data was going to be a bit out of sync because data was coming from different places.

This should now be resolved.

The server syncs a minicpan to http://cpan.cpantesters.org/, then a META.yml database is updated from the minicpan, a CPAN::SQLite index is built from the same minicpan, and then both of them are joined together with the ORDB::CPANUploads database to product the completed tables.

The final step is the application of the graph algorithms to produce the weight and volatility scores for each distribution, which are now being added to the database as well.

Now that cpandb is ready for the big time, I'll start to try and merge in the three main outstanding data sets (CPAN Ratings, rt.cpan.org and CPAN Testers) and then rewrite the CPAN Top 100 to turn it into a fully operational death star... I mean website.

You can use the CPANDB module to fetch and ORM-inflate the database, or to download the database directly, use the following URL.

http://svn.ali.as/db/cpandb.gz

The current schema for the database now has the slightly expanded distribution table.

CREATE TABLE distribution (
    distribution TEXT NOT NULL PRIMARY KEY,
    version TEXT NULL,
    author TEXT NOT NULL,
    release TEXT NOT NULL,
    uploaded TEXT NOT NULL,
    weight INTEGER NOT NULL,
    volatility INTEGER NOT NULL,
    FOREIGN KEY ( author ) REFERENCES author ( author )
)

Perlbuzz: Perlbuzz news roundup 2009-07-05

These links are collected from the Perlbuzz Twitter feed. If you have suggestions for news bits, please mail me at andy@perlbuzz.com.

Alias's Journal: Let me be clear, again, about the nature of the DarkPAN.

Alias's Journal

The growth in the argument that the DarkPAN is somehow some form of boogieman, some wispy vaporous nothing that is unobservable and thus something able to be ignored astonishes me. And I'm not singling out one person here, I'm hearing it from a number of different people.

It's especially unnerving because a big chunk of it is sitting in plain view.

So let me repeat this again.

Until perhaps very recently, the DarkPAN was generally considered to be more or less all the Perl code that wasn't on the CPAN. Because if it wasn't on the CPAN, it was largly impossible to find. And even if you could find it, you couldn't do anything with it.

With the advent of PPI and Ohloh, the situation has now changed.

Now we know, for example, that just the small part of the DarkPAN that is visible is at least 4 times bigger than the CPAN. Because 4 times more code than CPAN is basically what Ohloh managed to uncover. Last time I looked, it was reporting about 97,000,000 lines of code, and we know that the CPAN is in the general range of 20-25,000,000 lines of code.

I've called this semi-visible part of the DarkPAN the GreyPAN, but that's just a way of categorising it. It's still a part of the DarkPAN. It's still code we can't feed into CPAN Testers or other automated systems to examine how a Perl change will impact it.

We also know that it's mostly not large codebases. Anecdotal reports from the Ohloh people themselves suggest it's made up of lots of different bits and pieces. So in fact, it serves as quite a useful analog for the consistency of the DarkPAN itself.

It's something we can suck in, process, and then run what-if scenarios for. At least at a document-level anyway.

Frankly, I'm sick and tired of this back and forth crap.

I'd like to see both sides of this argument shut up (me included) until we've actually built the thing that can suck in the visible parts of the DarkPAN and process it.

If you'd like to help, I've got most of the "Process it" part working now, but I'd dearly love some help on the "sucking it in" part.

If, after we've finished, we're able to establish that (for example) across all C code there is on average 1 line of utility Perl code for every 100 lines of C code then we've got something to work with.

Because we can take estimations about the total amount of C code in the world and extrapolate from that to make a guess at the total amount of Perl code in the world.

Aristotle's Journal: Polite fiction and the elephant in the room

Aristotle's Journal

Rafa?l Garcia-Suarez :

Who’s trying to be realistic by attempting to release software with some quality expectations, notably by making the upgrade process seamless and introducing as little bugs as possible?

The problem with that argument is that 5.10.0 did contain regressions.

That the rarity of releases is justified by the high quality standards being adhered to is, unfortunately, merely polite fiction. What it all boils down to is simple:

Shit happens.

No matter how much we’d like for it to be otherwise, shit happens. The release process needs to be reality-based: it needs to deal with the very real fact that shit happens and has in fact already happened. The only realistic way to deal with that is for releases to be easy enough that the shit that does invariably happen can be dealt with soon enough, so that it won’t cause too many people too much trouble.

And the best way to make releases easy is to make them frequently.

And the simplest (though not only) way to ensure that is to put them on a schedule.

That is all.

Rafa?l Garcia-Suarez :

Whenever I hear someone saying we should have regular releases, I hear we should release when Venus enters Pisces.

There is your misunderstanding, then: what they are really saying is we need a reliable plan for dealing with accidents. If you can make that happen without sticking to scheduled releases, that’s fine too.

Yes: releasing often does not affect the quality of software by itself. But releasing it rarely almost certainly will ? negatively. Because shit happens.

I don’t like it either! But that’s reality for you. I doesn’t care what you like. It just is.

nothingmuch's perl blog: Bootstrapping KiokuDB::Cmd

I just closed a ticket in KiokuDB's RT queue that asked for simpler dependencies. The fix was splitting the KiokuDB::Cmd modules into their own distribution, making the core more easily installable on Windows.

The problem is that I depended on Proc::InvokeEditor for the kioku edit command. Unfortunately that module does not install cleanly on Windows, preventing KiokuDB itself from installing, even though it's not required for normal use.

The problem is that KiokuDB's command line tool requires KiokuDB::Cmd to run. What I ended up doing is having the kioku script (which still ships with KiokuDB) allow bootstraping KiokuDB::Cmd by using Module::AutoInstall (if it's available and the user grants permission to do so).

If kioku can't require KiokuDB::Cmd cleanly, then it calls try_auto_install function:

sub try_auto_install {
    if (eval {
        require Module::AutoInstall;
        require ExtUtils::MakeMaker;
        1;
    }) {
        print "\n";
        if (
            ExtUtils::MakeMaker::prompt(
                "Module::AutoInstall is available. " .
                "Should I use it to install KiokuDB::Cmd?",
                "N/y",
            ) =~ /^y/i
        ) {
            my @installed = Module::AutoInstall->install(
                [],
                "KiokuDB::Cmd" => $KiokuDB::REQUIRED_CMD_VERSION,
            );
            return @installed > 0;
        }
    }

    return;
}

If installation seems to have succeeded then we delete $INC{"KiokuDB/Cmd.pm"} and try to load it again.

Otherwise the script exits with an error asking the user to install KiokuDB::Cmd manually.

I think this is a fair tradeoff, especially if you don't need the command line tools in production deployments (you can still make backups by programmatically scanning the database yourself).

xsawyerx's Journal: Red Flags in Programming Slides are UP!

xsawyerx's Journal

The slides are available HERE

I should be calling this entry Why Slideshare.net is stupid and I hate it but I'm going to leave that to another time. Instead, I would like to rant a bit on the purpose of Red Flags. You don't have to read this, and you probably won't find this enlightening or even slightly interesting. I just have to vent.

A fellow programmer who attended the lecture wrote in his blog about it, and I couldn't find the energy to reply verbally, so I'll do it here.

The purpose of Red Flags is not to generalize on who is evil and stupid and vile and who is correct and pure and fluffy. The point is to understand practices that usually don't benefit us but rather derive from practices employed in previous jobs, prior experience with different (usually older or drastically different) languages.

This is something that can and should be done in all areas of life, and not just programming. We should always search for what we do because of prior pretenses and reevaluate it and see if there's room for improvement or change. This does not mean that what I would consider a "bad practice" necessarily applies to you and some of the slides do indicate that sometimes you have no other choice but to chose something that.. if you did have another choice, you wouldn't choose.

That person also denounced the lecture as generalization, which "is always bad". I'm sorry, but generalization is not always bad. I generalize people who hit other people when they're drunk as people I do not want to be around when they are drunk. Strict generalization. I also generalize coders who write a 400 line program in one single line as people who don't really want their code to be read, that's a generalization. I also generalize that as a bad coding practice. Yes, I do. There is nothing really wrong with generalization as a way to try and avoid (or at least be cautious around) things that from our experience (or basic understand) might (might) not be good for us. People see generalization as a problem because people generalize the wrong things, but this does not mean we should avoid the quality of generalization. "You shouldn't talk to strangers" is... a generalization, my friend, and it's the first thing you would tell your child.

I have to say I'm deeply disappointed that instead of saying "well, maybe I really should consider avoiding these practices unless I absolutely find the need for it" or saying "this doesn't apply to me, I'm too good of a programmer to listen to this kid", the saying was "he generalizes try and catch for workflow (unless necessary) as a bad practice, and I remember from school that generalizations are bad [I won't stress the point that this is... yet another generalization], so I'm going to say this sucks". Deeply disappointed.

This is exactly the point I don't write in forums, communities, do lectures on programming to a large crowd or engage in conversation with fellow programmers outside my work or social circle (which has about 2 programmers).

</rant>

Code and Hacks: Stealing from Padre for Vim part 3

As promised in my last post, I have released a new version of App::EditorTools and have a number of screenshots of the new functionality. This version includes App::EditorTools::Vim, which provides an easy way to add the vim scripts to integrate the package into Vim.

perl -MApp::EditorTools::Vim -e run > ~/.vim/ftplugin/perl/editortools.vim

And now you should have the following mappings:

  • ,pp - Show a menu of the functions availabe from App::EditorTools

  • ,pL - Lexically rename the variable under the cursor (make sure the cursor is at the start of the variable for now

  • ,pP - Rename the package based on the path of the current buffer

  • ,pI - Introduce a temporary variable


Here are a few screenshots of these actions:

Lexically Rename Variables:

vim-renamevar

Rename Package based on the current file's path:

vim-renamepackage

Introduce Temporary Variable

vim-introtempvar


I'd love to hear feedback and any suggestions for future PPI based tools that Vim, Padre and other editors could leverage.

I also have to note that the editortools-vim script from App::EditorTools was very easy to put together (although it still needs a fair amount of clean-up work and documentation) since is was based on Ricardo's App::Cmd--very easy to use and feature rich.

** Updated 7/5/09 10:37am: moved the screencasts to an external server and fixed some spelling

ChrisDolan's Journal: Copy protection: users vs. developers

ChrisDolan's Journal

A few weeks ago, LWN ran an article about the Okular PDF viewer which enforces copy protection as specified in the PDF specification. The LWN editor and several commenters complained about this restriction to their freedom. I have three comments on that topic:

1) As a PDF implementor myself, I chose to implement the PDF copy protection features just as Okular did. I did this because Adobe's license agreement to download the spec insisted that I do not willfully violate the spec. I agreed to those terms and so I have ignored all requests to disable said protection in my own library.

2) It's open source. Anybody can trivially turn off the copy protection and recompile (my library is Perl, so you don't even need to recompile). If they do, then they can bear the responsibility for violating the spec.

3) Do you ever hear people complaining about permissions in the tar file utility? Even GNU tar implements file access controls as specified in the tar file. If I untar a file which is -r--r--r-- or even ---x--x--x, is that a violation of my rights? I say not. It's a minor inconvenience at worst and an excellent safety precaution at best. Nobody's beating a drum to remove copy protection features from tar.

The copy protection worth fighting against is the kind that can take away your current rights at some unspecified future time (like what happened when Google Video or Walmart music shut down their DRM servers)

tsee's Journal: In defense of Perl ithreads

tsee's Journal

People like to point out the problems with Perl's threading, say they're simply the Windows fork-emulation ported to other operating systems and conclude that they're of no use otherwise. They generally omit mentioning the cases in which Perl ithreads are the only viable solution for concurrency in Perl.

First, you have to understand the i in ithreads. Read: interpreter threads. Each ithread in your Perl program has its own copy of the whole interpreter. Nothing is shared between the interpreters by default*. Most other threading implementations work the other way around: By default they share everything and the user has to deal with locking of any shared resources. This has many advantages over ithreads. Most obviously, an ithread takes a lot more memory. Furthermore, passing data between ithreads is rather painful and very, very slow. But there is, unfortunately, a big downside to shared-by-default:

Real concurrency (i.e. multiple threads executing concurrently on multiple CPUs) doesn't seem to be feasible with the shared-by-default approach in a language such as Perl. This is because almost all operations -- including those who seem to be entirely read-only -- can potentially modify the data structures. Use a scalar that contains an integer in a string-context and the scalar will be modified to contain a char*. Marc Lehmann explained this in more detail in his talk "Why so-called Perl threads should die" at the German Perl Workshop 2009. (Couldn't find his slides online, sorry.) As far as I know, the typcial dynamic programming languages other than Perl only have (non-concurrent) cooperative multi-threading to start with.

Now, some will be quick to point out that ithreads are a mere fork() reimplementation with quite a few disadvantages. For a real fork, the kernel can do COW and non-thread-safe XS modules aren't a problem. But if your software has to run on Windows, the fork's a non-starter. As mentioned earlier, threads are used for the emulation of fork() on Windows. That means if you use fork(), you'll get multiple processes on systems which support it natively and multiple (i)threads on Windows with all the associated problems regarding memory use and thread-safety. If you're writing software predominantly on Linux, would you rather debug problems in your development environment or on your customer's (or generally user's) machine? I thought so. There is a case to be made for consistency.

The other big contender is the excellent Coro module (or an event loop). I suggest you have a look at its documentation to understand what it does exactly**. The downside? It's cooperative multi-threading. It doesn't really run concurrently. The code in each Coro has to cede control to the other coroutines regularly. If there is some code that's not directly under your control and takes a long time, your GUI or what not will be blocked. If you think about it a bit, you'll realize that heavy re-use of code from CPAN and cooperative multi-threading is a non-starter. In my case, I needed to parse Perl code using PPI. That can take seconds...

I'm all ears for suggestions on how to do concurrency right in a dynamic language. (here: Perl, but if another language does it better, that'd be interesting, too.)

The requirements are:

  • Real concurrency, i.e. using multiple cores.
  • Non-cooperative multi-threading due to code that is not under my control
  • Portability
  • A point I haven't touched in my rant: Ability to recover from crashes. You can recover from crashing ithreads.

* This statement may become painfully untrue if you use a non-thread-safe XS module, unfortunately.

** I'm not restating what it does in my own words because I'd expect them to be slightly inaccurate thus provoking eternal damnation.

Dave's Free Press: Bryar security hole

Someone on IRC reported a bug in Bryar. Namely that a Naughty Person can exploit the feature that notifies you of blog-spam by email to execute arbitrary code on your machine, as the user you run Bryar under.

A patched release is on the way to the CPAN, and you are strongly urged to upgrade.

Dave's Free Press: Thanks, Yahoo!

[originally posted on Apr 3 2008]

I'd like to express my warm thanks to the lovely people at Yahoo and in particular to their bot-herders. Until quite recently, their web-crawling bots had most irritatingly obeyed robot exclusion rules in the robots.txt file that I have on CPANdeps. But in the last couple of weeks they've got rid of that niggling little exclusion so now they're indexing all of the CPAN's dependencies through my site! And for the benefit of their important customers, they're doing it nice and quickly - a request every few seconds instead of the pedestrian once every few minutes that gentler bots use.

Unfortunately, because generating a dependency tree takes more time than they were allowing between requests, they were filling up my process table, and all my memory, and eating all the CPU, and the only way to get back into the machine was by power-cycling it. So it is with the deepest of regrets that I have had to exclude them.

Cunts.

[update] For fuck's sake, they're doing it again from a different netblock!

Dave's Free Press: Module pre-requisites analyser

As a service to module authors, here is a tool to show a module's pre-requisites and the test results from the CPAN testers. So before you rely on something working as a pre-requisite for your code, have a look to see how reliable it and its dependencies are.

Dave's Free Press: Ill

I am ill. I've been ill since Thursday, with a cold. You're meant to be able to cure a cold with [insert old wives tale remedy here] in 5 days, or if you don't, it'll clear itself up in just under a week. So hopefully today is the last day.

So what have I done while ill?

On Friday I became old (see previous post), and went to the Byzantium exhibition at the Royal Academy. It was good. You should go.

Saturday was the London Perl Workshop. My talk on closures went down well, and people seemed to understand what I was talking about. Hurrah! I decided that rather than hang around nattering and going to a few talks, I'd rather hide under my duvet for the rest of the day.

I mostly hid on Sunday too, and spent most of the day asleep. In a brief moment of productivity, I got my laptop and my phone to talk to each other using magic interwebnet bluetooth stuff. I'd tried previously without success, but that was with the previous release of OS X. With version X.5 it seems to Just Work, so no Evil Hacks were necessary.

The cold means that I can't taste a damned thing, not even bacon. So now I know what it's like to be Jewish. Being Jewish sucks.

And today, I am still coughing up occasional lumps of lung and making odd bubbling noises in my chest, although my nasal demons seem to be Snotting less than they were, so hopefully I'll be back to normal tomorrow.

Dave's Free Press: POD includes

One of my CPAN distributions is CPAN-FindDependencies. It contains a module CPAN::FindDependencies, and a simple script that wraps around it so you can view dependencies easily from the command line. That script, naturally, has a man page. However, that manpage basically says "if you want to know what arguments this program takes, see the CPAN::FindDependencies docs". This is Bad from a usability point of view, good from a not-duplicating-stuff point of view, and good from a laziness point of view. Which means that it's Bad.

So, the solution.

=over

#include shared/parameters

=back

and some Magic that does the cpp-stylee substitution at make dist time. Note the 'dist' section in my call to WriteMakefile.

This is, of course, crying out to be made less horribly hacky, but it works for now, so I'm happy.

My original idea was to write some crazy shit that would do the #include at install-time, when the user was installing my code. But that has the disadvantage that tools like search.cpan wouldn't show it properly, as they simply look at the files in the distribution. So this does the #includes at the last moment just before I package up the code and upload to the PAUSE. You lovely people get the right documentation in all the right places, I only have to maintain it in one place so it stays in sync, and (in the interests of Laziness) I don't have to remember to run any extra scripts before releasing, make dist just Does The Right Thing.

Dave's Free Press: XML::Tiny released

I have released my XML::Tiny module. The parser at its core is less than twenty lines of code. Pretty easy to follow code too, I think, and that also includes error handling. One of my aims in writing it was to keep memory usage and code to the absolute minimum, so it doesn't handle all of XML. The documentation says that it supports "a useful subset of XML". Personally, I think it supports the useful subset. It's certainly enough to parse the data I get back from Amazon when I use their web services, and to parse an RSS feed.

Dave's Free Press: YAPC::Europe 2007 report: day 1

As is becoming normal, I used the times between talks to bugfix some of my modules - this time Tie::STDOUT and Data::Transactional. The former was failing on perl 5.6, the latter on 5.9.5. The former was a bug in perl (you can't localise tied filehandles and expect the tieing to go away in 5.6, so it now declares a dependency on 5.8), the latter was a bug in my code.

Philippe Bruhat's talk on Net::Proxy was great - you can tell it's great because I came away with ideas for at least four things that I need to write. First up will be a plugin for it to allow the user to specify minimum and maximum permitted data rates for proxied connections. This will permit bandwidth limits for maximum permitted rates, but will also help to defeat IDSes doing traffic analysis if you specify a minimum permitted data rate.

This will protect (eg) ssh sessions from being identified based on their very bursty traffic pattern, by "filling in the blanks" with junk data.

In the evening, the CPAN-testers BOF was productive.

Dave's Free Press: Palm Treo call db module

To make up for a disappointing gap in Palm's software for the Treo smartphone, I wrote a <a href=http://www.cantrell.org.uk/david/tech/treo/call-dumper/>small perl script</a> to parse the database that stores my call history. I then re-wrote it as <a href=http://search.cpan.org/search?query=Palm%3A%3ATreoPhoneCallDB>a re-useable module</a> which also figgers out whether the call was incoming or outgoing.

Dave's Free Press: Number::Phone release

There's a new release, <a href=http://www.cantrell.org.uk/david/tech/perl-modules/Number-Phone-1.58.tar.gz>version 1.58</a>, of Number::Phone, my set of perl modules for picking information out of phone numbers. Changes from the previous release are that Mayotte, Reunion and Comoros can't decide which country is which, and there's the usual updates to the database of UK numbers, mostly to support the <a href=http://www.ofcom.org.uk/media/news/2007/02/nr_20070213b>new 03 numbers</a>.

Dave's Free Press: CPANdeps

<a href=http://cpandeps.cantrell.org.uk/>CPANdeps</a> now lets you filter test results by perl version number, and also knows what modules were in core in which versions of perl. Hurrah!

Dave's Free Press: YAPC::Europe 2007 report: day 2

A day of not many talks, but lots of cool stuff. Damian was his usual crazy self, and MJD's talk on building parsers was really good. Although I probably won't use those techniques at work as functional programming seems to scare people.

The conference dinner at a Heuriger on the outskirts of Vienna was great. The orga-punks had hired a small fleet of buses to get us there and back, and one of the sponsors laid on a great buffet. The local wine was pretty damned fine too, and then the evening de-generated into Schnapps, with toasts to Her Majesty, to her splendid navy, and to The Village People.

It wasn't all debauchery in the evening though - on the bus, I had a very useful chat with Philippe about Net::Proxy, and re-designing it to make it easier to create new connectors for it.

Dave's Free Press: YAPC::Europe 2006 report: day 3

There were quite a few interesting talks in the morning, especially Ivor's one on packaging perl applications. Oh, and mine about rsnapshot, of course, in which people laughed at the right places and I judged the length of it just right, finishing with a couple of minutes left for questions.

At the traditional end-of-YAPC auction, I avoided spending my usual stupid amounts of money on stupid things, which was nice. Obviously the hundred quid I put in to buying the hair style of next year's organisers wasn't stupid. Oh no. Definitely not.

An orange mohican will suit Domm beautifully.

Dave's Free Press: YAPC::Europe 2007 report: day 3

My Lightning Talk on cpandeps went down really well, although as Jos? pointed out, I need to fix it to take account of File::Copy being broken. I also need to talk to Domm after the conference is over to see if I can get dependency information from CPANTS as well as from META.yml files.

There were lots of other good lightning talks. Dmitri Karasik's regexes for doing OCR, Juerd Waalboer's Unicode::Semantics, and Ren?e B?cker's Win32::GuiTest were especially noteworthy.

Richard Foley's brief intro to the perl debugger was also useful. Unfortunately Hakim Cassimally's talk was about debugging web applications, which I'd not noticed on the schedule, so I didn't stay for that.

And finally, Mark Fowler's grumble about why perl sucks (and what to do about it) had a few interesting little things in it. I am having vaguely sick ideas about mixing some of that up with an MJD-stylee parser.

At the auction I paid ?250 to have the Danish organisers of next year's YAPC::Europe wear the Swedish flag on their foreheads. This, I should point out, was Greg's idea. I would never be so evil on my own.

Dave's Free Press: Perl isn't dieing

Perl isn't dieing, but it tells me that it wishes it was. Last night it went out on the piss with Python and Ruby (PHP was the designated driver) and it did rather too many cocktails. It isn't quite sure what happened, but it woke up in the gutter in a puddle of its own fluids and its head hurts a lot.

It asked me to ask you all to keep the volume down.

Dave's Free Press: YAPC::Europe 2007 travel plans

I'm going to Vienna by train for YAPC::Europe. If you want to join me you'll need to book in advance, and probably quite some way in advance as some of these trains apparently get fully booked.
arr dep date
Waterloo 1740 Fri 24 Aug
Paris Nord 2117
Paris Est 2245
Munich 0859 0928 Sat 25 Aug
Vienna 1335

The first two legs of that are second class, cos first wasn't available on Eurostar (being a Friday evening it's one of the commuter Eurostars and gets booked up months and months in advance) and was way too spendy on the sleeper to Munich. Upgrading to first class from Munich to Vienna is cheap, so I have.

Coming back it's first class all the way cos upgrading was nearly free ...

arr dep date
Vienna 0930 Fri 31 Aug
Zurich 1820
Zurich 1402 Sun 2 Sep
Paris Est 1834
Paris Nord 2013
Waterloo 2159

Don't even think about trying to book online or over the phone, or at the Eurostar ticket office at Waterloo. Your best bet is to go to the Rail Europe shop on Picadilly, opposite the Royal Academy and next to Fortnums.

Dave's Free Press: Wikipedia handheld proxy

I got irritated at how hard it was to use Wikipedia on my Treo. There's so much rubbish splattered around their pages that it Just Doesn't Work on such a small screen. Given that no alternatives seemed to be available - at least, Google couldn't find any - I decided to write my own Wikipedia handheld proxy.

It strips away all the useless rubbish that normally surrounds Wikipedia pages, as well as things like the editing functions which are also hard to use on portable devices. Internally, it's implemented using perl, LWP, and mod_perl, and is hosted by Keyweb.de.

Shlomi Fish: Meta: Script to Filter the Master use.perl.org Blogs' Feed

As expected from the latest trend in the Perl blogosphere this post will be about Roles. And Moose! And Roles in Moose! And Moose in Roles! And Roles outside Moose…

Seriously now, this is a post about a completely non-Moosey and non-Roley script I wrote to filter the use.perl.org master journals' feed. What this script does is fetch the Atom feed of all the use.perl.org journals' posts, and filters out the entries of the use.perl.org authors that the invoker specified.

Here is out to use it. First of all: svn checkout it (or otherwise fetch it using HTTP). Then you can simply use:

perl filter-use-perl-journals.pl -o everything.atom

Then you can serve everything.atom with a web-server to read it using your web feeds' aggregator.

To simply create a non-filtered copy of the feed. Now let's say you want to get rid of posts from my journal (because it sucks). In that case, say:

perl filter-use-perl-journals.pl -o non-shlomif.atom \
    --blacklist="Shlomi Fish"

Now, let's say you also want to get rid of Ovid's posts. I have no idea why you'd want to do that, because his journal is great, but it's just for the sake of the example. In that case, do:

perl filter-use-perl-journals.pl -o non-shlomif-and-ovid.atom \
    --blacklist="Shlomi Fish" --blacklist="Ovid"

Finally, there's the --rand flag which is useful in case you're running the script with cron. What it does is wait for a period of time of random length, before fetching the feed, so the HTTP server would not be overloaded at regular periods. This requires a working /dev/urandom for the time being.

The script is made available under the MIT/X11 Licence so its use is completely unencumbered. I wrote this script today, because I have a personal use for it, but other people may find it useful too. It requires a recent version of Perl (5.8.x should be enough I think) and XML-Feed.

Header image by Tambako the Jaguar. Some rights reserved.