Question

Fermeture de cette question. Va boire du taureau rouge. Sommeil. Codez et revenez avec une nouvelle question flambante avec des cas de tests unitaires.

UPDATE: le nouveau fichier est ici

.

Le fichier de configuration est également ici

J'ai refait le code:

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

Ce code meurt toujours ici die("$ETLSplitter::name is not specified in the config file");.

Un autre indice est que si je change de split (':', $cols); à split (/:/, $cols); je reçois cette erreur.

 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.
Était-ce utile?

La solution

ENVOI FINAL DE CETTE QUESTION: D'après vos dernières mises à jour, le code suivant montre bien que l'utilisation de /:/ en tant que premier argument de split ne pose aucun problème. Il indique également qu'il est plus facile de lire du code lorsque l'on utilise des arguments pour des fonctions plutôt que de s'appuyer sur des variables globales:

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

Il y a beaucoup de cruauté dans ce code. Voici mon interprétation de ce que vous essayez de faire:

UPDATE: Étant donné votre remarque récente sur les caractères spéciaux regex dans les modèles, si vous comptez les utiliser dans le modèle à scinder, veillez à les citer correctement. Il est également possible que $ETLSpliter::name contienne d'autres caractères spéciaux. J'ai modifié le code pour traiter cette 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;
  }

UNE AUTRE MISE À JOUR:

Ainsi, le modèle est en effet /=>/ basé sur votre commentaire ci-dessous. Puis:

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

Aucune erreur ... Aucun avertissement Par conséquent, vous tenez à autre chose que vous ne voulez pas nous montrer. / p>

Autres remarques:

  1. Utilisez des descripteurs de fichiers lexicaux et laissez perl vous indiquer les erreurs qu'il peut rencontrer plutôt que de les présumer.

  2. Déclarez les variables dans la plus petite portée applicable.

  3. Il n'est pas nécessaire d'attribuer $_ à $conline dans le corps de la boucle lorsque vous pouvez le faire dans l'instruction while.

  4. Dans le code d'origine, vous ne mettiez rien dans @columns ou ne faites rien qui soit utile avec $colData.

  5. Atténuez la rhétorique. Les ordinateurs fonctionnent sur le principe de GIGO.

  6. En regardant le code sur le lien que vous avez posté , il semble que vous ne l'êtes pas. conscient que vous pouvez faire:

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

De plus, il semblerait que vous utilisiez un package dans lequel hash aurait été utile:

$ETLSpliter{filepath}

Enfin, vous réalisez que Spliter est incorrect. ITYM: Splitter.

Autres conseils

Êtes-vous sûr que c'est bloqué? Vous ne stockez jamais de données dans @columns. Votre code renverra donc toujours une liste vide.

Autres notes:

  • Votre die appel doit inclure $! (erreur du système d'exploitation). Il y a d'autres raisons pour lesquelles open pourrait échouer en plus d'un fichier inexistant, et chomp $conline vous dira quel était le véritable problème.
  • Vous devriez probablement faire un while (my $conline = <CFILE>) pour vous débarrasser de la nouvelle ligne.
  • Vous pouvez faire $_ au lieu de copier la valeur de <.
  • Deux arguments open(my $fh, '<', $filename) or die... (en particulier avec un mode implicite <=>) ont une forme médiocre. L'utilisation de la forme à trois arguments (idéalement avec un descripteur de fichier lexical) est préférable: <=>

Qu'y a-t-il $ETLSpliter::name - Tous les / caractères qui y figurent doivent être masqués.

De nombreux autres problèmes figurant dans l'extrait de code ont déjà été traités, je ne vais donc pas y aller.

FINALEMENT FIGURED IT !!!!! Wow Sleep est une puissance incroyable.

Quoi qu'il en soit. Le problème était dans $ ETLSplitter :: configFile dans mon message de die.

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

Qui a des séparateurs de chemin Winblows '/'. Donc, parce que je sortais entre guillemets, Perl interpertait le '/' dans le chemin en tant que motif. À partir d'ici

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

à

...  /=>/, 

Qui a gâché le déroulement complet du programme dans le sous-programme. Cela a été résolu en faisant cela.

<*>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top