19 May 2007 fxn   » (Master)

CPAN

CPAN is, no doubt, one of the great things about Perl. I am not talking about the amount of modules, but about the repository itself.

A central repository is certainly good, but what I think makes CPAN fantastic are the consequences of having such a thing:

  • If you need a module you know where you to go to search for it.
  • Since there's a shared way to do things, people are able to create tools around this, like cpan(1), skeleton generators for new distributions, IRC bots that announce releases, etc.
  • If you want to contribute a module the path is clear and well-defined. I am convinced that makes easier for people to become module authors and explains the amount of work there.
  • It makes viable the existence of volunteers that test modules in their machines and report the results back in an organized way. You can see your test suite PASS or FAIL in multiple platforms. See for instance the CPAN Testers reports of my modules. Man I think that's invaluable.
  • Style in documentation, distributions, module testing, etc., converge because such a centralized repository gives a context where your work can naturally fit.
  • And more ...
Those are some implications of the existence of CPAN, which I believe greatly amplify its benefits.

Algorithm::Combinatorics

Precisely thanks to a CPAN Tester, David Cantrell, I knew the last release of Algorithm::Combinatorics was broken on Perl 5.6.2. David was so kind as to provide me with a shell account in his machine to be able to debug the problem. I could run Valgrind in his Linux this way, how kind and helpful of him, thank you dude!

The sympton was that 2 tests out of about 300 in the suite gave a segfault. I've spent some nigths this week working on that problem, and finally I discovered the culprit.

You know Perl has scalars, that's a type of data that can store strings, integers, doubles, references, ... The C structure that represents scalars is called SV. My module constructs private arrays of indices and performs the combinatorics on those arrays. When a tuple is generated a wrapper in Perl-land slices the original array of data and that's what iterators return. OK, since those are private integers the XS code can rely on that, and used the macro SvIVX which goes directly into the IV slot of a SV. It can in fact act as an lvalue. That is, in the code we assume the SVs actually hold integers.

Perl 5.8.x tries to preserve IVs, but 5.6.x did not, I had forgotten that. Just about any arithmetic you did on an integer gave a double behind the scenes, that's what the following NV means:


  $ perl5.6.2 -MDevel::Peek -e '$a = 1; $b = $a + 1; Dump $b'
  SV = NV(0x180a810) at 0x1807730
    REFCNT = 1
    FLAGS = (NOK,pNOK)
    NV = 2
and so my assumption was broken. The subroutine partitions() has some of that simple arithmetic involving indices. The code read the IV slot, which contained garbage, and that had the side-effect of an invalid memory access later. Once I understood what happened the fix was trivial, which is to base the code on the SvIV macro instead. That macro returns an integer doing conversions if necessary. I published today a new release with the correct XS.

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!