Sie sehen häufig die Überprüfung auf Definiertheit, damit Sie sich nicht mit der Warnung für die Verwendung eines undef-Werts befassen müssen (und in Perl 5.10 wird die fehlerhafte Variable angezeigt):
Use of uninitialized value $name in ...
Um diese Warnung zu umgehen, kommen die Leute auf alle Arten von Code, und dieser Code scheint eher ein wichtiger Teil der Lösung zu sein als der Kaugummi und das Klebeband, die er ist. Manchmal ist es besser zu zeigen, was Sie tun, indem Sie die Warnung, die Sie vermeiden möchten, explizit deaktivieren:
{
no warnings 'uninitialized';
if( length $name ) {
...
}
}
In anderen Fällen verwenden Sie anstelle der Daten einen Nullwert. Mit dem definierten oder Operator von Perl 5.10 können Sie length
anstelle der Variablen, die die Warnung auslöst , eine explizite leere Zeichenfolge (definiert und Länge von Null) zurückgeben:
use 5.010;
if( length( $name // '' ) ) {
...
}
In Perl 5.12 ist dies etwas einfacher, da length
bei einem undefinierten Wert auch undefiniert zurückgegeben wird . Das mag ein bisschen albern erscheinen, aber das freut den Mathematiker, den ich vielleicht sein wollte. Das gibt keine Warnung aus, weshalb diese Frage existiert.
use 5.012;
use warnings;
my $name;
if( length $name ) { # no warning
...
}
length undef
undef zurückgegeben, anstatt zu warnen und 0 zurückzugeben. Im booleschen Kontext ist undef genauso falsch wie 0. Wenn Sie also auf Version 5.12 oder höher abzielen, können Sie einfach schreibenif (length $name) { ... }
Wie mobrule angibt, können Sie stattdessen Folgendes für eine kleine Ersparnis verwenden:
Sie könnten den definierten Scheck fallen lassen und etwas noch kürzeres bekommen, z.
Aber in dem Fall, in dem
$name
nicht definiert ist, obwohl der Logikfluss genau wie beabsichtigt funktioniertwarnings
, erhalten Sie die folgende Ermahnung , wenn Sie verwenden (und Sie sollten es sein):Wenn es also eine Chance gibt, die
$name
möglicherweise nicht definiert ist, müssen Sie in erster Linie die Definiertheit überprüfen, um diese Warnung zu vermeiden. Wie Sinan Ünür hervorhebt, können Sie Scalar :: MoreUtils verwenden , um Code, der genau das tut (prüft auf Definiertheit, prüft dann auf Nulllänge) , sofort über die folgendeempty()
Methode abzurufen :quelle
Erstens, da
length
immer eine nicht negative Zahl zurückgegeben wird,und
sind gleichwertig.
Wenn Sie einen undefinierten Wert durch eine leere Zeichenfolge ersetzen können, können Sie den
//=
Operator von Perl 5.10 verwenden , der die RHS der LHS zuweist, sofern die LHS nicht definiert ist:Beachten Sie das Fehlen von Warnungen zu einer nicht initialisierten Variablen, da
$name
die leere Zeichenfolge zugewiesen wird, wenn sie nicht definiert ist.Wenn Sie jedoch nicht von der Installation von 5.10 abhängig sein möchten, verwenden Sie die von Scalar :: MoreUtils bereitgestellten Funktionen . Zum Beispiel kann das Obige wie folgt geschrieben werden:
Wenn Sie nicht überfallen möchten
$name
, verwenden Siedefault
.quelle
length( $name // '' )
.//
und//=
Operatoren sind möglicherweise die nützlichsten spezialisierten Operatoren, die es gibt.length
jetzt etwas zurückgegeben werden, das keine Zahl ist (aber nicht NaN;)In Fällen, in denen es mir egal ist, ob die Variable
undef
gleich oder gleich ist, fasse''
ich sie normalerweise wie folgt zusammen:quelle
$name //= "";
was genau das ist, was Sinan gepostet hat.$name ||= "";
undef
und befasst""
, einfach einen zum anderen wechseln und einen einzigen Test verwenden sollte. Dies funktioniert im allgemeinen Fall nicht, für den die anderen veröffentlichten Lösungen viel besser sind, führt aber in diesem speziellen Fall zu ordentlichem Code. Sollte ich meine Antwort umformulieren, um dies klarer zu machen?Du könntest sagen
anstatt
quelle
Es ist nicht immer möglich, sich wiederholende Dinge auf einfache und elegante Weise zu tun.
Tun Sie einfach das, was Sie immer tun, wenn Sie gemeinsamen Code haben, der in vielen Projekten repliziert wird:
Suchen Sie nach CPAN, möglicherweise hat jemand bereits den Code für Sie. Für diese Ausgabe habe ich Scalar :: MoreUtils gefunden .
Wenn Sie in CPAN nichts finden, was Ihnen gefällt, erstellen Sie ein Modul und fügen Sie den Code in eine Unterroutine ein:
Dann nennen Sie es in Ihrem Code:
Wenn Sie Prototypen ablehnen und keine Einwände gegen die zusätzlichen Parens erheben, überspringen Sie den Prototyp im Modul und nennen Sie ihn wie folgt :
is_nonempty($name)
.quelle
Scalar::MoreUtils
.&
Siegels beim Aufrufen von Funktionen. Daher verlasse ich mich nicht auf Prototypen, um die ganze Arbeit zu erledigen. Ich nehme an, ich könnte der Fehlermeldung "hinzufügen und die Verwendung von & sigil bei Unteraufrufen beenden, es sei denn, Sie meinen es wirklich so".Die ausgezeichnete Bibliothek Type :: Tiny bietet ein Framework, mit dem Sie die Typprüfung in Ihren Perl-Code integrieren können. Was ich hier zeige, ist nur die dünnste Spitze des Eisbergs und verwendet Type :: Tiny auf einfachste und manuellste Weise.
Weitere Informationen finden Sie im Type :: Tiny :: Manual .
quelle
Wie wäre es mit
Dies entspricht nicht ganz Ihrer Originalversion, da es auch false zurückgibt, wenn
$name
der numerische Wert 0 oder die Zeichenfolge ist'0'
, sich aber in allen anderen Fällen gleich verhält.In Perl 5.10 (oder höher) wäre der geeignete Ansatz, stattdessen den definierten Operator oder Operator zu verwenden:
Dies entscheidet darüber, wie lang es sein soll, basierend darauf, ob
$name
es definiert ist und nicht, ob es wahr ist. 0 /'0'
behandelt diese Fälle also korrekt, erfordert jedoch eine neuere Version von Perl, als viele Leute zur Verfügung haben.quelle
quelle