[Roma.pm] senza vergogna
Flavio Poletti
flavio at polettix.it
Tue Jan 8 14:35:25 PST 2008
(mi scuso per la sciatteria di questa risposta, ma non mi è venuto in
mente niente di più semplice).
Una lista è una cosa differente da un array. Nel caso specifico, puoi
pensare ad un array come ad una lista dotata di una maniglia: se vuoi
prenderla e trasportarla da qualche parte, basta usare la maniglia.
Qual è la maniglia? Sostanzialmente è data dal fatto che a questa lista di
elementi assegni uno spazio ben determinato, che puoi indicare con un nome
o un riferimento. Infatti, puoi creare un array in due modi: o utilizzando
una variabile che comincia con "@":
@array = 1 .. 10;
oppure utilizzando un costruttore anonimo, che restituisce un riferimento
all'array stesso:
$rif_ad_array = [ 1 .. 10 ];
Sempre parlando di riferimenti, puoi prendere un riferimento ad "@array"
con il backslash, tipo:
$rif_ad_altro_array = \@array;
Come vedi, abbiamo modo di "dare un nome" a qualcosa che poi possiamo
portarci appresso ed utilizzare, sia questo il nome dell'array (come
"array" in "@array") o di un riferimento ad esso (come "$rif_ad_array").
Senza la "maniglia" non hai modo di poter dire "sto parlando di questo,
questo e quest'altro elemento": puoi solo far "scivolare" gli elementi
come una sequenza indistinta. Ci sono casi, come la chiamata a funzione,
in cui un array viene "appiattito" in una lista, e da quel punto non ti
rimane altro, tipo in:
funz(@array1, @array2);
sub funz {
my @elementi_in_ingresso = @_;
}
Qui, in fase di chiamata di "funz()" sia "@array1" che "@array2" vengono
appiattiti e viene creata *una* lista unica, che poi viene passata a
"funz()" stessa. In teoria, sarebbe possibile evitare questo appiattimento
degli array utilizzando i prototipi, ma ci porta un po' fuori obiettivo e
puoi eventualmente approfondirlo da solo sulla documentazione. La cosa
importante, però, è capire che se i prototipi possono evitare
l'appiattimento degli array, se tu *già parti* da una lista non hai modo
di farci niente: rimarrà sempre e solo una lista.
In particolare, quindi, se hai due funzioni che restituiscono liste:
sub funz1 { return 1 .. 10; }
sub funz2 { return 20 .. 30; }
metterle come sotto-chiamate ti produrrà solo una lista più lunga:
funz(funz1(), funz2()); # crea una sola, lunga lista
Se hai bisogno di maniglie, devi passare per gli array. Questo però non ti
obbliga a doverle "nominare", basta che tu aggiunga le maniglie, ad
esempio con il costruttore anonimo di array che abbiamo visto sopra:
funz([funz1()], [funz2()]);
In questo modo, la lista restituita da "funz1()" viene "catturata" e messa
in un array (anonimo), un riferimento al quale viene passato come primo
parametro a "funz()". Stessa cosa per "funz2()". Quindi, nella sub ti
ritrovi:
sub funz {
my ($rif1, $rif2) = @_;
# qui usi @$rif1 e @$rif2 come da documentazione...
}
Un'alternativa potrebbe essere quella di restituire riferimenti ad array
invece di liste, tipo:
sub funz1 { return [ 1 .. 10 ]; } # uso il costruttore anonimo
sub funz2 {
my @risultato = 20 .. 30;
return \@risultato;
}
funz(funz1(), funz2()); # già ho dei riferimenti ad array
La scelta sta a te.
Infine, va detto che la sintassi stessa di Perl dà adito, a mio modo di
vedere, a confusione a riguardo. Ad esempio, la funzione "wantarray"
dovrebbe essere chiamata, più logicamente, "wantlist", visto che si può
restituire una lista ma non un array:
sub ultimafunz {
my @array = qw( ciao a tutti );
return @array;
}
Quest'ultima funzione, ad esempio, restituisce la lista derivante
dall'appiattimento di @array, ma sempre di lista si tratta.
Spero di non aver detto troppe corbellerie, ma per quelle c'è emazep :)
Ciao,
Flavio.
PS la mail non l'ho riletta, non sparate sul pianista :)
> come dicevo a stefano vorrei essere libero di chiamare la sub usando
> liste o risultati (sempre liste) di altre sub.
>
> non ce' modo di separare le liste senza "nominarle" ?
>
> comuqnue piu'tardi do una scorsa all'indirizzo sui riferimenti.
>
> thx
>
>
>
>> Ciao,
> usa i riferimenti =>> perldoc perlref
>> Praticamente alla funzione gli passi i riferimenti agli array.
>> Successivamente dentro la funzione recuperi il contenuto delle strutture
>> dati passate
>> dereferenziando il riferimento stesso:
>
>> sub non_mischia {
>> #recuperi i riferimenti passati nella chiamata
>> my ($ref_list1, $ref_list2) = @_;
>> #dereferenzi e crei un array come quello passato
>> my @list1 = @$ref_list1;
>> #idem con patate
>> my @list2 = @$ref_list2;
>> }
>
>> #chiami la funzione passando i riferimenti e non gli array
>> non_mischia(\@list1, \@list2);
>
>> Il concetto e' questo, per capire la sintassi e le sfumature, leggiti il
>> manuale.
>
>> Saluti
>
>
>
> --
> Best regards,
> kanak mailto:kanak at perl.it
>
> _______________________________________________
> Roma mailing list
> Roma at pm.org
> http://mail.pm.org/mailman/listinfo/roma
>
More information about the Roma
mailing list