venerdì 28 ottobre 2016

From File::Find to File::Find::Rule

I tend to use File::Find the most in order to get some file searching and mangling. Usually my scripts have the same simple structure as follows:

$| = 1; # autoflush
find( \&directory_scanner, ( $starting_directory ) );
$| = 0; # non autoflush

# and the scanner is something like
sub directory_scanner{
    chomp;

    return if ( $_ eq $starting_directory || ! -f $_ );
    return if ( $File::Find::dir !~ /$re_dir(\d{4}-\d{6})$/ );
    ...
}
 
As you can see the event handler invoked by File::Find is used to both print some report (the $counter) in order to tell me the script is still alive (I do pass 200+k files at once) but, most notably, applies a regexp to the directory I'm in in order to avoid some staging/backup/etc. directory that could be likely the one I'm interested into but I don't want the script to pass.
For a few times I've tried to convert my Find::File based scripts to File::Find::Rule, just to get more used with such interface, but I didn't know how to fix the application of regular expression to the traversing path. Reading a little more deeply the documentation I found the exec subroutine that allows me to specify an handler (i.e., a subroutine) that can return true or false depending on what I want to do on the file I'm visiting. Therefore, converting my scripts becomes as easy as follows:
 
$| = 1; 
my $engine = File::Find::Rule->new();
my @files  = $engine->file()
    ->exec( sub {
        my ( $shortname, $path, $fullname ) = @_;
        return $path !~ /$re_dir(\d{4}-\d{6})$/;
            } )
    ->exec( sub{
        my ( $shortname, $path, $fullname ) = @_;
        $counter++;
        return $shortname =~ /KCL/;
            } )
    ->exec( sub{
        my ( $shortname, $path, $fullname ) = @_;
        print "." if ( $counter % 100 == 0 );
        print "$counter\n" if ( $counter % 1000 == 0 );
        return 1; # do not forget !
            } )
    ->in( $starting_directory );
$| = 0
 
I've kept three different handlers for readibility sake, but as you can image, it is possible to shrink them down into a single one. The funny part here is that I can check the path against a regexp again. The drawback is that an handler used for output reporting only must return always a true value.
In the case you are wondering, the autoflush is used simply to display the dots while the program is running.

not $foo++

Sono inceppato nell'impementazione di List::MoreUtils::PP::uniq e ho notato una cosa che mi ha fatto sorgere un grosso punto di domanda: un uso quasi malsano dell'operatore not. Ma in fondo è questo il bello di Perl: riuscire ad esprimere concetti molto difficili con pochissimo codice. Ecco quindi il codice in esame:


sub uniq (@)
{
    my %seen = ();
    my $k;
    my $seen_undef;
    grep { defined $_ ? not $seen{ $k = $_ }++ : not $seen_undef++ } @_;
}
 
