Newsgroup: it.comp.lang.perl
Titolo: un banale problema per una cgi.

Saslve.
Ho un semplicissimo script con due subroutine.
In una viene costruita una form e nell'altra vengono eseguite delle
operazioni in base ai dati inseriti nel form.
my $query = new CGI;
print $query->header,
      $query->start_html("Cambio password");
print "<div style='margin:0 auto;width:500px;text-align:center;'>";
print $query->img({src=>'/images/logo.gif'});
print $query->h2('Cambio password');
&print_form($query);
print "</div>";
print $query->end_html;
viene chiamata la subroutine print_form che stampa una form su una pagina
web, vengono riempiti i campi e alla pressione del tasto submit vorrei
richiamare la subroutine change_pass che e' definita nello stesso script e
che si incarica di elaborare i dati inseriti.
Ho provato a mettere nella action $myself/change_pass, dove
myself=$query->self_url, ma non funziona.
Come devo fare? 

 Come devo fare? 
Non è così che funziona, e lo studio di un manuale di programmazione CGI 
aiuterebbe ;-)
Scusa, davvero non voglio essere né spocchioso né provocatorio, ma la 
tua domanda solleva una tale quantità di questioni (passaggio di 
parametri, PATH_INFO (REST), query string, sicurezza, dispatching, 
statefulness, framework etc.) che ci vorrebbero 200 pagine per 
approfondirli tutti (certo, poi dipende dalla lunghezza delle pagine ;-)
Per farla breve, sporca e rozza, il browser deve passare al tuo script 
cgi un parametro il cui valore indica la subroutine da eseguire.
Per passare tale parametro (che supporremo di chiamare "sub") puoi 
valorizzare l'action della tua form con:
	url_tuo_script?sub=change_pass
oppure valorizzare un campo hidden della form (e ci sono ancora altri 
metodi, migliori).
Poi nel tuo script leggi il valore di tale parametro, in questo modo:
	my $action = $query->param('sub');
ed infine esegui la subroutine appropriata:
	change_pass() if $action eq 'change_pass';
Ma, ripeto, questo è soltanto un modo rozzo e sbrigativo (peraltro non 
testato, caveat emptor!) per darti un'idea di come si fa, che non tiene 
conto di una serie di importanti ulteriori questioni, prima tra tutte la 
sicurezza.
Dai un'occhiata ad un manuale di programmazione CGI in Perl (ce ne sono 
una quantità sul web) e considera di adottare un framework per le tue 
applicazioni CGI, tipo ad esempio CGI::Application:
http://search.cpan.org/~markstos/CGI-Application-4.03/
Ciao,
Emanuele.


S.
-- 
Stefano Rodighiero      |  
http://larsen.perlmonk.org/blog
mailto:
lar...@perl.it
   |  Italian Perl Mongers: 
http://www.perl.it

 change_pass() if $action eq 'change_pass';
Infatti ho fatto una cosa del genere:
my $query = new CGI;
if($query->param('change_pass')) {
  &change_pass($query);
}
else{
  &print_page;
}
sub print_page {
  print $query->header,
        $query->start_html("Cambio password");
  &print_form;
  print $query->end_html;
}
sub print_form {
  print $query->start_form();
  print "<p>userid:";
  print $query->textfield({-style=>'position:absolute;right:0px;'},
                           -name=>'user',
                           -size=>30,
                           -maxlength=>30);
....e altri campi....
  print $query->hidden(-name=>'change_pass',
                       -value=>'1');
  print $query->submit(-name=>'button_name',
                       -value=>'cambia'),
        $query->reset(-value=>'annulla');
  print $query->endform;
}
sub change_pass {
  my ($query) = @_ ;
  warn $query->param;
  my($user, $cur, $new1, $new2) = (
                                $query->param('user'),
                                $query->param('cur'),
                                $query->param('new1'),
                                $query->param('new2')
                                );
  $user =~ s@^\s+|\s+$@@g;
Il problema e' che non funziona nel senso che mi dice che le variabili
$user, $cur, ecc. risultano non inizializzate.

                            -maxlength=>30);
perché il metodo textfield non accetta un hash anonimo mixato con altri 
parametri.
La corretta invocazione del metodo è pertanto così (che è anche più 
semplice):
print $query->textfield(
	-style     => 'position:absolute;right:0px;',
	-name      => 'user',
	-size      => 30,
	-maxlength => 30
);
Non ti confondere con altri metodi di generazione dell'HTML di CGI quali 
span() e h*() che invece richiedono il passaggio di -style in un hash 
anonimo (difatti, se guardi bene, questi metodi utilizzano il passaggio 
di parametri posizionale e non "per nome", come invece fa textfield() ).
Per vedere se l'errore è proprio questo basta controllare l'HTML (della 
form) generato dal tuo script, verificando che i campi input della form 
abbiano l'attributo "name" correttamente valorizzato (con la tua 
chiamata c'è il rischio che i parametri vengano letti male, pertanto i 
nomi dei campi non vengano valorizzati e quindi alla fine 
$query->param() non li trovi).
Un'altra verifica consiste nel controllare l'output di warn() nei log 
del tuo web server... Visto che l'hai utilizzato ;-)
(Devi verificare che vengano stampati i nomi di *tutti* i campi.)
Ciao,
Emanuele.

 parametri.
L'errore infatti sta proprio, grazie mille.
Scusa la mia ignoranza ma cosa intendi per hash anonimo?

 Scusa la mia ignoranza ma cosa intendi per hash anonimo?
L'hash anonimo è quello che hai passato tu al metodo textfield come 
primo argomento: in sostanza è la struttura tra parentesi graffe (le 
parentesi graffe vanno considerate come un operatore che restituisce un 
riferimento (reference) all'hash anonimo).
Per altre informazioni al riguardo consulta il tutorial sui riferimenti:
http://perldoc.perl.org/perlreftut.html
e il prontuario sulle strutture di dati:
http://perldoc.perl.org/perldsc.html
Oppure le traduzioni in italiano dei suddetti documenti:
http://pod2it.sourceforge.net/pods/perlreftut.html
http://pod2it.sourceforge.net/pods/perldsc.html
fornite meritoriamente dal gruppo pod2it:
http://pod2it.sourceforge.net/pods/responsibles.html
Ciao,
Emanuele.