Ho usato Perl per un po ‘di tempo, ma oggi ho trovato questo codice:
sub function1($$) { //snip }
Cosa significa questo in Perl?
È una funzione con un prototipo che accetta due argomenti scalari.
Ci sono forti argomentazioni per non utilizzare in realtà i prototipi Perl in generale – come notato nei commenti seguenti. L’argomento più forte è probabilmente:
C’è una discussione su StackOverflow del 2008:
C’è una ansible sostituzione nel modulo MooseX :: Method :: Signatures .
Come menziona l’altra risposta, il $$
dichiara un prototipo. Ciò che l’altra risposta non dice è a cosa servono i prototipi. Non sono per la convalida dell’input, sono suggerimenti per il parser.
Immagina di avere due funzioni dichiarate come:
sub foo($) { ... } sub bar($$) { ... }
Ora quando scrivi qualcosa di ambiguo, come:
foo bar 1, 2
Perl sa dove mettere i paren; la barra richiede due arg, quindi consuma i due più vicini. pippo prende un arg, quindi prende il risultato della barra e i due argomenti:
foo(bar(1,2))
Un altro esempio:
bar foo 2, 3
Lo stesso vale; pippo prende un arg, quindi ottiene 2. la barra prende due args, quindi ottiene foo(2)
e 3:
bar(foo(2),3)
Questa è una parte piuttosto importante di Perl, quindi respingerlo come “non usare mai” ti sta rendendo un disservizio. Quasi tutte le funzioni interne utilizzano i prototipi, quindi comprendendo come funzionano nel proprio codice, è ansible ottenere una migliore comprensione di come vengono utilizzati dai builtin. Quindi puoi evitare parentesi non necessarie, il che rende il codice più gradevole.
Infine, un anti-pattern ti avvertirà contro:
package Class; sub new ($$) { bless $_[1] } sub method ($) { $_[0]->{whatever} }
Quando si chiama codice come metodo ( Class->method
o Class->method
$instance->method
), il controllo del prototipo è completamente privo di significato. Se il tuo codice può essere chiamato solo come metodo, aggiungere un prototipo è sbagliato. Ho visto alcuni moduli popolari che fanno questo (ciao, XML::Compile
), ma è sbagliato, quindi non farlo. Se vuoi documentare il numero di argomenti da passare, che ne dici di:
sub foo { my ($self, $a, $b) = @_; # $a and $b are the bars to fooify ....
o
use MooseX::Method::Signatures; method foo(Bar $a, Bar $b) { # fooify the bars ....
A differenza di foo($$)
, questi sono significativi e leggibili.