¿Alguien puede explicar por qué al devolver $ false de una función de PowerShell no puede usar un operador de comparación para determinar si la función ha devuelto $ false pero cuando devuelve $ true la comparación se evalúa como $ true?
function boolean {
return $false
}
boolean -eq $false
function boolean {
return $true
}
boolean -eq $true
>>>False
>>>True
Puede solucionar esto configurando la llamada de función a una variable, pero me preguntaba si alguien podría explicar qué está sucediendo aquí debajo del capó.
function boolean {
return $false
}
$bool = boolean
$bool -eq $false
function boolean {
return $true
}
$bool = boolean
$bool -eq $true
>>>True
>>>True
2 respuestas
PowerShell tiene dos modos de análisis fundamentales :
argumento modo , que funciona como los tradicionales shells
- En el modo de argumento, el primer token se interpreta como un nombre de comando (como el nombre del cmdlet, el nombre de la función o el nombre de archivo de un ejecutable), seguido por una lista separada por espacios en blanco de argumentos .
Modo expresión , que funciona como los lenguajes de programación tradicionales.
Ejecutando Get-help about_Parsing
proporciona una introducción a estos modos; en resumen, es el primer token que determina qué modo se aplica.
También tenga en cuenta que una declaración determinada puede estar compuesta de partes que se analizan en cualquier modo.
boolean -eq $false
se analiza en modo argumento , porque su primer token parece un nombre de comando (un identificador que podría ser un nombre de programa, un nombre de cmdlet, un nombre de función o un alias).
Por lo tanto, -eq
y $false
se interpretan como argumentos (valores de parámetros) para pasar a la función boolean
.
Dado que sus funciones boolean
están definidas de una manera que no impone el paso de valores solo a parámetros declarados , los argumentos se ignoran de manera efectiva y el resultado de la declaración es cualquier salida de la función ($false
o $true
).
Como se demuestra en respuesta de Mike Shepard, puede hacer que una función aplique el uso de solo parámetros declarados (incluido none ) con un bloque param()
decorado con el atributo [CmdletBinding()]
, que al menos daría como resultado un error si pasas argumentos inadvertidamente a la función boolean
sin parámetros.
Puede solucionar esto configurando la llamada de función a una variable
$bool = boolean # execute function and capture result in variable
$bool -eq $false # use variable in the comparison
La razón por la que esto funciona es que la instrucción -eq
comienza con $
, una referencia de variable en este caso, lo que hace que PowerShell analice en modo expresión , donde -eq
se reconoce como un operador y $false
como su RHS.
Sin embargo, no es necesario realizar este paso intermedio:
Para forzar que un fragmento de código se interprete como una expresión , enciérrelo entre (...)
:
(boolean) -eq $false # Calls function 'boolean' and uses result as LHS of -eq
(...)
fuerza un nuevo contexto de análisis (que en sí mismo se analiza en modo de argumento o expresión, de nuevo según el primer token) y trata el resultado como una expresión . que luego permite su uso como parte de una expresión más grande , como un operando del operador -eq
, o como un argumento de comando .
PowerShell ve -eq como el nombre de un parámetro que se pasa a la función "booleana".
Para ver esto, puede poner la función llamada en parens:
function boolean {
return $false
}
(boolean) -eq $false
function boolean {
return $true
}
(boolean) -eq $true
O puede convertirla en una función avanzada para que obtenga un error con el parámetro faltante (-eq):
function boolean {
[CmdletBinding()]
Param()
return $false
}
boolean -eq $false
function boolean {
[CmdletBinding()]
Param()
return $true
}
boolean -eq $true
Preguntas relacionadas
Preguntas vinculadas
Nuevas preguntas
powershell
PowerShell es una línea de comandos multiplataforma y una utilidad de secuencias de comandos de Microsoft. Use esta etiqueta para preguntas sobre cómo escribir y ejecutar scripts de PowerShell SOLAMENTE. Las preguntas de programación específicas de la versión multiplataforma PowerShell Core (Windows, macOS y Linux) deben etiquetarse [powershell-core]. Se deben hacer preguntas sobre la administración del sistema en Super User o Server Fault.