Me gustaría hacer una sustitución de cadena en un forbloque usando una captura con nombre. Esperaba obtener los números 1,2,3 como salida. Pero es Nilpara la primera carrera, y luego 1 y 2 para la segunda y tercera carrera. ¿Cómo uso .substcorrectamente en la construcción de bucle? Veo el mismo comportamiento cuando uso una mapconstrucción en lugar del forbucle. Funciona como se esperaba, si lo reemplazo con un valor de cadena fijo.
for <a1 b2 c3> -> $var {
say $var;
say $var.subst(/.$<nr>=(\d)/, $<nr>); #.subst(/.$<nr>=(\d)/, 'X'); #OK
}
#`[
This is Rakudo version 2019.11 built on MoarVM version 2019.11
Output:
a1
Use of Nil in string context
in block at test3.pl6 line 3
b2
1
c3
2
]
raku
string-substitution
Valle Lukas
fuente
fuente

S///veces. En este caso, podrías hacerloS[.$<nr>=(\d)] = $<nr> given $varRespuestas:
TL; DR Aplazar la evaluación
$<nr>hasta después de la evaluación de la expresión regular. @ JoKing ++ sugiere una forma . Otra es simplemente envolver el reemplazo con llaves ({$<nr>}).¿Qué sucede cuando su código original llama?
substAntes de que Raku intente llamar a la
substrutina, reúne una lista de argumentos para pasarle.Hay dos valores El primero es una expresión regular. No , no funciona . El segundo valor es
$<nr>. Se evalúaNilporque, al comienzo de un programa, la variable de objeto de coincidencia actual está vinculada a algo que afirma que su valor esNily cualquier intento de acceder al valor de una clave dentro de él$<nr>- también devuelveNil. Entonces, las cosas ya han salido mal en este punto, antes desubstque se ejecute.Una vez que Raku ha reunido esta lista de argumentos, intenta llamar
subst. Tiene éxito ysubstcorre.Para obtener el próximo partido,
substejecuta la expresión regular. Esto actualiza la variable de objeto de coincidencia actual$/. Pero es demasiado tarde para hacer alguna diferencia en el valor de sustitución al que ya se ha pasadosubst.Con una coincidencia en la mano,
substluego mira el argumento de sustitución. Lo encuentraNily actúa en consecuencia.Para la segunda llamada de
subst,$<nr>ha tomado el valor de la primera llamada desubst. Y así.Dos formas de diferir la evaluación de
$<nr>@JoKing sugiere considerar el uso de
S///. Esta construcción evalúa primero la expresión regular (entre el primer par de/s), luego el reemplazo (entre el último par de/s). (El mismo principio se aplica si utiliza otrasSsintaxis válidas comoS[...] = ...).Si usa
subst, entonces, como se explicó en la sección anterior, Raku reúne la lista de argumentos antes de llamarlo. Encuentra una expresión regular (que no se ejecuta) y un cierre (que tampoco se ejecuta). Luego intenta llamarsubstcon esos argumentos y logra hacerlo.A continuación,
substcomienza a correr. Ha recibido código tanto para el partido (una expresión regular) como para la sustitución (un cierre).Ejecuta la expresión regular como la operación de coincidencia. Si la expresión regular devuelve una coincidencia,
substejecuta el cierre y utiliza el valor que devuelve como la sustitución.Por lo tanto, debido a que cambiamos de pasar
$<nr>como un valor desnudo, lo que significaba que se congelabaNil, a pasarlo envuelto en un cierre, lo que aplazó su evaluación hasta que$/se ajustara a una coincidencia con una<nr>entrada poblada , resolvimos el problema.Tenga en cuenta que esto solo funciona porque quien diseñó / implementó
substfue lo suficientemente inteligente / amable como para permitir que los argumentos de coincidencia y sustitución sean formas deCode(una expresión regular para la coincidencia y el cierre ordinario para la sustitución) si un usuario lo desea. Luego ejecuta el partido primero y solo luego ejecuta el cierre de sustitución si se ha pasado uno, utilizando el resultado de esa última llamada como la sustitución final. Del mismo modo,S///funciona porque eso ha sido diseñado para evaluar solo el reemplazo después de que primero se evaluó la sustitución.fuente