Pergunta

Fechar esta questão. Vai beber touro vermelho. Dormir. Código e voltar com marca spanking nova pergunta com casos de teste de unidade.

UPDATE: O novo arquivo é aqui

Além disso, o arquivo de configuração é aqui

Eu refeito novamente o código:

sub getColumns {
    open my $input, '<', $ETLSplitter::configFile
        or die "Error opening '$ETLSpliter::configFile': $!";

    my $cols;
    while( my $conline = <$input> ) {
        chomp $conline;
        my @values = split (/=>/, $conline);
        if ($ETLSplitter::name =~ $values[0] ) {
            $cols = $values[1];
            last;
        }
    }

    if($cols) {
        @ETLSplitter::columns = split (':', $cols);
    }
    else {
        die("$ETLSplitter::name is not specified in the config file");
    }
}

Este código sempre morre aqui die("$ETLSplitter::name is not specified in the config file");.

Outra dica é que se eu mudar split (':', $cols); para split (/:/, $cols); eu recebo este erro.

 perl -wle "
 use modules::ETLSplitter;
 \$test = ETLSplitter->new('cpr_operator_metric_actual_d2', 'frame/');
 \$test->prepareCSV();"
 syntax error at modules/ETLSplitter.pm line 154, near "}continue"
 Compilation failed in require at -e line 2.
 BEGIN failed--compilation aborted at -e line 2.
Foi útil?

Solução

FINAL POST para esta pergunta: Com base em suas últimas atualizações, eu acredito que o código a seguir ilustra como não há nenhum problema com o uso /:/ como o primeiro argumento para split. Ele também aponta que é mais fácil de ler o código quando se usa argumentos para funções em vez de depender de variáveis ??globais:

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

for my $varname ( qw( adntopr.cpr.smtref.actv cpr_operator_detail )) {
    print $varname, "\n";
    print Dumper get_columns(\*DATA, $varname);
}

sub get_columns {
    my ($input_fh, $varname) = @_;

    while ( my $line = <$input_fh> ) {
        chomp $line;
        my @values = split /=>/, $line;
        next unless $varname eq $values[0];
        return [ split /:/, $values[1] ];
    }
    return;
}

__DATA__
adntopr.cpr.smtref.actv=>3:8:18:29:34:38:46:51:53:149
adntopr.smtsale2=>3:8:16:22:27:37:39:47:52:57:62:82:102:120:138:234:239:244:249:250:259:262:277:282:287:289:304:319:327:331:335:339:340:341:342:353:364:375:386:397:408
cpr_operator_detail=>3:11:18:28:124:220:228:324
cpr_operator_org_unit_map=>7:12
cpr_operator_metric_actual=>8:15:25:33:38:40:51

C:\Temp> tjm
adntopr.cpr.smtref.actv
$VAR1 = [
          '3',
          '8',
          '18',
          '29',
          '34',
          '38',
          '46',
          '51',
          '53',
          '149'
        ];
cpr_operator_detail
$VAR1 = [
          '3',
          '11',
          '18',
          '28',
          '124',
          '220',
          '228',
          '324'
        ];

Há um monte de cruft nesse código. Aqui é a minha interpretação do que você está tentando fazer:

UPDATE: Dada a sua recente observação sobre caracteres especiais regex em padrões, se você estiver indo para usá-los no padrão de divisão, certifique-se de citá-los. Há também uma chance de que $ETLSpliter::name pode conter outros caracteres especiais. Eu modifiquei o código para lidar com essa possibilidade.

sub getColumns {
    open my $input, '<', $ETLSpliter::configFile
          or die "Error opening '$ETLSpliter::configFile': $!");
      my @columns;
      while( my $conline = <$input> ) {
          my @values = split /=>/, $conline;
          print "not at: ".$conline;
          push @columns, $values[1] if $values[0] =~ /\Q$ETLSpliter::name/;
      }
      return @columns;
  }

Outra atualização:

Assim, o padrão de fato é /=>/ com base no seu comentário abaixo. Então:

my $conline = q{cpr_operator_detail=>3:11:18:28:124:220:228:324};
my @values = split /=>/, $conline;

use Data::Dumper;
print Dumper \@values;
__END__

C:\Temp> tml
$VAR1 = [
          'cpr_operator_detail',
          '3:11:18:28:124:220:228:324'
        ];

Sem erros ... Nenhuma advertência Portanto, não há outra coisa que está acontecendo que você insiste em não mostrar-nos.

Outras Observações:

  1. Use filehandles lexicais e deixá-perl dizer o que erros que podem ocorrer em vez de presumir.

  2. variáveis ??Declare no menor espaço aplicável.

  3. Não há necessidade de $_ atribuir a $conline no corpo do loop quando você pode fazer isso na declaração while.

  4. No código original, você não colocar nada em @columns ou fazer qualquer coisa útil com $colData.

  5. suavizar a retórica. Computadores trabalham com o princípio de GIGO.

  6. Olhando para o código em o link que você postou , parece que você não está ciente de que você pode fazer:

    use File::Spec::Functions qw( catfile );
    ...
    catfile($ETLSpliter::filepath_results, $ETLSpliter::actual_name);
    

Além disso, parece que você está usando um pacote onde haxixe teria feito o trabalho:

$ETLSpliter{filepath}

Finalmente, você percebe Spliter está incorreto. ITYM:. Splitter

Outras dicas

Você tem certeza que ele está preso? Você nunca armazenar todos os dados em @columns, para que o seu código sempre retornará uma lista vazia.

Outras indicações:

  • A sua chamada die deve incluir $! (erro OS). Há outras razões que o open poderia deixar além de um arquivo inexistente, e $! vai dizer o que o verdadeiro problema era.
  • Você provavelmente deve fazer um chomp $conline para se livrar da nova linha.
  • Você pode fazer while (my $conline = <CFILE>) em vez de copiar o valor de $_.
  • open Two-argumento (particularmente com um modo < implícita) é uma forma pobre. Usando o formulário três argumentos (de preferência com um filehandle lexical) é o preferido: open(my $fh, '<', $filename) or die...

O que está em $ETLSpliter::name -. Quaisquer caracteres / não deve ser escapado

Muitas outras questões no trecho já foram abordadas por isso não vou ir lá.

finalmente descobri-lo !!!!! Uau sono é incrível poder.

De qualquer forma. O problema estava em $ ETLSplitter :: configFile na minha mensagem de morrer.

die ('Error opening '.$ETLSpliter::configFile.': '.$!);

Que tem Winblows separadores de caminho '/'. Então porque eu estava saída em dupla cotação, perl interperted a '/' no caminho como padrões. A partir daqui

die "Error opening some/path/to/ ...

para

...  /=>/, 

O que mexeu com todo o fluxo de programa na sub-rotina. Isto foi resolvido fazendo isso.

die ('Error opening '.$ETLSpliter::configFile.': '.$!);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top