Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

ferreira (5993)

ferreira
  (email not shown publicly)
http://www.ferreira.triang.net/

Just another Brazilian Perl hacker.

Journal of ferreira (5993)

Tuesday September 16, 2008
05:36 PM

YAPC Brasil 2008 hatching

We just started preparing a YAPC Brasil 2008. It will happen together with CONISLI 2008, at São Paulo (http://www.conisli.org/), October 18-19. Yes, that's very little time until the event, but we'll make the best we can with our distributed efforts. Brazilians are known for being good at improvising. (But we'll work hard to make that work in this limited piece of time.)

We know we will have a stand and a room where the talks will happen. Everything else is in flux yet. We are going to try to put down a preliminary scheduling very soon, and we would appreciate contributors as speakers and people with good ideas and suggestions.

At first sight, it is quite possible that we can gather together many Perl developers that never meet one another in person. That's mainly the people who keep busy the mailing lists Cascavel-pm, Rio-pm, and SaoPaulo-pm.

We are assembling a preliminary list of talks here: http://www.perl.org.br/Main/Yapc2008Preliminares.

I will try to post more information on the event as it is available.

Saturday May 31, 2008
05:20 PM

Bye bye, old modules

I just scheduled for deletion (via PAUSE) the last CPAN files related to Carp-Indeed and Class-Constructor-Factory distributions. Both were renamed: Carp::Indeed became Carp::Always and was deprecate since a long time ago. Class::Constructor::Factory was meant to be renamed since its inception and became Class::Lego::Constructor. I doubt anyone will miss them.

These files will no longer be found in CPAN, but only at BACKPAN. It got me thinking at how often that sort of cleanup happens. There were some occasions when I only found modules mentioned in the documentation of other code at BACKPAN. In general, these deletions look sensible (incomplete code that were never finished, superseded code, etc.). But many times it is hard to find the reasons they were removed and what was left in its place (if any). So it looks like BACKPAN really become an archeological research field, with all the difficulties to reconstruct the past when someone wants to.

Wednesday April 30, 2008
09:50 PM

Is your file tidy? Really?

With respect to Perl::Tidy, it is quite obvious that a tidy file is one that has gone through perltidy and which does not change if reformatted again.

$ perltidy tidy_file.pl
$ diff tidy_file.pl tidy_file.pl.tdy
# zero, no difference

But Perl::Tidy is a work in progress which is constantly improving. And improving means changing. Those changes may include the fixes of some behaviors considered non-ideal or even flawed. So tidy files under a Perl::Tidy version may not be tidy under another version. So this concept is a little fragile (or needs a more precise wording).

Even Test::PerlTidy (which intends to capture that tidy-ness concept in the form of an automated test) was caught by this detail, since a new release of Perl::Tidy got out. Edmund von der Burg and me are working on a reasonable approach to this issue. Wait for a new release of Test-PerlTidy soon.

09:37 PM

Clashes between functional and OO worlds

In refactoring some code, I opted for turning "warn/carp" calls into method calls "$self->carp". This way the objects could act by themselves (using CORE::warn/Carp::carp) or cooperate with others (via a closure).

sub carp {
    my $self = shift;
    my $on_warn = $self->on_warn;
    if ( $on_warn ) {
         $on_warn->(@_);
    } else {
         Carp::carp(@_);
    }
}

It turned out that naming the method the same as a function was a bad idea (at least in the transition to the fully refactored code). The simple application used some simple hierarchies, and when I "fixed" the superclasses as in:

package Parent;

sub carp {
    ...
}

I found after some perplexity that in the children, code like that:

package Child;

use base qw( Parent );

use Carp qw( carp );

...
   $self->carp("message");
...

emitted strange messages like:

Parent=HASH()message

because $self->carp("message") resolved to Carp::carp( $self, "message" ) as Carp::carp had been exported to Child overriding the method I was expecting to inherit.

That's what we earn because methods are just subs.

Friday April 25, 2008
07:10 AM

Being clever by half may hurt

I know Perl may be quite irregular sometimes, and because it is irregular gotchas are easily glossed over and bite.

After some code refactoring, I ended up with a code like that:

for (@$x) {
    push @array, $_;
}

which immediately suggested me an equivalent expression:

push @array, @$x;

Unfortunately, this is not quite equivalent when $x is undef. Under strict, @$x bails with "Can't use an undefined value as an ARRAY reference " while for (@$x) {} works flawlessly as a loop that is never entered. So the real equivalence I was looking for is:

if ( $x ) {
    push @array, @$x;
}

whick is ok (as long as $x contains array refs or undefs).

Wednesday April 23, 2008
08:06 AM

"perldoc -A @+" is out there

Ovid proposed a patch to let perldoc search for Perl predefined variables from perlvar and mentioned it at use.perl here and here.

The development release Pod-Perldoc 3.14_05 brings this goodness to your delight.

Sunday March 09, 2008
03:13 PM

Nancy: from Lua to Perl

Some days before, Reuben Thomas (a known contributor to Lua community) announced the release of Nancy, "a simple web site builder" at the Lua mailing list.

For the dismay of Lua afficcionados, this release was not written in Lua.

Oh, and it's written in Perl. I thought it might be interesting to say why. The problem was not libraries (I used my pure-Lua stdlib and LuaFileSystem), but deployment on Windows (I use Linux). I had previously built an all-in-one binary for Windows using a cross-compiler. That worked fine but made it hard to debug on Windows as I couldn't just edit-run, and also broke nastily when the cross-compiler was upgraded. So, I switched to LuaBinaries. That enabled me in the end to deploy only pre-built binaries, but at the cost of having to install 2 binary packages, and then do manual fiddling to get .lua files run as commands by the Windows shell.

ActivePerl does all this for me, and I was already using some Perl scripts in the same system, so by rewriting Nancy in Perl I got down to "run the Perl installer" as being the prerequisites for running Nancy.

Nancy begun its life as Lua code (and that's the reason Reuben announced this at Lua mailing list for the last time unless it be written in Lua again in the future).

Perl still has an edge ahead before some of the popular dynamical languages out there, which (I hope) is not going away anytime soon in the future.

Wednesday March 05, 2008
03:13 PM

Abusing "Memoize"

A few days ago, I was writing a code (namely the Path-Classy dist) and stared at the code that produced the file size in raw bytes or "humanized" (28300 or 28K).

sub _format_size {
  my ($sz, $opt) = @_;

  my $format = $opt->{format};
  if ( $format eq 'h' ) {
    require Numbers::Bytes::Human;
    return Number::Bytes::Human->new->format( $sz );
  }
  else { # raw bytes
    return $sz;
  }
}

Of course, loading Number::Bytes::Human and creating a instance every time $f->size({ format => 'h' }) was invoked seemed overkill. But saving the N::B::H into a class/instance variable seemed overkill too: it has nothing to do with Path::Classy (which are Path::Class ) objects but for that instant relationship to format a file property, size.

Hey, that's a chance to use memoization, splitting the formatter creation into a function and then memoizing it (so that we don't need to create a [reusable] object with the same capabilities over and over), we come to this code.

use Memoize;

sub _size_formatter {
  require Number::Bytes::Human;
  return Number::Bytes::Human->new;
}
memoize('_size_formatter');

sub _format_size {
  my ($sz, $opt) = @_;

  my $format = $opt->{format};
  if ( $format eq 'h' ) {
    return _size_formatter->format( $sz );
  ...

That looked elegant to me. To make it even more tight (and to require yet another CPAN module ;-) ), using Attribute::Memoize seemed right. It avoids the need to repeat the function name in the memoize call and it anticipated the wrapping up of the sub to BEGIN time (a free bonus of Attribute::Handlers in the backstage).

use Attribute::Memoize;

sub _size_formatter :Memoize {
  require Number::Bytes::Human;
  return Number::Bytes::Human->new;
}

That's it! Efficient code, localized behavior, no need for extra variables. Will people understand that for maintenance? I hope so.

Thursday February 14, 2008
11:07 AM

Wanna break some dists?

An easy recipe to do this is to include a dependency on a module version which only development releases reached that far.

That will provoke installations by the CPAN shell to fail complaining about a bad dependency. These actually will generate NA test reports because of dependencies which could not be satisfied.

I saw such an example the other day. The dist KSx-Analysis-StripAccents declared a dependency on 0.2 version of KinoSearch . The latest stable release of KinoSearch is 0.162 and the current devel release is 0.20_05. That filled CPAN Testers with NA reports on SPROUT's module.

Note that this is not a major fault from author's part. It is just how the toolchain works nowadays. There is no automated way to have a dependency on development versions, which seems a good thing, but which cannot be circumvented (unless it is done manually).

Maybe, that has some resemblances with declaring dependencies on third-party modules which are not in CPAN (like SVN::Core and modules in the list kept by Module::ThirdyParty, and company-specific code).

Wednesday February 13, 2008
12:13 PM

What's better? -Ilib or -Mblib?

When testing/playing with a distribution, one usually runs:

$ perl Makefile.PL; make
$ perl -Mblib demo.pl
# or (with tests)
$ prove -b test.t

Sometime the make (or ./Build) gets annoying and a shortcut is nice:

$ perl -Ilib demo.pl
# or
$ prove -l test.t

However, there are a bunch of reasons not do that. Among them:

  • -Ilib won't work for modules with XS parts (it will use installed XS components or fail to load)
  • the current build settings may establish an environment different from the current lib/ layout (with modules not in the MANIFEST and things like that)

At the end, we conclude that working under -Mblib is safer (and closer to release conditions) than playing with -Ilib.