Domanda

Chiusura di questa domanda. Berrà il toro rosso. Dormire. Codifica e torna con la nuova domanda sculacciata del marchio con i casi di test unitari.

AGGIORNAMENTO: il nuovo file è qui

Anche il file di configurazione è qui

Ho rifattorizzato nuovamente il codice:

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");
    }
}

Questo codice muore sempre qui die("$ETLSplitter::name is not specified in the config file");.

Un altro indizio è che se cambio split (':', $cols); in split (/:/, $cols); ottengo questo errore.

 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.
È stato utile?

Soluzione

POST FINALE PER QUESTA DOMANDA: in base ai tuoi ultimi aggiornamenti, credo che il seguente codice illustri come non vi siano problemi nell'uso di /:/ come primo argomento di split. Sottolinea inoltre che è più semplice leggere il codice quando si usano argomenti per le funzioni piuttosto che fare affidamento su variabili globali:

#!/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'
        ];

C'è molta cruft in quel codice. Ecco la mia interpretazione di ciò che stai cercando di fare:

AGGIORNAMENTO: data la tua recente osservazione sui caratteri speciali regex nei motivi, se li userai nel motivo per dividere, assicurati di citarli. È anche possibile che $ETLSpliter::name contenga altri caratteri speciali. Ho modificato il codice per far fronte a tale possibilità.

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;
  }

UN ALTRO AGGIORNAMENTO:

Quindi, il modello è in effetti /=>/ basato sul tuo commento qui sotto. Poi:

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'
        ];

Nessun errore ... Nessun avviso Pertanto, sta succedendo qualcos'altro su cui insisti a non mostrarci.

Altre osservazioni:

  1. Usa filehandle lessicali e lascia che perl ti dica quali errori potrebbe riscontrare piuttosto che presumere.

  2. Dichiara le variabili nel più piccolo ambito applicabile.

  3. Non è necessario assegnare $_ a $conline nel corpo del ciclo quando è possibile farlo nell'istruzione while.

  4. Nel codice originale, non hai inserito nulla in @columns o fatto nulla di utile con $colData.

  5. Riduci la retorica. I computer funzionano secondo il principio di GIGO.

  6. Guardando il codice in il link che hai pubblicato , sembra che tu non lo sia consapevole che puoi fare:

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

Inoltre, sembra che tu stia usando un pacchetto in cui l'hash avrebbe fatto il lavoro:

$ETLSpliter{filepath}

Infine, ti rendi conto che Spliter non è corretto. ITYM: Splitter.

Altri suggerimenti

Sei sicuro che sia bloccato? Non memorizzi mai dati in @columns, quindi il tuo codice restituirà sempre un elenco vuoto.

Altre note:

  • La tua chiamata die dovrebbe includere $! (errore del sistema operativo). Esistono altri motivi per cui il open potrebbe non riuscire oltre a un file inesistente e chomp $conline ti dirà qual è il vero problema.
  • Probabilmente dovresti fare un while (my $conline = <CFILE>) per sbarazzarti della nuova riga.
  • Puoi fare $_ invece di copiare il valore da <.
  • Due argomenti open(my $fh, '<', $filename) or die... (in particolare con una modalità <=> implicita) ha una forma scadente. È preferibile utilizzare il modulo a tre argomenti (idealmente con un filehandle lessicale): <=>

Cosa c'è in $ETLSpliter::name - qualsiasi / caratteri lì dovrebbe essere evitato.

Molti altri problemi nello snippet sono già stati risolti, quindi non ci andrò.

FINALMENTE FATTO FUORI !!!!! Wow Sleep è un potere fantastico.

In ogni caso. Il problema era in $ ETLSplitter :: configFile nel mio messaggio die.

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

Che ha i separatori di percorso winblows '/'. Quindi, poiché stavo producendo una doppia citazione, il perl ha interpretato il '/' nel percorso come schemi. Da qui

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

a

...  /=>/, 

Che ha incasinato l'intero flusso del programma nella subroutine. Ciò è stato risolto facendo questo.

<*>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top