2013-02-09 16 views
12

Sto pianificando di passare due variabili a una funzione perl, una delle quali può essere facoltativa. Sto cercando di verificare se il secondo è definito o meno, ma non funziona correttamente. Quando ho chiamato la funzione myFunction (18), si presuppone che la variabile $ opzionale sia definita e vada alla dichiarazione else. Ma nella dichiarazione else quando si accede alla variabile $ opzionale, viene generato un errore "non inizializzato". Questo è esattamente l'opposto di quello che mi aspettavo. Qualsiasi aiuto è molto apprezzato.Uso di defined/undef in Perl

sub myFunction { 
    my ($length, $optional) = (@_); 
    if(undef($optional) 
    { 
    more code.. 
    } 
    else 
    { 
    more code... 
    } 
} 

myFunction(18) 
+4

Se stai cercando di scoprire quanti vengono passati, quindi prendi il conteggio degli argomenti: 'scalare (@_)'. Se chiami 'foo (4, undef)', hai passato 2 arg. –

+0

Questo perché il test per un valore non definito è ['non definito'] (http://perldoc.perl.org/functions/defined.html), non [' undef'] (http://perldoc.perl.org /functions/undef.html). – hd1

risposta

21

La funzione corretta è defined. undef undefines $optional. Che cosa si vuole fare è qualcosa di simile:

sub myFunction { 
    my($length, $optional) = @_; 
    if(! defined $optional) { 
     # Do whatever needs to be done if $optional isn't defined. 
    } 
    else { 
     # Do whatever can be done if $optional *is* defined. 
    } 
} 

Un altro modo per affrontare il problema (in particolare Perl 5.10+) è quello di utilizzare il "definito o" operatore, //, in questo modo:

sub MyFunc { 
    my $length = shift; 
    my $optional = shift // 'Default Value'; 
    # Do your stuff here. 
} 

In questo modo viene rilevato se è stato definito il valore di ritorno di shift @_. Dal momento che hai già chiamato shift una volta, stiamo testando il secondo parametro. Se è definito, assegnare il valore a $optional. Se non è definito, assegnare 'Default Value' a $optional. Naturalmente devi venire con il tuo predefinito sano di mente.

Se sei bloccato in tempi bui di pre-Perl 5.10, si potrebbe ottenere lo stesso con:

my $optional = shift; 
$optional = defined $optional ? $optional : 'Default value'; 

... o ...

my $length = shift; 
my $optional = defined($_[0]) ? shift : 'Default value'; 

In entrambi i casi, Spesso preferisco avere un predefinito corretto, piuttosto che un percorso del flusso di controllo completamente separato. Spesso è un buon modo per semplificare il codice.

+1

'$ SCALAR = undef;' solo non definisce. 'undef (VAR)' fa molto di più, anche per gli scalari. (Libera vari bit di memoria.) – ikegami

+0

@ikegami È corretto, ma perché complicare le cose? Mi sono attenuto al comportamento documentato in 'perldoc -f undef'. Forse la parola "solo" è il problema. Lo rimuoverò. – DavidO

+0

cos'è 'shift'? –

0
my $optional = defined($_[0]) ? shift : 'Default value'; 

Questo è un codice pericoloso in quanto sposta solo fuori il parametro se definita, se si ha un terzo parametro questo sarebbe ottenere confuso quando si chiama

MyFunc(10, undef, 20)