質問

この質問を終了します。レッドブルを飲みます。睡眠。ユニットテストケースを使用して、新しい質問をコーディングしてブランドに戻ってください。

更新:新しいファイルはこちら

また、設定ファイルはこちら

コードを再度リファクタリングしました:

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

このコードは常にここで死ぬdie("$ETLSplitter::name is not specified in the config file");

別の手がかりは、split (':', $cols);split (/:/, $cols);に変更するとこのエラーが発生することです。

 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.
役に立ちましたか?

解決

この質問の最終投稿:最新の更新に基づいて、次のコードは/:/の最初の引数としてsplitを使用しても問題がないことを示していると思います。また、グローバル変数に依存するよりも、関数の引数を使用するとコードを読みやすくなることも指摘しています。

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

そのコードには多くの問題があります。あなたがしようとしていることの私の解釈は次のとおりです。

更新:パターン内の正規表現の特殊文字に関する最近の発言を考えると、パターンでそれらを使用して分割する場合は、必ず引用符で囲んでください。 $ETLSpliter::nameに他の特殊文字が含まれる可能性もあります。その可能性に対処するためにコードを修正しました。

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

別の更新:

したがって、パターンは実際に以下のコメントに基づいて/=>/です。次に:

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

エラーなし ... 警告なし したがって、私たちを見せないことを主張している何か他のものがあります。

その他のコメント:

  1. レキシカルファイルハンドルを使用し、perlが推測するのではなく、発生する可能性のあるエラーを教えてください。

  2. 適用可能な最小のスコープで変数を宣言します。

  3. $_ステートメントで実行できる場合、ループの本体で$conlinewhileを割り当てる必要はありません。

  4. 元のコードでは、@columnsに何かを入れたり、$colDataで何か便利なことをしたりしていませんでした。

  5. レトリックを調整します。コンピューターはGIGOの原則に基づいて動作します。

  6. 投稿したコードのコードを見ると、そうではないようですあなたができることに注意してください:

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

さらに、ハッシュを使用してパッケージを使用しているように見えます:

$ETLSpliter{filepath}

最後に、Spliterが間違っていることに気付きます。 ITYM:Splitter

他のヒント

それがスタックしていることは確かですか? @columnsにはデータを保存しないため、コードは常に空のリストを返します。

その他の注意:

  • die呼び出しには$!(OSエラー)を含める必要があります。存在しないファイル以外にopenが失敗する可能性のある他の理由があり、chomp $conlineは実際の問題が何であるかを教えてくれます。
  • おそらくwhile (my $conline = <CFILE>)を実行して、改行を削除する必要があります。
  • $_から値をコピーする代わりに<を実行できます。
  • 2つの引数open(my $fh, '<', $filename) or die...(特に暗黙的な<=>モードの場合)は、形式が貧弱です。 3つの引数形式(理想的にはレキシカルファイルハンドル)を使用することをお勧めします:<=>

$ETLSpliter::nameの内容-そこにある/文字はすべてエスケープする必要があります。

スニペットの他の多くの問題はすでに対処されているため、ここには行きません。

最終的にそれを計算しました!!!!!すごい睡眠は素晴らしいパワーです。

とにかく。問題は、ダイメッセージの$ ETLSplitter :: configFileにありました。

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

Winblowsパス区切り文字「/」があります。そのため、二重引用符で出力しているため、perlはパスに「/」をパターンとして挿入しました。ここから

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

to

...  /=>/, 

サブルーチン内のプログラムフロー全体を台無しにしました。これはこれを行うことで解決しました。

<*>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top