2013-02-09 8 views
12

Ich plane, zwei Variablen an eine Perl-Funktion übergeben, von denen eine optional sein kann. Ich versuche zu überprüfen, ob der zweite definiert ist oder nicht, aber es funktioniert nicht richtig. Wenn ich die Funktion als myFunction (18) aufgerufen habe, nimmt sie an, dass die Variable $ optional definiert ist und zur else -Anweisung geht. Aber in der else-Anweisung, wenn auf die $ optionale Variable zugegriffen wird, löst es einen "nicht initialisierten" Fehler aus. Das ist genau das Gegenteil von dem, was ich erwartet habe. Jede Hilfe wird sehr geschätzt.Verwendung von definierten/undef in Perl

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

myFunction(18) 
+4

rufen Wenn Sie viele, um herauszufinden, sind versucht, wie übergeben werden, dann nehmen Sie die Anzahl der Argumente: 'Skalar (@_)'. Wenn Sie 'foo (4, undef)' aufrufen, haben Sie 2 Argumente übergeben. –

+0

Das liegt daran, dass der Test für einen undefinierten Wert [nicht definiert] (http://perldoc.perl.org/functions/defined.html), nicht [undef] (http://perldoc.perl.org) ist /functions/undef.html). – hd1

Antwort

21

Die korrekte Funktion ist defined. undef undefines $optional. Was Sie tun möchten, ist so etwas wie dieses:

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. 
    } 
} 

Ein anderer Weg, damit umzugehen (insbesondere Perl 5.10+) ist die Verwendung der „definiert oder“ Operator, //, wie folgt aus:

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

In diesem Fall wird erkannt, ob der Rückgabewert shift @_ definiert ist. Da Sie schon einmal shift aufgerufen haben, testen wir jetzt den zweiten Parameter. Wenn es definiert ist, weisen Sie den Wert $optional zu. Wenn es nicht definiert ist, weisen Sie 'Default Value' dem $optional zu. Natürlich müssen Sie sich Ihre eigene Standardvorgabe einfallen lassen.

Wenn Sie in den dunklen Zeiten der Pre-Perl 5.10 stecken, könnte man das gleiche mit erreichen:

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

... oder ...

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

So oder so, Ich bevorzuge oft einen vernünftigen Standard und keinen völlig separaten Kontrollflussweg. Es ist oft ein guter Weg, um Code zu vereinfachen.

+1

'$ SCALAR = undef;' nur undefines. 'undef (VAR)' macht viel mehr, sogar für Skalare. (Es befreit verschiedene Speicherbits.) – ikegami

+0

@ikegami Das ist richtig, aber warum die Dinge komplizieren? Ich blieb bei dem Verhalten, das in 'perldoc -f undef 'dokumentiert ist. Vielleicht ist das Wort "nur" das Problem. Ich werde es entfernen. – DavidO

+0

Was ist 'shift'? –

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

Dies ist gefährlich, Code, wie es verschiebt sich aus nur die Parameter, wenn definiert ist, wenn Sie dies einen dritten Parameter hätte verworren, wenn Sie

MyFunc(10, undef, 20) 
Verwandte Themen