Il trucco che fa funzionare il tutto è in quel pezzo not $seen{ $k = $_ }++, e in particolare nella negazione. Provo a smontare il codice far comprendere come io sono giunto alla soluzione. Anzitutto la funzione grep processa la lista di paramentri e si aspetta un risultato true o false a seconda del fatto che lo si voglia restituire in uscita dalla funzione (essendo grep l'ultima istruzione effettuata si ha un return implicito). Se il parametro corrente $_ è valido (defined) lo si usa come chiave di un hash %seen e si incrementa (con autovivification) il valore della cella relativa. Fin qui tutto facile, ma occorre ricordarsi che l'operatore postfisso ++ restituisce il valore prima del suo incremento. In sostanza, la prima volta che si trova un elemento nella lista la relativa cella di %seen viene incrementata ma il valore restituito dall'operazione di ++ è zero (ossia falso). Questo valore viene passato all'operatore not che a sua volta lo riconverte in contesto boolean a true e l'elemento viene "greppato" nella lista di ritorno. Alla successiva occorrenza dello stesso elemento la sua cella in %seen viene incrementata, l'operatore ++ restituisce il vecchio valore (1) e questo viene forzato in contesto boolean (quindi true) e negato portando quindi il valore a false, scartando quindi l'elemento. Cosa analoga avviene per i valori undefined, che però in questo caso vengono considerati tutti uguali e quindi non si ha bisogno di tenerli come chiave di un hash.
Direi un bell'esempio di come Perl 5 possa portare a codice molto compatto che però richiede un po' di potenza mentale per essere interpretato!

venerdì 14 ottobre 2016

PGDay.IT 2016: there's some extra time before the CFP is out!

Ehi, the CFP for the PGDay.IT 2016 (Italian tenth edition of the PGDay) has been extended until next Saturday 22 October at 23:59 (Rome).
Don't miss the opportunity to be a speaker at one of the most well known PGDay!

Happy Birthday KDE!

Oggi KDE (era Kool Desktop Environment) compie 20 anni!
E da circa 8 è il mio desktop di riferimento, per scelta, sia per uso quotidiano che sviluppo.
Ho scritto tanti post su questo famoso e glorioso progetto, ma oggi una cosa in particolare ha fatto sobbalzare il mio animo informatico: una nuova release di KDE 1. No, non è un errore di battitura, bensì lo sforzo di un programmatore di mantenere in vita la prima versione del famoso desktop facendola girare su sistemi moderni. E poco dopo l'uscita di una immagine NEON, che non vedo l'ora di provare.
Già, ricordo ancora quando quel desktop comparve, brillante e ordinato, sulla mia Mandrake 6 che dopo appena un paio di ore si era installata su un vecchio Celeron a 300 MHz...

PGDay.IT 2016: CFP estesa ancora di qualche giorno

Al fine di fornire un PGDay.IT 2016 denso e ricco di contenuti gli organizzatori hanno deciso di estendere la Call For Papers di ancora qualche giorno, e precisamente fino a 

SABATO 22 OTTOBRE alle ore 23:59

Le informazioni su come inviare un contributo si trovano sul sito ufficiale della conferenza.

Questione di educazione...

Eh si, su gigetto si incontra gente molto variegata e soprattutto variopinta.
Ebbene chi come me lo prende alla mattina sa che il treno è assaltato da studenti assonnati dal naso illuminato dai loro smartphone (ma che C$%&! vi dovete scrivere alle 7 della mattina?) e quindi si fatica un po' per trovare un posto a sedere.

E così qualche giorno fa trovo due persone sedute una di fronte all'altra, che occupano bellamente ciascuno un sedile da due posti. Faccio segno ad uno dei due di farmi spazio e senza troppi convenevoli mi siedo. Ovviamente il signore in questione brontola con la sua compagna di chiacchere circa la mia intromissione, ma forse a quell'ora della mattina sono troppo assonnato e troppo educato per mandarlo a farsi...beh avete capito.
Dopo qualche fermata una studentessa, con aria gentile e molto educata, chiede cortesemente alla signora che mi stava di fianco se poteva sedersi, visto che il resto del sedile era occupato dal suo marsupio (non zaino, marsupio).
La signora molto sgarbatamente risponde di no, e manda via la studentessa che, visibilmente perplessa ha perfino l'educazione per scusarsi del disturbo.
E da qui inizia un concione della signora che spiega al suo compagno di viaggio che lei deve andare a lavorare, che si vuole riposare sul treno, che non vuole stare pigiata, che gli studenti possono andarsene aff...
Ora, considerato che a tutti piacerebbe viaggiare comodi, non pigiati come sardine, senza l'alito del vicino in faccia o la tosse di qualche ragazzoto che si asciuga il naso nella manica o il telefono di un qualche personaggio scuro che urla. Ma al momento non pare che i trasporti vogliano dare soluzione e soddisfazione a viaggiatori. E a parte questo, l'educazione è ancora un valore importante.

Quindi cara signora, spero vivamente che qualche studente non ti lasci il posto la prossima volta.

Inserire il cubo nel buco della sfera......

Chissà, forse gente non ha mai fatto all'asilo quel simpatico gioco in cui si dovevano inserire le forme giuste nel foro giusto.
Perché affermo questo?
Beh, è molto facile osservare ai supermercati donne indaffarate alla cassa mentre tentano di infilare il carrellino rettangolare in quello stondato. Certo, le due forme non sono compatibili, ma nulla ferma la donna in carriera che con forza da muratore riesce ad incastrare i due oggetti fra loro.
Un altro esempio lo sti trova nella stazione centrale dei treni di Modena. Fino a qualche mese fa le panchine esterne erano di forma semicircolare e addossate alle pareti delle scale, ovvero ben riparate dalla pensilina in caso di pioggia. Ebbene un qualche colto ha deciso di sostituirle con un altro modello di panchina, lineare. Nulla di male fino a qui, peccato che, per usare esattamente lo stesso spazio tali panchine siano state messe lunghe quanto il raggio del cerchio di quelle di prima (eh si, devono stare nello stesso spazio). E come ti insegnano nella geometria piana delle elementari il raggio è ben piu' lungo della circoferenza! O no?



Vabbé, ma il colpo di genio non finisce qui: per permettere una comoda seduta da ambo i lati della panchina questa è stata spostata dal muro e quindi si trova esattamente sotto al bordo della pensilina. In altre parole quando piove l'acqua arriva direttamente sulla panchina. E in tutto questo quanti posti in piu' sono stati guadagnati? Nessuno! Eh si, perché anche se bilaterale la panchina non è piu' larga di quella precedente, quindi un posto su un lato occupa anche l'altro lato. Provare per credere!

Ma il premio assoluto per non aver giocato al gioco degli incastri lo vince chi ha progettato i bidoni della spazzatura con oblç per i sacchetti del pattume. Già, perché così si insegna il senso civico di dover infilare un sacchetto di dimensioni prestabilite in un foro prestabilito. COme è noto esistono standard molto ferrei nella produzione di pattumiere, quindi non capiterà di certo che vi siano in commercio bidoncini di forma e dimensione differenti! O no?
Uhm...forse gli standard sulle pattumiere non sono poi così definiti, visto che tutti i bidoni sono stati poi rifatti per permettere l'apertura totale senza oblò. 
Allora prima di fare questi ammodernamenti inutili, magari mandiamo questa gente a fare un corso di geometria base.

giovedì 13 ottobre 2016

Hacktoberfest

Si, sto cercando di partecipare all'Hacktoberfest 2016.
E qui si trova il mio stato ad oggi, anche se non sto partecipando solo a patch #Hacktoberfest!