Dalla shell al web. Conversione di uno script di shell in HTML.

Dott. Emiliano Bruni, info/at/ebruni_dot_it
Copyright 2005-2006 Emiliano Bruni

Ultima modifica: 2005/12/26
Licenza Creative Commons

Abstract.

Analizzando del codice reale in Perl si imparerà, tra le altre cose, a deserializzare dei dati salvati tramite il modulo Data::Dumper e come convertire uno script di shell in uno script Web-based. Si analizzeranno inoltre alcuni metodi di scrittura degli script web in particolare la modalità mista codice+html e quella basata sui template  sia costruiti ad-hoc e sia con l'utilizzo di un più generico motore di templating.

Introduzione.

Questo articolo prende spunto dalla necessità di mostrare l'output prodotto dalla script irc_check.pl descritto in un mio precedente articolo. Questo script controlla la presenza o meno di un utente sulla rete IRC e salva lo stato dell'utente e l'elenco dei canali in cui esso è presente in una struttura dati salvata su di un file tramite il modulo Data::Dumper.

Per basarci quindi su di un caso reale da cui estrarre alcune caratteristiche peculiari del Perl, inizieremo a realizzare uno script da lanciare via shell che ci mostri se siamo o meno online e l'elenco degli eventuali canali recuperando questi dati dal file da questo file di output

$irc_status1 = {
            'channels' => {
                '#telug' => 'La chat del Teramo Linux Users Group.....',
                '#geeks' => 'Un canale pieno di buchi (geeks?!) ......',
                '#areanetworking' => ' Benvenuti su #areanetworking ! .',
                '#controguerra' => 'Gli abitanti di Controguerra, .....',
                '#webgui' => '',
                '#pescaralug' => 'PescaraLUG ....'
            },
            'online' => 1,
            'timestamp' => 'Sun Mar 27 15:01:06 2005'
};

prodotto dallo script irc_check.pl. Impareremo cosi a deserializzare una struttura salvata via Data::Dumper e altre funzionalità accessorie.

Per complicarci la vita poi, vedremo quali sono i requisiti minimi per convertire lo script di shell in uno script web-based che ci mostrerà i risultati su di un browser invece che su di una shell.

A partire da questo ultimo esempio che conterrà mischiato sia codice HTML che codice Perl vedremo di trasformare lo script utilizzando vari metodi ti templating di modo da permettere la separazione tra la parte di presentazione (HTML) e quella di logica (Perl). In particolare vedremo di costruirci un semplice motore di templating fatto in casa, useremo poi un sistema di templating già pronto e infine vedremo lo stesso script trasformato per funzionare in un framework di sviluppo "professionale".

Il primo amore non si scorda mai: la console.

Iniziamo quindi ad analizzare lo script che leggerà il file di output che contiene lo stato del nostro nick su IRC e che stamperà i risultati sulla console o, se si vuole essere precisi, sullo standard output.

Innanzitutto cerchiamo di capire cosa contiene la struttura dati contenuta nel file. La struttura presente nella variabile $irc_status1 è un hashref di tre chiavi

Questa struttura è stata serializzata dal modulo Data::Dumper e salvata nel file irc_status.txt.

Iniziamo quindi l'analisi dello script da shell che chiameremo irc_status.pl.

A parte le classiche righe di intestazione da 1 a 3 già descritte nel mio articolo precedente

1 #!/usr/bin/perl
2 use strict;
3

che, come ogni bravo script in Perl, definiscono il percorso al compilatore e l'attivazione della direttiva strict, e tralasciando la definizione di alcune variabili che poi verranno usate nel prosieguo del programma

 
4 my $br = "\n";
5 my ($online_str,$elenco_canali_str) = ('','');
6

la parte più interessante di questo script è racchiusa all'interno di questa chiamata

7 my $irc_status = &load_data;

alla funzione &load_data che ha il compito di ottenere dal file irc_status.txt una variabile Perl contenente l'hashref che rappresenta il nostro stato su IRC e che vogliamo stampare a video.

Per capire come si esegue questa operazione va chiarito cosa contiene il file irc_status.txt ossia che risultato produce il metodo Data::Dumper::Dumper.

Data::Dumper è uno strumento fantastico in quanto riesce a ricreare il codice Perl che può rigenerare la struttura dati sulla quale il metodo Dumper viene applicato. Se si apre quindi il file irc_status.txt quello che si trova dentro il codice Perl che definiva la variabile $irc_status ossa il codice necessario a definire un hashref come descritto in precedenza.

Come di può allora recuperare e utilizzare tale variabile in un nuovo programma? Grazie alla funzione eval che prende una stringa contenente del codice Perl e la esegue all'interno dello stesso contesto del programma. L'unica attenzione da porre è relativa al fatto che, trovandoci all'interno della direttiva "strict" è necessario predichiarare la variabile $irc_status1 altrimenti non sarebbe possibile usarla successivamente in quanto il parser a runtime si accorgerebbe della variabile non inizializzata e produrrebbe un errore di runtime. Per evitare di inizializzare la variabile sarebbe necessario usare la funzione eval in tutte le chiamate a questa variabile nel prosieguo del programma. Ma dato che questo risulterebbe molto scomodo la variabile viene inizializzata alla linea 24.

 

23 sub load_data {
24     my $irc_status1;

viene quindi eseguito il codice che apre il file e che, recuperando la stringa all'interno del file


25     undef local $/;
26     open(IRC,'irc_status.txt')
27         or die "Impossibile aprire irc_status.txt: " . $!;
28     my $script = <IRC>;
29     close(IRC);

lo esegue come se fosse una parte del programma

30     eval $script;

ritornando poi la struttura recuperata alla variabile in riga 7


31     return $irc_status1;
32 }

Il risultato di questa metodo è identico a se si fosse scritto esplicitamente il contenuto del file irc_status.txt all'interno del programma.

Il programma prosegue con il recupero esplicito della variabile booleana online,

8 my $sono_online = $irc_status->{online};
9

la definizione di una stringa che stampi un risultato "umano" dello stato del mio utente su IRC

 
10 unless ($sono_online) {
11     $online_str = "In questo momento non sono collegato su IRC$br";
12 } else {
13     $online_str = "In questo momento sono collegato su IRC sui canali$br";

e, se sono online, il recupero della lista dei canali sotto formata di hashdef


14     my $elenco_canali = $irc_status->{channels};

e un ciclo sulle chiavi ($k) e sui valori ($v) dell'hashref e la definizione di una stringa che formatti questo elenco.


15     while (my ($k,$v) = each %$elenco_canali) {
16         $elenco_canali_str .= sprintf "%-20s: %s$br",$k,$v;
17     }
18 }
19

Il programma si chiude con la stampa a video delle due stringhe


20 print $online_str;
21 print $elenco_canali_str;

che producono, con il file irc_status.txt definito sopra, il seguente risultato:

root@K7# perl irc_status.pl
In questo momento sono collegato su IRC sui canali
#telug              : La chat del Teramo Linux Users Group.....
#geeks              : Un canale pieno di buchi (geeks?!) ......
#controguerra       : Gli abitanti di Controguerra, .....
#areanetworking     : Benvenuti su #areanetworking ! .
#webgui             :
#pescaralug         : PescaraLUG ....