Newsgroup: it.comp.lang.perl
Titolo: hash con dimensione massima?

Ragazzi, questo script mi sta tirando scemo.
Ma gli hash di hash hanno una dimensione massima??
Allora, riporto come al solito lo spezzone di codice sotto accusa.
Ormai ho spezzato il codice e praticamente rimane solo questo.
Se io faccio
my ($file) = $ARGV[0];
	open(FILE,"<$file") || die ("$^E: $file");
	while (<FILE>)
	{ 
if ( $_ =~ m/new\smsg\s(\d+)/ )	{ print "DEBUG
$1\n";	$messaggi{$1}{new_id}=$1; $messaggi{$1}{new_time}=time();}
}
Le righe che matchano quella regex sono 1349. In output ho esattamente
1349 righe "DEBUG" con il relativo valore, segno che il matching e č
posto, ma quando vado a esplorare l'hash con:
foreach $chiave (keys %messaggi) {print "new id:
$messaggi{$chiave}{new_id}\n"; }
ottengo solo 599 valori!
Ci sto impazzendo. Dove sbaglio?
Scusate se il codice si legge male, ma dal form di newsland non si riesce
a fare molto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 1349 righe "DEBUG" con il relativo valore, 
PS: ovviamente non ho valori duplicati...


Ci sto impazzendo. Dove sbaglio?
A me questo funziona, ed è "praticamente" uguale al tuo codice, sicché non
sbagli nulla, il tuo script funziona... e noi tutti viviamo nel migliore
dei mondi possibili.
    my ($file) = $ARGV[0];
    open FILE, '>' . $file || die ("$^E: $file");
    for my $num (1 .. 1349) {
        print FILE 'new msg ', $num, "\n";
    }
    close FILE;
    open (FILE,"<$file") || die ("$^E: $file");
    print STDERR $file, "\n";
    while (<FILE>) {
        if ( $_ =~ m/new\smsg\s(\d+)/ ) {
            print STDERR "DEBUG $1\n";
            $messaggi{$1}{new_id}=$1; $messaggi{$1}{new_time}=time();
        }
    }
    foreach $chiave (keys %messaggi) {
        print "new id: $messaggi{$chiave}{new_id}\n";
    }
Ciao.

 non ci si capirà mai nulla.
Eccolo:
#!/usr/bin/perl
sub reader
{
	my ($file) = $ARGV[0];
	open(FILE,"<$file") || die ("$^E: $file");
	while (<FILE>)
	{
		if ( $_ =~ m/new\smsg\s(\d+)/ )	{ print "CHIAVE
$1\n";	$messaggi{$1}{new_id}=$1; print "id: $messaggi{$1}{new_id}\n" }
	}
	close(FILE);
}
use strict;
our %messaggi = ();
my $chiave;
&reader;
foreach $chiave (keys %messaggi) { print "new id:
$messaggi{$chiave}{new_id}\n";}
# fine


 # fine
Come diceva Giovanni, il tuo codice sembra semanticamente corretto 
(benché contenga diverse imperfezioni stilistiche, che mi permetto di 
segnalarti perché lo rendono piuttosto fragile).
E se non avessi memoria a sufficienza per allocare gli elementi 
dell'hash, comunque otterresti un errore di "OUT OF MEMORY" (peraltro 
non trappabile).
Quindi, a meno di sviste, rimane soltanto l'ipotesi delle chiavi duplicate.
Per escluderla (o confermarla), inserisci questa riga come prima 
istruzione all'interno del corpo dell'if (per essere più chiari, nel 
punto che ho indicato con (*) nel tuo codice):
print "CHIAVE DUPLICATA: $1\n" if exists $messaggi{$1};
Se non è neanche questo, prova ad isolare una porzione (possibilmente 
piccola) del tuo file che sia in grado di generare l'incongruenza tra il 
numero di righe matchate e il numero di elementi dell'hash, e postala 
qui (ma probabilmente a quel punto avrai capito da solo di cosa si 
tratta ;-)
Ciao,
Emanuele.

 print "CHIAVE DUPLICATA: $1n" if exists $messaggi{$1};
Se avessi un muro vicino alla scrivania, lo avrei già tirato giù a testate.
La lista CONTENEVA duplicati, solo che non me ne ero accorto perché avevo
cannato la sintassi di uniq...
Forse dovrei aumentare un po' la dimensione dei font.. :P
Vabbeh, grazie 1000, almeno adesso so perché avevo metà delle entry negli
hash!
