2009-06-23 42 views
-1

この質問を閉じる。赤い牛を飲むだろう。睡眠。ユニットテストのケースでは、新しい疑問にぶつかるブランドでコーディングして戻ってください。Perlループが読み込みファイルを読み込んでいませんか?

UPDATE:新しいファイルがhere

である。また、設定ファイルはhere

である私は再びコードをリファクタリング:

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. 
+1

最後に不要な「 '; next;」を削除してもこれは起こりますか? –

+0

split()に使用されている/文字を入れるとすぐに壊れているようです。 – kthakore

+0

それはまだあります。たとえ次がなくても! – kthakore

答えて

6

FINAL POST:使用に問題がないかあなたの最新の更新プログラムに基づいて、私は次のコードは示して信じて/:/splitの最初の引数として使用します。また、1ではなく、グローバル変数に頼るよりも、関数に引数を使用する場合、コードを読みやすくであることを指摘:

#!/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. 使用字句ファイルハンドルとlet perlが、それは仮定ではなく、発生する可能性のあるどのようなエラーを教えてくれ。

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

  3. ループの本体に$_$conlineを割り当てる必要がない場合は、whileステートメントでこれを行うことができます。

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

  5. レトリックを下げてください。コンピュータはGIGOの原理に基づいて動作します。あなたはあなたができることに気づいていないよう

  6. the link you postedのコードを見てみると、それは見えます:あなたは、ハッシュが行われていたパッケージを使用しているよう

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

さらに、それが見えます仕事:

$ETLSpliter{filepath} 

最後に、あなたはSpliterが間違っている実現します。 ITYM:Splitter

+0

それでもループの/文字を使用するとすぐに破損しますか?何故ですか? cygwinでperlを使用していますが、ファイルはvimの[dos]モードにありますか?それは違いを生むだろうか? – kthakore

+0

パターンデリミタとして '/'を使うことにしたので、いいえ、プラットフォームとエディタは何の違いもありません。 –

+0

Um ... split(/ pattern /、$ foo)の使い方でまだ失敗しています。 split( 'pattern'、$ foo)を使う必要があります。なぜこれが起きているのか理解しないでください。私はあなたが言った変更を実装し、ファイルを投稿するようにします。 – kthakore

3

本当に問題はありますか? @columnsには決してデータを格納しないので、コードは常に空のリストを返します。

その他の注意事項:

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

$ETLSpliter::nameにあるもの - 任意の/文字をエスケープする必要があります。

スニペットの他の多くの問題は既に解決されていますので、私はそこには行かないでしょう。

+0

なぜその文字列でスラッシュをエスケープする必要がありますか? – innaM

+0

Manniがwinblowsのために – kthakore

+0

私はあなたの恩赦を請う? – innaM

0

結局のところ明らかにIT OUT !!!!!ワウスリープは素晴らしいパワーです。

とにかく。問題は私の死のメッセージで$ ETLSplitter :: configFileにありました。

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

これには、 '/'というwinblowsパス区切り文字があります。だから私は二重引用符で出力していたので、perlはパスの '/'をパターンとして解釈しました。ここ

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

からサブルーチンでプログラム全体の流れを台無し

... /=>/, 

へ。これはこれを行うことで解決されました。

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

最初と最後のdieステートメントの違いはありません。私はあなたがMS-Windowsを指しているwinblowsと言うときはいつですか?しかし、Windowsのパス区切りはいつからですか?これは意味をなさない。ごめんなさい。 – innaM

+0

私は$ ETLSpliter :: configFileを印刷するまでそれは私にはなかった。それはローカルイントラネットのために/ 10.0.1.1/inです。それは何がそれを台無しにしていた。 – kthakore

関連する問題