Instrução de controle Raku para criar seqüências numéricas interpretadas como numéricas

8

Eu tenho um grande hash de matrizes,

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

que varia de 88 a 100 e são lidos em arquivos de texto,

e quando imprimo %qual<discordant>.mine %qual<discordant>.maxvejo que os valores estão claramente errados.

Eu posso corrigir isso alterando a maneira como os dados são lidos nos arquivos de texto:

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

para

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

mas isso não foi intuitivo, levei alguns minutos para descobrir por que Raku / Perl6 estava dando respostas claramente incorretas no início. Teria sido muito fácil perder esse erro. No perl5, o comportamento padrão seria tratar essas seqüências como números de qualquer maneira.

Deve haver alguma declaração de controle para tornar esse comportamento padrão, como posso fazer isso?

vigarista
fonte
1
Como é @linepreenchido?
Elizabeth Mattijsen 29/10/19
@lineestá cheio de arquivos de texto,my @line = $line.split(/\s+/)
con
my @line = $line.wordsserá então mais rápido.
Elizabeth Mattijsen

Respostas:

10

O problema / característica é realmente que, no Raku, quando você lê linhas de um arquivo, elas se tornam cadeias de caracteres (também conhecidas como objetos do tipo Str). Se você chamar .mine .maxem uma matriz de Strobjetos, a semântica de cadeias será usada para determinar se algo é maior ou menor.

Não são valores especiais em Raku que agem como valores em Perl. Em Raku, eles são chamados de " alomorfos ". Eles são Str, mas também Num, ou Rat, ou Int, ou Complex.

A sintaxe para criar um alomorfo apropriado para uma string em $_é << $_ >>. Portanto, se você alterar a linha que lê as palavras para:

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

então os valores em @lineserão ou Strou IntStrou RatStr. O que deve fazer .mine .maxfuncionar como você espera.

No entanto, se você tiver certeza de que apenas o quinto elemento @lineserá numérico, provavelmente será mais eficiente converter o Strnúmero em um número antes de enviar para a matriz. Uma sintaxe mais curta seria o prefixo de +:

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

Embora você possa achar isso muito barulhento.

ATUALIZAÇÃO: Eu tinha esquecido que na verdade há um sub chamado valque pega um Stre cria um alomorfo apropriado (ou retorna o original Str). Portanto, o código para criação @linepode ser escrito como:

my @line = $line.words>>.&val
Elizabeth Mattijsen
fonte
1
Muitas vezes eu gosto de usar em .Numericvez de +em parte para evitar muitos símbolos seguidos, mas também porque salta um pouco mais para dizer "Ei, eu preciso disso como um número", +é pequeno o suficiente para se perder. o shuffle (idem para ~vs .Str).
user0721090601
Eu acho que o comportamento padrão no Raku deve ser semelhante ao Perl, ou seja, basicamente tudo é um alomorfo, é mais fácil e intuitivo. Eu acho que o padrão deve ser considerar seqüências de caracteres como 83.44numérico
con
Criar alomorfos é complicado em Raku, pois exige trabalho a ser feito para criar o tipo certo de alomorfismo. Isso é contrário ao Perl, onde esse trabalho é realizado quando a variável é realmente usada em um contexto numérico porque o Perl não possui nenhuma digitação explícita. Portanto, não criar tudo como um alomorfo não é apenas uma decisão de projeto muito bem pensada, também existem razões de desempenho para não fazer isso.
Elizabeth Mattijsen 30/10/19
fwiw, acho que o raku deve "fazer o que eu quero dizer" ... << $ _ >> é muito barulhento ... então, independentemente da velocidade, por favor, podemos ter um método, digamos $ line.allo para isso? (sim eu sei que eu posso escrever um!)
p6steve
val($line)não faria isso por você?
Elizabeth Mattijsen 31/10/19