Ramblings

<rant>

Subscribe to RSS feed

Pumpkin Perl logo

, , ,

Spent some hours yesterday contemplating how a Pumpkin Perl logo could look like. Opinions? http://jolly.opentheweb.org/pumpkin/

Using map to have less explicit checks, good idea or bad?

,

So, sometimes you want to get the attribute of the first element of a list that might be undefined or empty. You want to keep passing around references both for clarity, and for convention, and use some Modern Perl style, and you don't want to die if something might be missing.

The other day I accidentally ran into using map() for that, what do you guys think?

Clear, easy and somewhat clever or hard-to-grasp, and useless?

(BTW: I guess List::Utils::first would save map() going through the whole array?)

# Example 1
sub get_first_person_name {
    my ($self) = @_:

    my $persons = $self->persons() || [];

    if (scalar @{ $persons }) {
        my $first_person = $persons->[0];
        if (ref $first_person) {
            return $first_person->{name};
        }
    }
    return;
}
vs.
# Example 2
sub get_first_person_name {
    my ($self) = @_;

    my ($first_person_name) = map { ref $_ && $_->{name} } @{ $self->persons() || [] };

    return $first_person_name; 
}

Too be fair I guess a more modern version of Example 1 would be:
# Example 1b
sub get_first_person_name {
    my ($self) = @_:

    my $persons = $self->persons() || [];

    return unless (ref $persons && scalar @{ $persons } && ref $persons->[0]);
    return $persons->[0]->{name};
}

But doesn't the map-style really save you a lot of thinking and explicit error-checking?

Using named parameters without names when calling functions in perl

, ,

I just read my collegue Zbigniew Lukasiak's blog post about wanting to pass variables without doing redundant work like: foo({ email => $email, username => $username }). I totally loved the idea as I'm doing this kind of stuff all the time. And just passing an object reveals its internal representation, unless you add cascades of getters/setters which are really (most of time) revealing its internal representation anyway.

So, I noticed he got a comment that he could use Devel::Declare and do something like the Perl6 implementation of prototypes, but I think it can be even easier than that (as it requires you to actually make new keywords and what not.)

Enter autoparams.pl:
#!/usr/bin/perl -wl
use strict;
use warnings;
use PadWalker qw/var_name/;

use Data::Dumper;

{
  no strict 'refs';
  *{'main:::'} = sub {
    my $ret;
    my @params;

    foreach  (@_) {
      my $var_name = var_name(1,\$_);
      do { $ret->{substr $var_name, 1} = $_; next } if $var_name;
      push @params, $_;
    }
    return $ret, @params;
  };
}

sub foo {
  print Dumper(\@_);
}

my $a = 123;
my $b = 'abc';
my $c = { foo => 'bar' };

foo(&:($a, $b, $c, '456', '567'));

gives:
$ perl perl/autoparams.pl
$VAR1 = [
          {
            'c' => {
                     'foo' => 'bar'
                   },
            'a' => 123,
            'b' => 'abc'
          },
          '456',
          '567'
        ];

Of course the implementation details could be slightly different, but I'm thinking something like this might make sense.

Family pic








Sendt fra min iPad

Synchronizing non-utf8 (latin-1) files with svnsync

, , ,

So, I was trying to run svnsync on an old repository to be able to list it in trac since it doesn't support remote repositories. After following the notes on how to synchronize, and setting up the repository, the synchronization process stopped with a simple svnsync: REPORT of 'http://repo/svn%27: 200 OK (http://repo).

After a lot of investigation, and various theories it turned out the synchronization stopped because of a committed file having a filename in latin-1 format. I didn't notice this until viewing the repo thru SVN::Web.

svnsync is supposed to add support for log messages wrongly committed as latin-1 in 1.7, but I didn't see any mention of actual filenames in latin-1.

So after various attempts and asking in the #subversion channel on irc.freenode.net it hit me, that I could set up a proxy that fixed the filename in the response itself. The solution ended up being:

Enable the use of a proxy in .subversion/servers

[global]
http-proxy-host=localhost
http-proxy-port=8080

Set up a translating proxy

#!/usr/bin/perl

