157 votes

PowerShell supporte-t-il les constantes ?

Je voudrais déclarer des constantes entières dans PowerShell.

Y a-t-il un bon moyen de le faire ?

165voto

Motti Strom Points 920

Utilisez

Set-Variable test -Option Constant -Value 100

ou

Set-Variable test -Option ReadOnly -Value 100

La différence entre "Constant" et "ReadOnly" est qu'une variable en lecture seule peut être supprimée (et ensuite recréée) via

Remove-Variable test -Force

alors qu'une variable constante ne peut pas être supprimée (même avec -Force).

Voir cet article de TechNet pour plus de détails.

4 votes

Hmm, mais comment forcer le type de données lors de l'utilisation de Set-Variable ? Lorsqu'on traite des variables, on peut utiliser [string]$name = value mais cela ne semble pas être possible pour les constantes ?

9 votes

@masi juste forcer la valeur Set-Variable test -option Constant -value [string]100

9 votes

@Monso Vous avez besoin de parenthèses autour de la valeur lorsque vous spécifiez le type, par exemple ([string]100) . Voir les réponses ci-dessous.

22voto

rob Points 3029

Voici une solution pour définir une constante comme celle-ci :

const myConst = 42

Solution tirée de http://poshcode.org/4063

    function Set-Constant {
  <#
    .SYNOPSIS
        Creates constants.
    .DESCRIPTION
        This function can help you to create constants so easy as it possible.
        It works as keyword 'const' as such as in C#.
    .EXAMPLE
        PS C:\> Set-Constant a = 10
        PS C:\> $a += 13

        There is a integer constant declaration, so the second line return
        error.
    .EXAMPLE
        PS C:\> const str = "this is a constant string"

        You also can use word 'const' for constant declaration. There is a
        string constant named '$str' in this example.
    .LINK
        Set-Variable
        About_Functions_Advanced_Parameters
  #>
  [CmdletBinding()]
  param(
    [Parameter(Mandatory=$true, Position=0)]
    [string][ValidateNotNullOrEmpty()]$Name,

    [Parameter(Mandatory=$true, Position=1)]
    [char][ValidateSet("=")]$Link,

    [Parameter(Mandatory=$true, Position=2)]
    [object][ValidateNotNullOrEmpty()]$Mean,

    [Parameter(Mandatory=$false)]
    [string]$Surround = "script"
  )

  Set-Variable -n $name -val $mean -opt Constant -s $surround
}

Set-Alias const Set-Constant

2 votes

Malheureusement, cela ne fonctionne pas lorsque Set-Constant est contenu dans un module. Elle créera une constante dans la portée du module, où Set-Constant est contenu. Comme solution de contournement, on pourrait passer le paramètre -Surround Global mais ce n'est pas toujours souhaité. Je voudrais créer une constante dans un autre module ou localement dans une fonction.

16voto

Mike Shepard Points 5109

Pour utiliser un type de valeur spécifique, par exemple Int64, vous pouvez explicitement convertir la valeur utilisée dans set-variable.

Par exemple :

set-variable -name test -value ([int64]100) -option Constant

Pour vérifier,

$test | gm

Et vous verrez que c'est un Int64 (plutôt qu'un Int32, ce qui serait normal pour la valeur 100).

0 votes

Cela pourrait être raccourci : set -o const test ([int64]100) . C'est l'un des rares cas où je préfère l'alias au nom complet de la commande dans un script, pour laisser mon esprit "scanner" le code source plus rapidement.

1 votes

Je ne suis pas d'accord. set -o est un peu trop cryptique pour que je puisse l'avoir dans un script.

15voto

zett42 Points 6849

J'aime vraiment le sucre syntaxique qui Réponse de Rob fournit :

const myConst = 42

Malheureusement, sa solution ne fonctionne pas comme prévu lorsque l'on définit l'attribut Set-Constant dans un module . Lorsqu'il est appelé depuis l'extérieur du module, il crée une constante dans la portée du module, où Set-Constant est définie, au lieu de la portée de l'appelant . Cela rend la constante invisible pour l'appelant.

La fonction modifiée suivante corrige ce problème. La solution est basée sur cette réponse à la question "Y a-t-il un moyen pour un module powershell d'accéder à la portée de son appelant ?" .

function Set-Constant {
    <#
    .SYNOPSIS
        Creates constants.
    .DESCRIPTION
        This function can help you to create constants so easy as it possible.
        It works as keyword 'const' as such as in C#.
    .EXAMPLE
        PS C:\> Set-Constant a = 10
        PS C:\> $a += 13

        There is a integer constant declaration, so the second line return
        error.
    .EXAMPLE
        PS C:\> const str = "this is a constant string"

        You also can use word 'const' for constant declaration. There is a
        string constant named '$str' in this example.
    .LINK
        Set-Variable
        About_Functions_Advanced_Parameters
    #>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, Position=0)] [string] $Name,
        [Parameter(Mandatory=$true, Position=1)] [char] [ValidateSet("=")] $Link,
        [Parameter(Mandatory=$true, Position=2)] [object] $Value
    )

    $var = New-Object System.Management.Automation.PSVariable -ArgumentList @(
        $Name, $Value, [System.Management.Automation.ScopedItemOptions]::Constant
    )

    $PSCmdlet.SessionState.PSVariable.Set( $var )
}

Set-Alias const Set-Constant

Notes :

  • La fonction uniquement fonctionne, lorsqu'il est appelé à partir de à l'extérieur de le module, où il est défini. C'est le cas d'utilisation prévu, mais j'aimerais ajouter une vérification, pour savoir si elle est appelée à partir du même module (dans ce cas, l'option Set-Variable -scope 1 devrait fonctionner), lorsque j'aurai trouvé comment le faire.
  • J'ai renommé le paramètre -Mean à -Value par souci de cohérence avec Set-Variable .
  • La fonction pourrait être étendue pour définir de manière facultative le Private , ReadOnly et AllScope drapeaux. Il suffit d'ajouter les valeurs souhaitées au 3ème argument de la fonction PSVariable Constructeur qui est appelé dans le script ci-dessus par l'intermédiaire de New-Object .

2 votes

Vous pouvez vérifier la pile d'appels pour savoir où l'affectation a eu lieu : if ((Get-PSCallStack)[1].Command -eq 'your-module-file-name.psm1') { <# inside module #> } else { <# outside #> }

13voto

Paolo Tedesco Points 22442

Utilisez -option Constant avec le Set-Variable cmdlet :

Set-Variable myvar -option Constant -value 100

Maintenant $myvar a une valeur constante de 100 et ne peut être modifiée.

3 votes

Wow, c'est encombrant. Tu dois utiliser Set-Variable pour le faire, hein ?

1 votes

Oui, il n'y a pas de façon simple de le faire :)

1 votes

Vous pouvez également modifier une variable existante avec set-variable (alias sv) ou en utilisant get-variable (gv) et en jouant avec sa propriété Options.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X