Las variables dentro de la función son locales a ese alcance a menos que salpique la invocación del nombre de la función. Cuando se salpican la fuente de un guión, las variables de proceso de nivel superior se importan de manera efectiva en el ámbito actual junto con la definición de funciones, por ejemplo:
PS> '$scriptvar = 2; function my-f { ${my-f-var} = 2 }' > my-f-script.ps1
PS> Remove-Variable scriptvar, my-f-var
Remove-Variable : Cannot find a variable with name 'scriptvar'.
Remove-Variable : Cannot find a variable with name 'my-f-var'.
PS> . .\my-f-script.ps1
PS> $scriptvar
2
PS> ${my-f-var}
PS>
Tenga en cuenta que $ {my-f-var} no está definido en el alcance local. Sin embargo, si i 'punto' la invocación de la función a continuación, su contenido se ejecutan en el ámbito actual por ejemplo:
PS> . my-f
PS> ${my-f-var}
2
En este caso, la variable establecida en la función se establece en el ámbito actual (invocando) porque del 'punto' utilizado para invocarlo.
Un par de puntos más: puede acceder a variables en varios ámbitos utilizando Get-Variable -scope
o los modificadores globales, de script, locales y privados más convenientes (aunque menos flexibles). Cuando accede a una variable dentro de una función donde la variable se define en un ámbito superior, puede leerla perfectamente. Pero cuando lo configura, PowerShell esencialmente realiza una "copia por escritura" de la variable, creando una nueva copia con un alcance desde esa función hacia abajo (es decir, a las otras funciones a las que llama). Si realmente desea modificar una variable de mayor alcance, puede usar $ global: Foo o $ script: Foo para modificar en esos ámbitos.
El osciloscopio local
es útil si quiere evitar inadvertidamente el uso de una variable definida fuera de su función. Otro MVP lo mencionó en la última cumbre de MVP y parece ser uno de esos consejos de "mejores prácticas". Este es el escenario:
PS> $foo = 'bad'
PS> function testscope { $fooo = 'good'; "The value of `$fooo is $foo" }
PS> testscope
The value of $fooo is bad
Tenga en cuenta que en este caso el uso de $foo
dentro de la función es un error tipográfico, pero casualmente hay una variable con ese nombre typo'd. Esta no era la intención de la función y no está funcionando correctamente, aunque es difícil de ver en este caso. A continuación, podemos usar el especificador local
para asegurarnos de que la función solo se ve dentro del alcance local de la variable. No lo encuentra debido al error tipográfico, pero al menos el error es un poco más fácil de detectar ahora.
PS> function testscope { $fooo = 'good'; "The value of `$fooo is $local:foo" }
PS> testscope
The value of $fooo is
El alcance private
es útil cuando no desea que ciertas variables sean visibles a las otras funciones que llama a su función.
bien, ¡eso tiene sentido! No sabía que las funciones pueden ser dot-source :). Entonces el [about_scripts] (http://technet.microsoft.com/en-us/library/dd819484.aspx#) en Microsoft TechNet no es correcto, creo. Lea la sección ÁMBITO DE ESCRITURA Y FUENTE DE PUNTOS. ¿Es eso correcto? –
Ejecute 'man about_scopes' desde el indicador de PowerShell. Ese sería un buen tema de ayuda para leer. –
Y usar 'Set-StrictMode -v latest' puede ayudarlo a evitar referencias accidentales a variables del alcance externo ... – Jaykul