use HTTP::Proxy;
use HTTP::Proxy::BodyFilter::simple;
use Data::Dumper;
use Encode;

my $proxy = HTTP::Proxy->new( port => 8080 );


$proxy->push_filter(
    method  => 'OPTIONS, PROPFIND, GET, REPORT, MKACTIVITY, PROPPATCH, PUT, CHECKOUT, MKCOL, MOVE, COPY, DELETE, LOCK, UNLOCK, MERGE',
    mime     => '*/*',
    response => HTTP::Proxy::BodyFilter::simple->new(
        sub { warn Dumper($_[1]); ${ $_[1] } = Encode::encode_utf8( ${ $_[1] } ); }
    )
);

$proxy->start;

And voila, syncing is working again! ;)

Unrecognized character \xC2

, ,

Ever seen this before? For me with a Norwegian keyboard, I run into it all the time. It happens specially when reaching out for the { } characters, and accidentally still keeping down AltGr when pressing space.

It's a pain in the ass, as AltGr+Space inserts a non-breakable space which is not valid in various programming languages, like perl, but still not visible to the eye.

nicolasm@akiko:~$ perl -wle 'my $a = { };'
Unrecognized character \xC2 in column 10 at -e line 1.
nicolasm@akiko:~$ echo "perl -wle 'my $a = { };'" | hd
00000000  70 65 72 6c 20 2d 77 6c  65 20 27 6d 79 20 20 3d  |perl -wle 'my  =|
00000010  20 7b c2 a0 7d 3b 27 0a                           | {..};'.|
00000018

Notice the c2 a0 combo between the curly brackets!

After ages of annoyance I finally found the solution via: http://lostwebsite.wordpress.com/2008/10/27/annoying-non-breakable-spaces-in-bashzsh/

In Ubuntu you can fix this by going to: Settings -> Keyboard -> Layout -> Alternatives, and select "Using space key to input non-breakable space character" and set it to: "Usual space at any level"

or to quickly fix it:
setxkbmap -option "nbsp:none"
in a shell

For Gnome3 (and Unity?): simply type "region" <Enter> in the command input and choose the same option.

PROFIT!

Facebook via Bitlbee username renaming script fix

, , ,

I have been using Facebook's XMPP chat for a while in bitlbee now, following the instructions at http://www.mindfuzz.net/?p=155 or http://pthree.org/2010/02/13/facebook-chat-in-bitlbee/ and everything has worked smoothly.

Until today, when Facebook seems to have renamed the usernames from u12345678 to -12345678. That made the auto rename script fail, as the whois $nick call, interpreted the username with a dash as an option, leading to the following output: Irssi: Unknown option: 12345678.

This is perfectly fixable, by simply changing the line:

    $server->command("whois $nick");
to:
    $server->command(qq{whois "$nick"});
in the bitlbee_rename.pl script. If anyone could notify the original author of the script, that would be awesome.


This is already fixed in: http://github.com/avar/irssi-bitlbee-facebook-rename/commit/251fb9b3529b3d765d4d936f008768707ccbb62d

Nomnomnom

Nomnomnom

Is there a use for u"æøå" notation in perl?

,

After struggling a bit with charset issues on MyOpera, mostly because of historical decisions or lack of, specifically agnostic use of strings in databases, I have become friends (love/hate relationship) with Encode, decode_utf8 for reading and encode_utf8 for outputting. But that's strictly for handling I/O.

When using strings constants containing utf8 characters you would need to either set the utf8 flag (utf8::_utf8_on) on your string, use utf8::upgrade or use utf8;.

The latter a bit scary and possibly inconsistency as in addition to letting you use utf8 characters as variable names etc, it also treats all string constants as utf8 strings. However it needs to be included everywhere to be sure, and that might be cumbersome when using many modules, possibly external ones that don't etc. etc.

So I was wondering if there actually could be any use of having a similar notation to python to allow you to explicit set string constants as utf8. An example would be:

perl -wle 'sub u { utf8::upgrade(shift); }; print encode_utf(u"æøå");'
What do you think?

Packaging HTML::Tidy for Debian 5.0 "Lenny"

