Newsgroup: it.comp.lang.perl
Titolo: bug del perl?

Salve a tutti!
E' la prima volta che scrivo su questo NG!!!!
Programmo da alcuni anni in perl....... ma questa
volta mi ritrovo davanti ad un caso molto strano:
ho fatto un script che mi mette in minuscolo i nomi di tutti i file in una
directory. Il mio problema e' che quando chiamo la funzione tolower che ho
scritto io non riesce ad elencarmi tutti i file. Invece se non la chiamo,
li visualizza tutti....... Guardate attentamente il codice.......
Io penso sia un bug del Perl5, voi che ne dite???
sub tolower {
    $str = shift(@_);
    $ris = "";
 
    @str = split("", $str);
 
    $i=0;
 
    while ($i < @str) {
 
        if ($str[$i] =~ /^[A-Z]$/) {
        $ris.=chr(ord($str[$i])+32);
        } else {
        $ris.=$str[$i];    
        }
 
        $i++;
    }
 
 
    return $ris;
}
opendir dir, ".";
@files = readdir(dir);
$i=0;
while ($i < @files) { 
    $file = $files[$i]; 
    print "i = $i\n";
 
    if ($file eq "." or $file eq "..") { 
        print "Salto perche' c'e' il punto.\n"; 
        $i++; next; 
    }
    print "Analizzo il file: '$file' \n";
#################################
#    print "Il tolower di $file e': ", tolower($file), "\n"; 
####Riga che da errore
#Ho provato questo script sotto piattaforma Linux RedHat 9.0.
#Se scommentate la riga sopra vedete che non vi elenca tutti i file della
#cartella, anzi, solo il primo. 
#
 
    $i++;
}
closedir dir;
Grazie per l'aiuto.
-- 
Vladislav Valtchev

 Io penso sia un bug del Perl5, voi che ne dite???
Penso di no.
Non ho analizzato approfonditamente il codice, ma io andrei
a vedere cosa succede di preciso alla variabile $i. Essendo
una variabile globale, la $i che modifichi in tolower() e`
_la_stessa_ che viene usata nel main. Ed essendo il contatore
di un ciclo i risultati sono imprevedibili. Ti consiglio di
cominciare ad usare strict e di imparare la differenza tra
lexical e global variable. Un documento molto utile secondo
me e` "Coping with Scoping" di M-J. Dominus:
 
http://perl.plover.com/FAQs/Namespaces.html
Sto lavorando ad una traduzione di questo documento: si puo`
dire ormai in fase beta, e credo di rilasciarla nei prossimi
giorni (mandero` comunque un avviso anche nel newsgroup, ad
ogni modo).
ciao,
Stefano

 _la_stessa_ che viene usata nel main. Ed essendo il contatore
e meno male che programma in perl da anni...

Guru03 wrote:

Si, infatti, ma non intendevo dire che da anni ci programmo tutti i giorni.
Da anni che lo conosco e lo uso per fare degli script....
Essendo che io sono abituato con il C/C++, Python, Php ecc.. non credevo
proprio che il perl usava la variabile globale $i. Il python nello stesso
caso non lo averebbe sicuramente fatto. Cmq vi ringrazio tanto per avermi
dato una dritta!!!
-- 
Vladislav Valtchev

caso non lo averebbe sicuramente fatto.
Quale sarebbe "lo stesso caso"?
Perl usa la variabile globale $i, perché tu gli hai detto di usare la
variabile $i, che tu gli hai detto che è globale.
Nello "stesso caso", voglio sperare che ognuno dei linguaggi che tu hai
citato (e tutti quelli che non hai citato) si comporti nel medesimo modo.
Poi ogni linguaggio ha il proprio modo per dichiarare visibilità e durata
delle variabili, ma non è che si può usare un linguaggio come se fosse un
altro e poi dire che è "lo stesso caso".
Il punto è questo:
  ...
  opendir dir, ".";
  @files = readdir(dir);
  $i=0;
  ...
