Newsgroup: it.comp.lang.perl
Titolo: Riconoscere tipo di dati

Ho questa funzione:
----------
sub scrivi_dati_su_file {
	my ($NOME_FILE, @PARAMETRI)=@_;
	my (%presente_fadf, $i, $j, $k, $TEMP1, $key, $value, @VALORI,
$VARIABILE, @FUNZIONI, @FUNZIONI_BETA, $PAR, $PAR2, @ALTRO);
	local (*SCRIVI, $VALORE_DA_SCRIVERE, @VALORE_DA_SCRIVERE,
%VALORE_DA_SCRIVERE);
	open (SCRIVI, ">$NOME_FILE") || die "Error. Cannot write into
file \"$NOME_FILE\"";
	binmode (SCRIVI);
	if (!(-e "/
command.com
")) {flock (SCRIVI, 2);}
	for ($i=0; $i<=$#PARAMETRI; $i++) {
		eval ('$TEMP1=\''.$PARAMETRI[$i].'\';');
		if ($TEMP1=~/^\$/) {
			($TEMP1, @ALTRO)=split(/\|/, $TEMP1);
			$TEMP1=~s/^\$//g;
			eval ('$VALORE_DA_SCRIVERE=$'.$TEMP1.';');
			if ($VALORE_DA_SCRIVERE ne "") {
				$VALORE_DA_SCRIVERE=~s/\r//g;
				@VALORI=split(/\n/,
$VALORE_DA_SCRIVERE);
				for ($k=0; $k<=$#VALORI; $k++) {
					print SCRIVI
$TEMP1.'ŁŁŁ'.$VALORI[$k]."\n";
				}
			}
		}
		elsif ($TEMP1=~/^\@/) {
			($TEMP1, @ALTRO)=split(/\|/, $TEMP1);
			$TEMP1=~s/^\@//g;
			eval ('@VALORE_DA_SCRIVERE=@'.$TEMP1.';');
			for ($j=0; $j<=$#VALORE_DA_SCRIVERE; $j++) {
				if ($VALORE_DA_SCRIVERE[$j] ne "") {
$VALORE_DA_SCRIVERE[$j]=~s/\r//g;
					@VALORI=split(/\n/,
$VALORE_DA_SCRIVERE[$j]);
					for ($k=0; $k<=$#VALORI; $k++)
{
						print SCRIVI
$TEMP1.'['.$j.']ŁŁŁ'.$VALORI[$k]."\n";
					}
				}
			}
		}
		elsif ($TEMP1=~/^\%/) {
			($TEMP1, @ALTRO)=split(/\|/, $TEMP1);
			$TEMP1=~s/^\%//g;
			eval ('%VALORE_DA_SCRIVERE=%'.$TEMP1.';');
			while ( ($key, $value) = each
%VALORE_DA_SCRIVERE) {
				if ($value ne "") {
					$value=~s/\r//g;
					@VALORI=split(/\n/, $value);
					for ($k=0; $k<=$#VALORI; $k++)
{
						print SCRIVI
$TEMP1.'{"'.$key.'"}ŁŁŁ'.$VALORI[$k]."\n";
					}
				}
			}
		}
		else {
			die "Error in \"scrivi_dati_su_file\"
function, data type not known in $TEMP1";
		}
	}
	close (SCRIVI);
	if ((stat($NOME_FILE))[7] == 0) {unlink $NOME_FILE;}
}
-----------
che viene richiamata da una linea del tipo
scrivi_dati_su_file ("pippo.txt", '@ASTERICS');
e scrive sul file pippo.txt delle righe del tipo
ASTERICS[0]ŁŁŁpluto
ASTERICS[1]ŁŁŁpluto34
[...]
La funzione compie il suo dovere per variabili semplici, array
semplici, e hash semplici ma non ho la piů pallida idea di come
implementarla per permetterle di gestire anche tipi di dati complessi
come array di array o array di hash. il semplice riconoscimento del
primo carattere non mi permette di andare oltre la prima macroscopica
distinzione nelle tre famiglie.
In pratica ho necessitŕ di riconoscere automaticamente il tipo di
variabile, quindi di navigarci dentro e per ognuno dei suoi valori
avere il nome della variabile e il valore corrispondente per poter
scrivere cose del tipo
$pippo{Lycos}[4]ŁŁŁpluto
Qualche consiglio?
Grazie
Ciao
Andrea Busia
No Spam, Grazie.







 Qualche consiglio?
Mi sbaglio io o stai cercando di serializzare i dati per poterli rileggere
in futuro? Perche' non usare Data::Dumper per un lavoro del genere?
Maurizio
-- 
Maurizio M. Munafo' / 
mmmu...@netscape.net
"Consider Phlebas, who was once handsome and tall as you" (T.S.Eliot)

Ho questa funzione:
----------
sub scrivi_dati_su_file {



	close (SCRIVI);


e scrive sul file pippo.txt delle righe del tipo
ASTERICS[0]ŁŁŁpluto
ASTERICS[1]ŁŁŁpluto34
[...]
La funzione compie il suo dovere per variabili semplici, array
semplici, e hash semplici ma non ho la piů pallida idea di come
implementarla per permetterle di gestire anche tipi di dati complessi
come array di array o array di hash. il semplice riconoscimento del
primo carattere non mi permette di andare oltre la prima macroscopica
distinzione nelle tre famiglie.
In pratica ho necessitŕ di riconoscere automaticamente il tipo di
variabile, quindi di navigarci dentro e per ognuno dei suoi valori
avere il nome della variabile e il valore corrispondente per poter
scrivere cose del tipo


Scusate per il post multiplo ma con i problemi di tiscali degli ultimi
giorni non ricevevo la conferma dell'invio del messaggio e non
vedendolo nel'elenco credevo non venisse postato, solo adesso mi sono
accorto del post multiplo
Ancora scusa


in futuro? Perche' non usare Data::Dumper per un lavoro del genere?
Perchč questi dati devono essere letti anche da applicazioni in PHP e
non potrei leggere array e hash se non dopo lunghe e complicate
modifiche. mi serve proprio avere in output la coppia
NOME VARIABILE -> VALORE
Ma non riuscendo a identificare i tipi di dati complessi (array di
array o hash di array o simili) non posso neanche bypassare il
problema rendendo ricorsiva la funzione di cui nel messaggio
precedente.


 precedente.
uhmmm... sono abbastanza sicuro che sul Cookbook ci sia qualcosa in
proposito, ma in questo momento ho il libro a casa.
Pero' tu puoi riconoscere tipi di dati complessi, senza neanche fare troppi
casini, usando 'ref'.
Senza neanche giocare troppo con i prefissi, basta che parti con la
reference al tuo dato originario e poi vai giu' in profondita'.
Ricordo infatti che 'ref EXPR' torna una stringa indicare se EXPR e' una
reference e di che tipo (REF, SCALAR,ARRAY,HASH,CODE,GLOB).
Non ho sotto mano il tuo codice originale per farti un esempio...
Saluti,


reference al tuo dato originario e poi vai giu' in profondita'.
Ho seguito il tuo consiglio e ho riscritto il codice in questa maniera:
------------------------
$pippo[0][0]=5;
$pippo[1][0]=1;
$pippo[1][1]=3;
$pippo[0][1]=6;
scrivi_dati_su_file_2(\@PIPPO, '@PIPPO');
sub scrivi_dati_su_file_2 {
 my ($REF, $NOME_VARIABILE)=@_;
 my ($STR, $REF2, $j, $k, $INDICE_MAX, @VALORI);
 local ($VALORE_DA_SCRIVERE, @VALORE_DA_SCRIVERE, %VALORE_DA_SCRIVERE);
 $NOME_VARIABILE=~s/^(\$|\@|\%)//;
 if (ref($REF) eq "SCALAR") {
  $VALORE_DA_SCRIVERE=$$REF;
  if ($VALORE_DA_SCRIVERE ne "") {
   $VALORE_DA_SCRIVERE=~s/\r//g;
   @VALORI=split(/\n/, $VALORE_DA_SCRIVERE);
   for ($k=0; $k<=$#VALORI; $k++) {
    $TESTO_DA_SCRIVERE_fjdjfd.=$NOME_VARIABILE.'ŁŁŁ'.$VALORI[$k]."\n";
   }
  }
 }
 elsif (ref($REF) eq "ARRAY") {
  @VALORE_DA_SCRIVERE=@$REF;
  $INDICE_MAX=$#VALORE_DA_SCRIVERE;
  foreach my ($j=0; $j<=$INDICE_MAX; $j++) {
   print $REF->[$j]."\t".\$$REF->[$j]."\n";
#   $REF2=\${$REF->[$j]};
#   $REF2 = \$$REF[$j];
   scrivi_dati_su_file_2($REF2, '@{$'.$NOME_VARIABILE.'}['.$j.']',
@PARAMETRI_FUNZIONE);
  }
 }
 elsif (ref($REF) eq "HASH") {
  %VALORE_DA_SCRIVERE=%$REF;
  while ( ($key, $value) = each %VALORE_DA_SCRIVERE) {
#   $REF2=\$value;
#   $REF2 = \$$REF[$j];
   scrivi_dati_su_file_2($REF2, '%{$'.$NOME_VARIABILE.'}['.$j.']',
@PARAMETRI_FUNZIONE);
  }
 }
 else {
  die "Error in \"scrivi_dati_su_file\" function, data type not known in
$NOME_VARIABILE";
 }
}
------------------------
Ho un problema nel riconoscere nel fare un reference a una variabile
referenziata. se provo con
$REF2=\$REF->[$j];
ref($REF2) mi restituisce "REF";
ho provato a racchiudere l'istruzione con parentesi graffe ma senza
successo.
nel caso deglia rray non posso neanche usare una forma del tipo
\$VALORE_DA_SCRIVERE[$j]
perchč, ovviamente, non so se devo usare \$VALORE_DA_SCRIVERE[$j],
\@{$VALORE_DA_SCRIVERE[$j]}, \%{$VALORE_DA_SCRIVERE[$j]}.
Qualche idea?
Grazie
Andrea Busia
-- 
Posted from 
puppis.tiscalinet.it
 [195.130.224.119] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 Qualche idea?
Quindi. Se fai $REF2= $REF->[$j] ottieni gia' il reference all'oggetto (ad
esempio array riga) o lo scalare.
Quindi a seconda che $REF2 sia un reference o meno, poi chiamare
ricorsivamente la tua funzione.
Quando arrivi in fondo, $REF2 non e' un reference, quindi puoi stampare
direttamente il valore o farne il reference scalare e chiamare la tua
funzione ricorsiva...
Nel blocco ARRAY, puoi mettere 
   $REF3=$REF->[$j];
   $REF2 = ref($REF3) ? $REF3 : \$REF3;
   scrivi_dati_su_file_2($REF2, '@{$'.$NOME_VARIABILE.'}['.$j.']',
                         @PARAMETRI_FUNZIONE);
e piu' o meno sembra funzionare.
Non ho provato con hash e altra roba, ma direi che non dovrebbero esserci
problemi :)


Non ho sotto mano il tuo codice originale per farti un esempio...
Grazie, ora provo
