Résolu Fonction avec valeur de retour bizarre

Plus d'informations
il y a 11 mois 1 semaine #34011 par J-L Prout
    Bonjour,

    Je suis assez intrigué par le comportement d'une fonction dans un script PowerShell. 

Fichier attaché :

Nom du fichier : Fonction_r...rone.ps1
Taille du ficher :4 ko
 

Fichier attaché :

Nom du fichier : Fonction_r...rone.ps1
Taille du ficher :4 ko
 

Fichier attaché :

Nom du fichier : Fonction_r...rone.ps1
Taille du ficher :4 ko
.

    Quand, dans le corps de la fonction, il y a une commande avec pipeline et que, plus loin, on a un "return" de la fonction
le programme principal reçoit, en valeur de retour de la fonction, la valeur de retour choisie, précédée de la sortie standard de
la commande réceptrice du pipeline. Est-ce bien de la sorte que doit se comporter une fonction?

    Je vous joins un exemple simple des opérations avec une fonction où on ne fait que rentrer afficher puis sortir.

    J'ai utilisé "Get-Member" juste pour créer un pipeline. La ligne qui le contient n'a, autrement, aucun sens.

    Merci pour vos essais et votre réponse.
Pièces jointes :

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 mois 6 jours - il y a 11 mois 6 jours #34012 par Fabien
Bonjour,

Effectivement le comportement est étrange.
En powershell, "return" dans une fonction retourne toutes les sorties.
Cela ne s'applique pas uniquement au pipeline.
Une simple commande "Get-ChildItem" suffit à perturber le retour.

Le seul moyen de contourner ce problème est de ne pas afficher de retour sur cette commande en ajoutant "| Out-null" après "Get-member".
Dernière édition: il y a 11 mois 6 jours par Fabien.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 mois 6 jours #34013 par J-L Prout
Merci pour le conseil. Dans mon script de travail, j'ai purement et simplement supprimé la ligne qui, de toute façon était sans intérêt. Je viens de réessayer en ajoutant " | Out-Null" dans mon script d'essai. Le programme principal retrouve bien la valeur de retour attendue.
Pour être juste, j'ai galéré plusieurs jours avant de trouver la cause de ce retour bizarre dans le programme principal. Je suis même allé jusqu'à faire un script avec le programme principal qui demande à la fonction de renvoyer tous les types possibles et il marche très bien. C'est par hasard, avec l'outil de débogage, que j'ai rapproché la valeur reçue avec une sortie standard de "Get-Member".

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 mois 6 jours #34016 par J-L Prout
Il reste, tout de même, le cas où on écrirait une fonction dans laquelle on ait réellement besoin d'un pipe-line et de sa sortie. Comment faire et comment concilier cela avec un "return"?
Si j'ai bien observé, il semblerait que "return value" envoie "value" dans le pipe-line. Est-ce normal?
J'aimerais bien avoir quelques explications et retours d'expérience sur le sujet. Merci.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 mois 5 jours #34019 par Fabien
Dans ce cas précis, je te conseille d'utiliser la portée des variables et non "return".
Dans la fonction, il faut déclarer la variable comme ceci : 
$Script:Val_Retour_Fc
La variable va donc avoir une portée Script, et elle peut être visible dans tout le script.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 mois 4 jours - il y a 11 mois 4 jours #34038 par Arnaud Petitjean
Bonjour Jean-Louis,

Je suis ravi de vous voir de retour dans notre forum ! 

En fait, le fonctionnement que vous obtenez est le fonctionnement normal de PowerShell. Il n'y a donc pas de bug ici ;-).

Il faut savoir que le mot clé Return est un faux-ami en PowerShell. La plupart des scripteurs PowerShell pensent (à tort) qu'en l'utilisant, PowerShell ne va retourne QUE ce qu'on lui demande de retourner. Or ça ne fonctionne pas comme ça.
En effet, PowerShell étant un Shell et non un langage de programmation compilé, le fonctionnement est différent. PowerShell en réalité retourne absolument tout ! Toute variable, toute fonction ou toute commande produisant un retour est retourné dans le flux standard.

Le mot clé Return est donc totalement inutile dans votre contexte, et même contre productif car cela pourrait laisser penser que la fonction ne retourne que votre variable. Ce qui n'est pas le cas.

Il n'existe que 2 cas ou Return est utile :
  1. à l'intérieur d'une étendue (bloc de script, boucle ou fonction), pour en sortir précipitamment (voir cette rubrique d'aide  about_return ),
  2. à l'intérieur d'une classe (nouveauté PowerShell 5) pour retourner de la donnée à l'intérieur d'une méthode.

C'est ce qui explique pourquoi vous obtenez le retour de la commande Get-Member.

Pour donner un peu plus de contexte, prenons cette fonction : 

function Test {
    
    $a = 3
    $b = 5

    $a + $b

    return $a 

    $b
}

Si on l'exécute, nous obtenons :
PS > test
8
3


8 correspond au résultat de l'addition des variables a et b.
3 correspond à "Return $a"

Et nous pouvons remarquer que $b n'est jamais affichée car la fonction a été quittée après l'exécution de la commande Return !

De plus, dernier petit complément d'informations, les blocs Begin, Process, et End ne vous sont d'aucune utilité dans votre code et je vous suggère de les retirer. On utilise ces blocs uniquement lorsque nous avons un paramètre qui accepte en entrée les données du pipeline. Mais cela est un tout autre sujet ;-) !

En espérant que mes explications vous aient aidé.

Arnaud

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Dernière édition: il y a 11 mois 4 jours par Arnaud Petitjean.

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.208 secondes
Propulsé par Kunena