Qui crei una variabile globale $i. E nella sub:
 sub tolower {
    $str = shift(@_);
    $ris = "";
 
    @str = split("", $str);
 
    $i=0;
    ....
utilizzi delle variabili, $i compresa, che si suppongono globali, dal
momento che non le hai dichiarate come locali.
 
Bastava modificare il ciclo della sub:
    while ($i < @str) {
 
        if ($str[$i] =~ /^[A-Z]$/) {
        $ris.=chr(ord($str[$i])+32);
        } else {
        $ris.=$str[$i];    
        }
 
        $i++;
    }
in:
    for my $stringa (@str) {       
        if ($stringa =~ /^[A-Z]$/) {
           $ris .= chr(ord($stringa) + 32);
        } else {
           $ris .= $stringa;    
        }        
    }
(A parte che non è chiaro perché non utilizzi la funzione lc o, se devi
fare una sostituzione particolare, un'opprortuna espressione di
translazione y///.)
In questo modo la variabile $stringa è dichiarata locale, e stai tranquillo
che perl non ti sporcherà nessun'altra variabile $stringa al di fuori di
quel ciclo for, e nessuno (neppure una funzione chiamata all'interno del
ciclo) sporcherà la variabile $stringa del ciclo.
Un'occhiata a perlsub chiarisce queste e altre cose.
Ciao.

 citato (e tutti quelli che non hai citato) si comporti nel medesimo modo.
Quindi, come vedi, vari linguaggi si comportano in modo differente e prima
di affermare che gli altri linguaggi si comporterebbero nello stesso modo,
informati su di essi, fra i quali alcuni piu' standard e piu' utilizzati
del Perl.
-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-
-`-`-`-` Cmq grazie per la lezione di Perl.       :-)))  -`-`-`-`-`
-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-`-

-- 
Vladislav Valtchev

 int i=0; //la inizializzo a 0
[CUT]
Scusa ma tu qui dichiari 2 volte la variabile i: una volta all'esterno
della funzione e una volta all'interno di prova. 
Se avessi fatto lo stesso in perl, usando my, non avresti avuto
problemi. E cmq my non è un attributo *particolare*. Quindi quello che
ha detto il sig. Giovanni Zezza mi sembra giusto.
Ciao,
-- 
+--------+ ASCII ribbon campaign ( )
|  kral  |  - against HTML email  X 
+--------+              & vCards / \

del Perl.
Non ti preoccupare che so benissimo quello che affermo, e non ho affermato
nulla di cui non abbia conoscenza. E' proprio perché conosco i linguaggi
che hai citato che posso dire che il comportamento è il medesimo, nelle
medesime situazioni. Le "medesime situazioni", ovviamente, sono "le
medesime situazioni", non "quelle che, per assonanza sintattica con altri
linguaggi, suppongo siano le medesime".
Ciao.

per definire che voglio usare la variabile globale.
"Gli altri linguaggi" che tu conosci (e trascurando sempre la questione
dell'"attributo"). Clipper usa la stessa convenzione di Perl, e cosě Awk, e
molte implementazione di Basic, e, alla fine, decine di "altri linguaggi".
E questo dimostra solo che stai facendo una generalizzazione indebita, e
(come capita, ahimč, almeno una volta al giorno ad ognuno di noi) tendi a
difenderla teoricamente come se fosse un'operazione corretta. Come chi,
avendo assaggiato solo gelati alla vaniglia, ne derivi che quello che sta
mangiando non puň essere un gelato, perché č al cioccolato.
Si puň discutere sulle scelte sintattiche di Perl, ma, nel frattempo, se si
vuole usarlo, č meglio cercare di impararlo sulla base della documentazione
propria, e non delle supposte analogie che dovrebbe avere con altri
linguaggi.
Ciao.

 Ciao.
-- 
Vladislav Valtchev

puo' confondere fra le sintassi di vari linguaggi.
Non mi sono offeso, e non ti critico perché dici che ci si può confondere
fra le sintassi dei vari linguaggi. Certo che ci si può confondere. Questo
è legittimo. Quello che non è legittimo è teorizzare l'uso sistematico
della confusione come strumento operativo.
E quello che ti ho detto, non per "criticarti" gratuitamente, ma per
avvisarti di un rischio, è che nella tua frase ho, a torto o a ragione,
avvertito un vago sentore di quest'ultimo atteggiamento. Se non è vero,
tanto meglio per te. In ogni caso, non ci sono gli estremi né da parte mia
per sentirmi offeso, né da parte di tua per risentirti per un richiamo che
vuol essere sostanzialmente amichevole e che, per di più, neppure ritieni
pertinente.
Ciao.