Dal vecchio articolo di Rolsky (Moose, DateTime) su cos’è Catalyst, sono passato (grazie ad un link nei commenti) ad un altro vecchio post 10 Catalyst models in 10 days scritto da Ashley Pond.
Mi è sembrato simpatico, con idee carine.
- Catalyst Model #1: Random quotes
- Catalyst Model #2: Moon phase data
- Catalyst Model #3: Cover images via Amazon.com’s APA
- Catalyst Model #4: Random numbers and really-o, truly-o random numbers
- Catalyst Model #5: Stock quotes
- Catalyst Models Intermission—MyApp source code browser
- Catalyst Model #6: Log file model–Apache access log
- Catalyst Model #7: Page view counter/tracker
- Catalyst Model #8: Titles in real typefaces on demand with Imager
- Catalyst Model #9: TheSchwartz
- Catalyst Model #10: Fixing your legacy code by not fixing it
- Wrap-up: 10 Catalyst models in 10 days
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.
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:
o (in maniera più perlica, poichè CPAN è infine anche un modulo)
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:
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:
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.)