Declaración de control de Raku para hacer que las cadenas numéricas se interpreten como numéricas

8

Tengo un gran hash de matrices,

%qual<discordant> (~ aproximadamente 13199 valores como '88 .23 ', '99 .23', etc.

que oscila entre 88 y 100, y se leen desde archivos de texto,

y cuando imprimo %qual<discordant>.miny %qual<discordant>.maxpuedo ver que los valores están claramente equivocados.

Puedo solucionar esto cambiando cómo se leen los datos de los archivos de texto:

%qual{$type}.push: @line[5]

a

%qual{$type}.push: @line[5].Num

pero esto no era intuitivo, me llevó unos minutos descubrir por qué Raku / Perl6 estaba dando respuestas claramente incorrectas al principio. Hubiera sido muy fácil pasar por alto este error. En perl5, el comportamiento predeterminado sería tratar estas cadenas como números de todos modos.

Debería haber alguna declaración de control para hacer que este sea el comportamiento predeterminado, ¿cómo puedo hacer esto?

estafa
fuente
1
¿Cómo @linese llena?
Elizabeth Mattijsen
@lineestá lleno de archivos de texto,my @line = $line.split(/\s+/)
con
my @line = $line.wordsEntonces será más rápido.
Elizabeth Mattijsen

Respuestas:

10

El problema / característica es realmente que en Raku cuando lees líneas de un archivo, se convierten en cadenas (también conocidos como objetos de tipo Str). Si llama .miny .maxen una matriz de Strobjetos, se usará la semántica de cadenas para determinar si algo es más grande o más pequeño.

No son valores especiales en Raku que actúan como valores en Perl. En Raku, estos se llaman " alomorfos ". Son Str, pero también Num, o Rat, o Int, o Complex.

La sintaxis para crear un alomorfo apropiado para una cadena $_es << $_ >>. Entonces, si cambia la línea que lee las palabras a:

my @line = $line.words.map: { << $_ >> }

entonces los valores en @lineserán o Str, IntStro RatStr. Lo que debería hacer .miny .maxfuncionar como esperabas.

Sin embargo, si está seguro de que solo el quinto elemento de @lineva a ser numérico, entonces probablemente sea más eficiente convertirlo Stra un número antes de pasar a la matriz. Una sintaxis más corta para eso sería prefijar a +:

%qual{$type}.push: +@line[5]

Aunque puede que te parezca demasiado ruidoso.

ACTUALIZACIÓN: Había olvidado que en realidad hay un sub llamado valque toma un Stry crea un alomorfo apropiado (o devuelve el original Str). Entonces el código para crear @linepodría escribirse como:

my @line = $line.words>>.&val
Elizabeth Mattijsen
fuente
1
A menudo me gusta usar en .Numericlugar de +en parte para evitar demasiados símbolos seguidos, pero también porque salta un poco más para decir "Oye, necesito esto como un número", +es lo suficientemente pequeño como para perderse en el shuffle (ídem para ~vs .Str).
user0721090601
Creo que el comportamiento predeterminado en Raku debería ser similar a Perl, es decir, básicamente todo es un alomorfo, es más fácil e intuitivo. Creo que lo predeterminado debería ser considerar cadenas 83.44como numéricas
con el
Crear alomorfos es engorroso en Raku, ya que requiere trabajo para poder crear el tipo de alomorfo correcto. Esto es contrario a Perl, donde ese trabajo se realiza cuando la variable se usa realmente en un contexto numérico porque Perl no tiene ningún tipo de escritura explícita. Por lo tanto, no crear todo como un alomorfo no es solo una decisión de diseño muy bien pensada, también hay razones de rendimiento para no hacerlo.
Elizabeth Mattijsen
fwiw creo que raku debería "hacer lo que quiero decir" ... << $ _ >> es muy ruidoso ... así que, independientemente de la velocidad, ¿podemos tener un método, digamos $ line.allo para esto? (sí, sé que puedo escribir uno!)
p6steve
val($line)no lo haría por ti?
Elizabeth Mattijsen el