En Perl, comment puis-je concise de vérifier si une variable $est définie et contient une chaîne de longueur zéro?
J'utilise actuellement le Perl suivante pour vérifier si une variable est définie et contient du texte. Je dois vérifier defined
d'abord pour éviter une "valeur non initialisée" avertissement:
if (defined $name && length $name > 0) {
# do something with $name
}
Est-il mieux (sans doute plus concis) méthode pour écrire cela?
Vous devez vous connecter pour publier un commentaire.
Vous voyez souvent le vérifier definedness de sorte que vous n'avez pas à traiter avec l'avertissement pour l'utilisation d'une valeur undef (et en Perl 5.10, il vous indique la délinquance de la variable):
Donc, pour se autour de cet avertissement, les gens viennent avec toutes sortes de code, et que le code commence à ressembler à une partie importante de la solution plutôt que du bubble-gum et du ruban adhésif qu'il est. Parfois, il est préférable de montrer ce que vous faites explicitement à la désactivation de l'avertissement que vous essayez d'éviter:
Dans d'autres cas, utiliser une sorte de valeur null à la place des données. Avec Perl 5.10 définies ou opérateur, vous pouvez donner
length
explicite d'une chaîne vide (définis, et de donner en retour de longueur zéro) au lieu de la variable qui va déclencher l'alerte:En Perl 5.12, c'est un peu plus facile parce que
length
sur une valeur non définie également retourne undefined. Cela peut sembler un peu de la bêtise, mais ce qui plaît le mathématicien que je l'aurais voulu être. Qui n'a pas d'émettre un avertissement, qui est la raison de cette question existe.length undef
retourne undef, au lieu de l'alerte et de retour 0. Dans boolean contexte, le fnud est tout aussi faux que de 0, donc si vous êtes ciblage v5.12 ou version ultérieure, vous pouvez simplement écrireif (length $name) { ... }
Comme mobrule l'indique, vous pouvez utiliser les éléments suivants à la place pour une petite épargne:
Vous pourriez fossé de la définition de vérifier et d'obtenir quelque chose d'encore plus court, par ex.:
Mais dans le cas où
$name
n'est pas défini, alors que la logique de flux de travail comme prévu, si vous utilisezwarnings
(et vous devriez), vous obtiendrez alors le suivant avertissement:Donc, si il ya une chance que
$name
peut pas être défini, vous avez vraiment besoin de vérifier pour definedness d'abord et avant tout, afin d'éviter que d'avertissement. Comme Sinan Ünür points, vous pouvez utiliser Scalar::MoreUtils pour obtenir le code qui fait exactement cela (vérifie definedness, puis vérifie la longueur zéro) hors de la boîte, via leempty()
méthode:Tout d'abord, depuis
length
retourne toujours un nombre non négatif,et
sont équivalentes.
Si vous êtes OK avec le remplacement d'une valeur indéfinie avec une chaîne vide, vous pouvez utiliser Perl 5.10 de l'
//=
opérateur qui affecte le membre de droite à GAUCHE, à moins que le membre de GAUCHE est définie:Note l'absence de mises en garde sur une variable non initialisée comme
$name
est affecté à la chaîne vide si elle n'est pas définie.Toutefois, si vous ne voulez pas dépendre de l'5.10 être installé, utilisez les fonctions fournies par Scalar::MoreUtils. Par exemple, le ci-dessus peut être écrite comme:
Si vous ne voulez pas pour les fringues
$name
, utilisezdefault
.length( $name // '' )
.//
et//=
opérateurs sont peut-être le plus utile opérateurs spécialisés dans l'existence.length
pouvez maintenant retourner quelque chose qui n'est pas un nombre (mais pas NaN 😉Dans le cas où je ne me soucie pas de savoir si la variable est
undef
ou égale à''
, j'ai l'habitude de le résumer ainsi:$name //= "";
qui est exactement ce que Sinan posté.$name ||= "";
undef
et""
, elle devrait juste changer de l'un à l'autre et à l'utilisation d'un seul test. Cela ne fonctionnera pas dans le cas général, pour lesquelles les autres solutions sont affichées de manière mieux, mais dans ce cas précis conduit à neat code. Dois-je reformuler ma réponse à faire de ce plus clair?On pourrait dire
au lieu de
Il n'est pas toujours possible de faire des choses répétitives dans une façon simple et élégante.
Il suffit de faire ce que vous faites toujours quand vous avez le bon code qui obtient répliqués dans de nombreux projets:
De recherche CPAN, quelqu'un en a déjà le code pour vous. Pour cette question j'ai trouvé Scalar::MoreUtils.
Si vous ne trouvez pas quelque chose que vous aimez sur le CPAN, faire un module et de mettre le code dans un sous-programme:
Puis dans votre code appeler:
Ou si vous vous opposez à des prototypes et ne s'opposent pas à l'extra parens, passez le prototype dans le module, et de l'appeler comme:
is_nonempty($name)
.Scalar::MoreUtils
.is_nonempty
à($)
Perl avertira au moment de la compilation lorsque la fonction est appelée avec le mauvais nombre d'arguments. Vous ne devriez pas en avoir besoin lors de l'exécution.&
sigil lors de l'appel de fonctions. J'ai donc tendance à ne pas compter sur des prototypes de faire tout le travail. Je suppose que je pourrais ajouter "et de cesser d'utiliser le & sigil sur sous les appels, sauf si vous dire vraiment" à la message d'erreur.is_empty
vérifie tous sur la place, c'est une grande victoire pour simplifier vos chèques ET de les garder cohérente en même temps.L'excellente bibliothèque Type::Minuscule fournit un cadre qui permet de construire la vérification de type dans votre code Perl. Ce que je montre ici est seulement la plus fine pointe de l'iceberg et est de Type::Minuscule dans la plus simpliste, et de façon manuelle.
Être sûr de vérifier le Type::Minuscule::Manuelle pour plus d'informations.
Comment sur
Ce n'est pas tout à fait équivalent à votre version d'origine, car elle retourne false si
$name
est la valeur numérique de 0 ou de la chaîne'0'
, mais se comporte de la même dans tous les autres cas.En perl 5.10 (ou plus tard), la meilleure approche serait d'utiliser la défini-ou l'exploitant de la place:
Ce sera décider ce que pour obtenir la longueur de base que
$name
est défini, plutôt que de savoir si c'est vrai, donc 0/'0'
permettra de traiter les dossiers correctement, mais il nécessite une version plus récente de perl que beaucoup de gens ont à disposition.