Digamos que uno crea una variable con nombre dinámico en zsh
, así:
name="hello"
typeset $name=42
echo ${(P)${name}} # Prints the variable $hello, which is 42
Ahora, supongamos que uno quiere incrementar o cambiar dicha variable, pero sin saber su nombre directo, es decir, esperaría que funcione algo similar a lo siguiente:
(( ${(P)${name}} = ${(P)${name}} + 1 )) # Set $hello to 43?
Lo anterior no funciona, ¿qué funcionará?
Respuesta1
$ name=hello
$ hello=42
$ (($name++))
$ echo $hello
43
Como en cualquier caparazón tipo Korn. O POSIXly:
$ name=hello
$ hello=42
$ : "$(($name += 1))"
$ echo "$hello"
43
El punto es que todas las expansiones de parámetros, sustituciones de comandos y expansiones aritméticas se realizan dentro de expresiones aritméticas antes de que se evalúe la expresión aritmética.
((something))
es parecido a
let "something"
Entonces, en (($name++))
(como let "$name++"
), primero se expande hello++
y se evalúa como el ++
operador aplicado a la hello
variable.
POSIX sh
no tiene ((...))
operador pero tiene la $((...))
aritméticaexpansiónoperador. No es así ++
(aunque permite que las implementaciones tengan uno como extensión en lugar de requerir que sea una combinación de +
operadores unarios y/o binarios), pero lo tiene +=
.
Al usar : "$((...))"
el :
comando null, obtenemos algo similar a ksh ((...))
. Aunque un equivalente estricto sería [ "$((...))" -ne 0 ]
, as ((expression))
devuelve falso cuando la expresión se resuelve en 0.
Respuesta2
Parece que esto lo hará:
typeset $name=$(( ${(P)${name}} + 1 ))
Cualquier método alternativo será muy apreciado.