2010-11-21 29 views
2

Je suis récemment tombé sur une ligne intéressante de code qui attend jusqu'à ce qu'un des ressorts de fichiers particuliers à la vie:Y at-il des pièges à tester pour l'existence de fichiers dans un certain temps conditionnel?

sleep 1 until -e $file; 

Pendant son séjour à la valeur nominale de la ligne fait ce que l'on s'y attend, je ne peux pas, mais aider à se sentir que quelque chose n'est pas juste ici; il semble plus naturel juste pour écrire:

while (1) { 

    sleep 1; 
    last if -e $file; 
} 

sont les opérateurs de test de fichiers destinés à être utilisés uniquement avec if et unless? Et y a-t-il des pénalités de performance dans le déploiement de ces opérateurs dans les conditions while?

+1

Performance ??? La seule pénalité ici est le ping du système de fichiers, qui est par pénalité plus grande que n'importe quelle boucle ... – Drakosha

+0

@Drakosha: Combien de temps vous attendez-vous d'un fichier ping typique à prendre? Un sommeil d'une seconde n'est-il pas suffisant pour combattre le décalage? – Zaid

+0

oui, semble assez de temps sur tout système de fichiers/stockage normal. Je n'ai tout simplement pas compris pourquoi vous vérifiez les performances de la boucle, ce qui est négligeable ici. – Drakosha

Répondre

3

Il n'y a pas de différence entre l'utilisation d'un opérateur de test de fichiers en temps-réel (while) vs un tout-fausse boucle (until), ou en séparant le test avec un if/unless, ni est là une différence avec rien d'autre en Perl.

Le seul cas magique avec la boucle while est ... while <$handle>; ou while (<$handle>) {...} qui définit $_ à la ligne suivante tant qu'il est défini. Et cela n'a pas vraiment de sens d'utiliser la boucle while-false (until) avec des poignées nues.

La construction a until b est simplement a while not b.

Pour convertir sleep 1 until -e $file; en boucle while, utilisez les éléments suivants:

sleep 1 while not -e $file; 

Cela peut ensuite être étendue à la forme de bloc:

while (not -e $file) {sleep 1} 

Ou comme un while infini avec fuite interne :

while (1) { 
    last if -e $file; 
    sleep 1; 
} 

Et toutes ces formes sont équivalentes. En réponse au reste de votre question, la plupart des systèmes de fichiers devraient être bien avec 1 seconde dort entre les vérifications, mais vous pouvez choisir un nombre plus grand si le processus n'attend pas d'urgence sur le fichier. De même, si vous utilisez un périphérique avec un système de fichiers lent (stocké dans la mémoire flash ou via un réseau lent), vous pouvez également essayer des valeurs plus grandes.

Et comme ysth nitpicks ci-dessous, en général, les formulaires de déclaration de retour différemment que les formes de bloc quand ils sont le dernier élément d'une construction qui retourne: do {...}, sub {...}, do FILE, eval ...

+0

@Eric: J'étais plus intéressé par la comparaison en utilisant des tests de fichiers dans les conditions 'while' que dans les conditions 'if'. L'équivalence 'until' /' while 'n'est pas le problème ici. – Zaid

+0

@Zaid => c'est le même problème, le test de fichier, comme toute autre opération dans un contexte booléen n'a pas de comportement magique dans un conditionnel dans une boucle ('if') vs une boucle conditionnelle (' while') –

+0

@Zaid: de votre "semble plus naturel", il semble qu'il utilise le modificateur de déclaration jusqu'à ce que tout ce qui vous dérange. – ysth

2

Votre manière plus naturelle semble dormir au démarrage même si le fichier existe.

while(not -e $file) { sleep 1; } 

me semble mieux, ce qui est exactement synonyme de sleep 1 until -e $file; mais plus compréhensible à mon avis.

+0

Pas un synonyme exact; on retournera faux, un vrai. – ysth