POD2-IT

 view release on metacpan or  search on metacpan

IT/perlsub.pod  view on Meta::CPAN

      my ($k, $href, %vista); # locali
      foreach $href (@_) {
         while ( $k = each %$href ) {
         	$vista{$k}++;
         }
      }
      return grep { $vista{$_} == @_ } keys %vista;
   }

Fino ad ora, stiamo solo utilizzando il normale meccanismo di restituzione
di una lista. Che succede se volete passare o restituire una hash? Bene,
se ne state utilizzando solamente una, o non vi interessa se si concatenano,
allora la convenzione di chiamata usuale va bene, per quanto sia un po'
costosetta computazionalmente.

Dove molta gente si inguaia E<egrave> qui:

    (@a, @b) = funzione(@c, @d);
o
    (%a, %b) = funzione(%c, %d);

Questa sintassi, molto semplicemente, non funziona. Quel che fa E<egrave>
impostare solamente C<@a> o C<%a>, e svuotare C<@b> o C<%b>. In piE<ugrave>,
la funzione non ha ricevuto due array, o hash, separati: solo una
lunga lista in C<@_>, come al solito.

Se riuscite a fare in modo che chiunque riesca a capirci qualcosa con
i riferimenti, il codice E<egrave> piE<ugrave> pulito, per quanto non
cosE<igrave> semplice da leggere. Ecco un esempio di funzione che prende due
riferimenti ad array come argomenti, restituendo gli elementi dei due array
nell'ordine di quanti ciascuno ne ha in sE<eacute>:

   ($aref, $bref) = funzione(\@c, \@d);
   print "@$aref ha piu` elementi di @$bref\n";
   sub funzione {
      my ($cref, $dref) = @_;
      if (@$cref > @$dref) {
         return ($cref, $dref);
      } else {
         return ($dref, $cref);
      }
   }

A conti fatti, potete anche fare cosE<igrave>:

   (*a, *b) = funzione(\@c, \@d);
   print "@$aref ha piu` elementi di @$bref\n";
   sub funzione {
      local (*c, *d) = @_;
      if (@c > @d) {
         return (\@c, \@d);
      } else {
         return (\@d, \@c);
      }
   }

Qui stiamo utilizzando i I<typeglob> per ottenere alias nella tabella
dei simboli. C'E<egrave> da dire che E<egrave> un po' sottile, perE<ograve>, e
che non funziona se utilizzate variabili dichiarate con C<my>, perchE<eacute>
solo le variabili globali si trovano nella tabella dei simboli (anche se sono
in incognito grazie a C<local>).

Se state passando dei I<filehandle>, potete utilizzare, di solito, anche
il puro e semplice typeglob, come C<*STDOUT>, ma funziona anche con
riferimenti a typeglob. Ad esempio:

   balbetta(\*STDOUT);
   sub balbetta {
      my $fh = shift;
      print $fh "her umh beh a hmmm\n";
   }

   $rec = ottieni_rec(\*STDIN);
   sub ottieni_rec {
      my $fh = shift;
      return scalar <$fh>;
   }

Se avete in mente di generare nuovi filehandle... potete farlo. Fate
attenzione a restituire solamente il filehandle C<*FH> cosE<igrave> 
com'E<egrave>, non un suo riferimento.

   sub aprilo {
      my $path = shift;
      local *FH;
      return open (FH, $path) ? *FH : undef;
   }

=head2 Prototipi
X<prototipi> X<subroutine, prototipo>

Perl supporta una forma piuttosto limitata di verifica degli argomenti
durante la compilazione, mediante l'utilizzo di prototipi di funzione. Se
dichiarate:

    sub mia_push (\@@)

allora C<mia_push()> accetta gli argomenti esattamente come C<push()>.
La dichiarazione della funzione deve essere visibile al momento della
compilazione. Il prototipo ha effetto solo sull'interpretazione delle
chiamate a funzione nuovo stile, dove "nuovo stile" si riferisce alla
chiamata a funzione senza utilizzare il carattere C<&>. In altre parole,
se chiamate questa funzione come se fosse parte integrante del
linguaggio, essa si comporterE<agrave> come tale. Se la chiamate come una
subroutine vecchio stile, allora si comporterE<agrave> al vecchio modo.
Da questa regola, naturalmente, discende che i prototipi sono
ignorati quando ci sono riferimenti a subroutine come C<\&pippo> o su
chiamate indirette a subroutine come C<&{$subref}> o C<< $ubref->() >>.

Anche le chiamate ai metodi [ossia, alle funzioni associate agli
oggetti, N.d.T.] non sono influenzate dai prototipi, perchE<eacute>
la funzione da chiamare non puE<ograve> essere stabilita a tempo di
compilazione, dal momento che questa dipende dal particolare
albero di ereditarietE<agrave>.

Visto che lo scopo di questa caratteristica E<egrave> sostanzialmente quella
di consentirvi di definire subroutine che funzionano come se fossero
delle funzioni native del linguaggio, ecco i prototipi di alcune
funzioni che corrispondono quasi esattamente alle relative
funzioni native:



( run in 0.684 second using v1.01-cache-2.11-cpan-e93a5daba3e )