Lavorando su un progetto che sfrutta Catalyst, mi sono ritrovato dinnanzi ad un problema oscuro: gli stessi dati, provenienti dalla stessa sorgente, maneggiati allo stesso modo, passando attraverso due viste diverse, davano luogo a due risultati differenti. Può capitare, ovviamente.

                +-------------------+
                | db Postgres UTF-8 |
                +---------+---------+
                          |
                +---------+--------+
                | Modello Catalyst |
                +---------+--------+
                          |
               +----------+----------+
               | Controller Catalyst |
               +----------+----------+
                          |
             +------------+--------------+
             |                           |
+------------+-----------+   +-----------+---------+
| subroutine che punta a |   | subroutine che crea |
| vista Template Toolkit |   | una vista XML::Feed |
+------------+-----------+   +-----------+---------+
             |                           |
 +-----------+----------+     +----------+----------+
 |   Vista giusta coi   |     | Vista sbagliata con |
 | caratteri in ordine. |     | encoding a ramengo. |
 +----------------------+     +---------------------+

Le pagine di documentazione consultate sono state le seguenti:

Nella notte dei tempi (quando gli uomini erano uomini e usavano ed) un carattere ascii era un byte – altrimenti detto un ottetto (di bit).
In soldoni, bastavano 8 bit per descrivere un carattere.
Ora, in quest’epoca di perdizione, un carattere come 読 è qualcosa di diverso – e può occupare più ottetti.

Perl di default pensa che ogni cosa sia un ottetto; è quindi necessario dire esplicitamente a Perl quando una fila di dati (binari) è del testo da convertire: se si è consapevoli del charset del testo, si può fare un decode dei dati binari in modo che Perl gestisca il tutto con codifiche che riconosce.

my $content = decode(‘utf-8′,$quote->{$id}->{‘text’});

In questo modo $content contiene la stringa in un modo che Perl può gestire.

In verità il mio problema era un po’ più sottile, perché attualmente Perl ha supporto nativo per i caratteri UTF-8 (come molti browser e terminali), ma non tutti i moduli di CPAN gestiscono la cosa in maniera trasparente.
Un modulo esterno a Catalyst quindi, va trattato a sè – nel mio caso, il modulo scassa, era XML::Feed.

Nota: In realtà Catalyst ha due plugin (uno vecchio e uno nuovo) per gestire in maniera automatica l’encoding dei suoi contenuti: Catalyst::Plugin::Unicode e Catalyst::Plugin::Unicode::Encoding . Personalmente preferisco evitare di installarmi ulteriori moduli se posso evitare il problema con qualcosa di molto semplice che ho già – come in questo caso. ;-)

CPAN è l’archivio online di tutta la robaccia che i vari perlisti si inventano. C’è bisogno di qualche modulo per puffare qualcosa di puffoso? Vallo a cercare su CPAN!

cpan è anche un programma che permette di interagire via linea di comando con l’archivio online di CPAN per scaricare e gestire i moduli perl che potrebbero risultare utili. Nel caso ce ne sia bisogno, si puo’ lanciare con un:

# cpan

o (in maniera più perlica, poichè CPAN è infine anche un modulo)

# perl -MCPAN -e ‘shell’

cpan ha un file di configurazione che indica dove e come agire quando si scaricano i moduli. Queste informazioni (che di solito stanno in un qualcosa di simile a CPAN/Config.pm) su debian sono nel file /etc/perl/CPAN/Config.pm; la configurazione è un semplice hash gestibile dalla shell di cpan con il comando > o conf.

Ovviamente, come per tutti i linguaggi, i file-librerie (moduli) che si usano per “aggiornare” il perl vanno messi in percorsi specifici che in questo caso sono dentro l’array @INC; lanciando un programma perl il compilatore va a cercare le lib incluse.
In Debian:

# Directory per lib perl in Debian

perl -e ‘for (@INC) { if (-d $_) { print "esiste    : $_"; } else { print "non esiste: $_"}; print "\n" }’
esiste    : /etc/perl
non esiste: /usr/local/lib/perl/5.10.1
non esiste: /usr/local/share/perl/5.10.1
esiste    : /usr/lib/perl5
esiste    : /usr/share/perl5
esiste    : /usr/lib/perl/5.10   #link a 5.10.1
esiste    : /usr/share/perl/5.10 #link a 5.10.1
non esiste: /usr/local/lib/site_perl
esiste    : .

Ohibò.
Gli /usr/local non esistono. WTF?

Di recente (settembre mi pare) perl è passato alla versione 5.10.1, e mentre Debian si è aggiornata serenamente in modalità semi-automatica, la parte /usr/local/ che viene gestita attraverso il modulo CPAN non e’ stata upgradata (son fesso, I know).

Dovendo cercare un modulo perl e auspicando che più controlli siano meglio, tanto vale affidarsi ai manutentori di Debian – cpan potrebbe essere più esotico e volatile; come sistemisti avere una base più solida può essere ritenuto generalmente migliore, anche se si rimane indietro di un paio di sottoversioni della lib voluta.
apt di norma ha tutti i pacchetti che si potrebbero volere, basta trovarli, e li si può a ragione ritenere stabili.
Le ricerche sui pacchetti di Debian possono essere completate nei due form a questa pagina; il secondo ricerca esattamente i pacchetti che contengono il file nominato, il che puo’ essere utile quando si ricerca un modulo specifico visto su CPAN.
(Es: Ricercando il modulo Restarter.pm si ottiene questo.)


Nota: le installazioni di cpan dipendono dal Makefile del modulo (vedere qui: /root/.cpan/build/ ), mentre quelle di Debian dai pacchetti (# dpkg -L nome_pacchetto).

Nota2: Se si è su Slackware o Gentoo, probabilmente tutte le lib perl stanno in un percorso sotto /usr/lib/perl divise per versione, site_perl e vendor_perl a seconda di come sono state installate.

Per servire un semplice file di testo come risultato di una chiama HTTP (una semplice view txt, insomma) con Catalyst:

sub testo : Path {
        my ($self,$c) = @_;
        my $txt = ‘Servi un file di testo, cavolo!’;
        $c->res->content_type(‘text/text-plain’);
        $c->res->header(‘Content-Disposition’, qq/attachment; filename="data.txt"/);
        $c->res->body($txt);
}

Semplice semplice. :)

Per la serie, sperimentiamo framework a caso.
Nella mia spasmodica voglia di carpire qualcosa di utile in questi minchia di framework che popolano l’universo (non ci credete? O_o), ho installato rapidamente come test su rodio Catalyst.

Su freeBSD, cercare il port www/p5-Task-Catalyst/ e dare un bel # make build install clean.
Post installazione, andare in una dir a casaccio (magari servita dal webserver per ulteriori sviluppi) e, dopo aver letto rapidamente il man di catalyst, comandare:

# catalyst.pl nome_webapp

A questo punto si crea lo “scheletro” del framework – leggere il readme e cominciare a scrivere componenti. :)
(Con script/webapp_server.pl faremo girare l’applicazione sulla porta 3000. Per un neofita come me, pare ricalcare lo schema di rails.)

    
SIMOTRONE WEB PAGE is based on WordPress platform, RSS tech , RSS comments design by Gx3.