문제

이 질문을 닫습니다. Red Bull을 마실 것입니다. 잠. 단위 테스트 사례로 새로운 질문을하는 브랜드를 코딩하고 다시 돌아옵니다.

업데이트 : 새 파일은입니다 여기

또한 구성 파일도 있습니다 여기

코드를 다시 리팩토링했습니다.

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

그 코드에는 많은 cruft가 있습니다. 다음은 당신이하려는 일에 대한 나의 해석입니다.

업데이트: 패턴의 Regex 특수 문자에 대한 최근의 언급을 감안할 때, 패턴으로 분할하여 분할하려면 인용해야합니다. 그 기회도 있습니다 $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. 할당 할 필요가 없습니다 $_ 에게 $conline 루프의 본문에서 while 성명.

  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 Newline을 제거합니다.
  • 넌 할 수있어 while (my $conline = <CFILE>) 값을 복사하는 대신 $_.
  • 두 가지 open (특히 암시 적 < 모드)는 형태가 좋지 않습니다. 세 가지 연계 양식 (어휘 파일 핸들이 이상적으로)을 사용하는 것이 선호됩니다. open(my $fh, '<', $filename) or die...

무슨 일이야 $ETLSpliter::name - 어느 / 숯이 탈출해야합니다.

스 니펫의 다른 많은 문제들이 이미 해결되었으므로 거기에 가지 않을 것입니다.

마침내 그것을 알아 냈습니다 !!!!! 와우 수면은 멋진 힘입니다.

그래도. 문제는 내 다이 메시지의 $ etlsplitter :: configfile에있었습니다.

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

Winblows 경로 분리기/'가 있습니다. 따라서 이중 인용문으로 출력했기 때문에 Perl은 경로에서 패턴으로 '/'를 삽입했습니다. 여기에서

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

에게

...  /=>/, 

서브 루틴의 전체 프로그램 흐름이 엉망이되었습니다. 이것은 이것을함으로써 해결되었습니다.

die ('Error opening '.$ETLSpliter::configFile.': '.$!);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top