, ,

Today at work a collegue asked help in getting the perl module HTML::Tidy working on a newly installed Deban 5.0 "lenny" machine. The module was needed for an intranet system currently running on Debian 4.0 "Etch", but since Etch is being deprecated, the new development server needed it to, but it was unfortunately not available in the standard package repository.

I have previously always encouraged people needing non-packaged CPAN modules to use the outstanding dh-make-perl. A simple
dh-make-perl --install --cpan HTML::Tidy
would normally have built and installed a Debian package in seconds.

Unfortunately this time it didn't, it compiled just fine, except some warnings about signed chars, but while running the tests, it failed.

t/perfect............dubious                                                 
	Test returned status 0 (wstat 11, 0xb)
DIED. FAILED test 3
	Failed 1/3 tests, 66.67% okay
t/pod-coverage.......ok                                                      
t/pod................ok                                                      
t/roundtrip..........ok                                                      
t/segfault-form......ok                                                      
t/simple.............ok 1/4Unknown error type: line 2 column 5 - Info: <body> previously mentioned at t/simple.t line 17
Unknown error type: line 2 column 5 - Info: <body> previously mentioned at t/simple.t line 17
Unknown error type: line 2 column 5 - Info: <body> previously mentioned at t/simple.t line 17
t/simple.............ok                                                      
t/too-many-titles....ok 1/3Unknown error type: line 4 column 9 - Info: <head> previously mentioned at t/too-many-titles.t line 22
t/too-many-titles....ok                                                      
t/unicode............dubious                                                 
	Test returned status 0 (wstat 11, 0xb)
DIED. FAILED test 7
	Failed 1/7 tests, 85.71% okay
t/venus..............ok 1/3Unknown error type: line 8 column 2 - Info: <h1> previously mentioned at t/venus.t line 21
Unknown error type: line 10 column 2 - Info: <h1> previously mentioned at t/venus.t line 21
Unknown error type: line 11 column 2 - Info: <h1> previously mentioned at t/venus.t line 21
Unknown error type: line 12 column 2 - Info: <h1> previously mentioned at t/venus.t line 21
Unknown error type: line 15 column 2 - Info: <h2> previously mentioned at t/venus.t line 21
Unknown error type: line 17 column 2 - Info: <h4> previously mentioned at t/venus.t line 21
Unknown error type: line 18 column 2 - Info: <h4> previously mentioned at t/venus.t line 21
Unknown error type: line 20 column 2 - Info: <h4> previously mentioned at t/venus.t line 21
Unknown error type: line 25 column 3 - Info: <h4> previously mentioned at t/venus.t line 21


A bit of googling and searching on CPAN led me to find two patches, one to ignore the error warnings, and one to fix what turned out to be segfaulting of the script. The latter is most likely caused by Lenny having a newer snapshot of libtidy, which is according to the author of HTML::Tidy informed is not really released, but they expect people to check out their source tree and compile themselves. Luckily Debian provides a package with a corresponding version name with the date it was made.

However the author of HTML::Tidy, Andy Lester, naturally, can't only rely on a specific Debian version and expect any user to use that (Perl is available on numerous platforms and distributions), so he is planning to include a snapshot of libtidy in the HTML::Tidy module itself, but hasn't had time to do it yet. Thanks to Andy for quickly giving me some insight btw ;-)

So, to make it work do the following:

dh-make-perl --cpan HTML::Tidy
cd HTML::Tidy # possibly having to tab your way to something like HTML::Tidy.37534
wget -O - http://rt.cpan.org/Ticket/Attachment/365180/165489/tidy.patch | patch -p0
cat | patch lib/HTML/Tidy.pm
267a268,271
>    elsif ( $line =~ m/^line [\d]+ column [\d]+ - Info:/ ) {
>    # Info line we don't want
>    
>    }
Ctrl+D
dh-make-perl --build


and you should have a working debian package in the parent directory. Remember to set DEB_FULLNAME and DEB_EMAIL environment variables first so that you get a proper Author: entry for the package.

For more info about the module and the patches:



June 2013
M T W T F S S
May 2013July 2013
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30