Perl 프로그램에서 하드 코딩 된 구성을 어떻게 무시할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/356337

  •  21-08-2019
  •  | 
  •  

문제

사용될 디렉토리 및 파일의 상단 근처에 변수를 설정하는 Perl 스크립트가 있습니다. 또한 몇 가지 변수를 명령 줄 인수로 설정해야합니다. 예시:

use Getopt::Long;

my ($mount_point, $sub_dir, $database_name, $database_schema);
# Populate variables from the command line:
GetOptions(
    'mount_point=s'       => \$mount_point,
    'sub_dir=s'           => \$sub_dir,
    'database_name=s'     => \$database_name,
    'database_schema=s'   => \$database_schema
);
# ...  validation of required arguments here

################################################################################
# Directory variables
################################################################################
my $input_directory    = "/${mount_point}/${sub_dir}/input";
my $output_directory   = "/${mount_point}/${sub_dir}/output";
my $log_directory      = "/${mount_point}/${sub_dir}/log";
my $database_directory = "/db/${database_name}";
my $database_scripts   = "${database_directory}/scripts";

################################################################################
# File variables
################################################################################
my $input_file       = "${input_dir}/input_file.dat";
my $output_file      = "${output_dir}/output_file.dat";
# ... etc

이것은 내 개발자, 테스트 및 생산 환경에서 잘 작동합니다. 그러나 개발 및 테스트를 위해 특정 변수 (디버거로 들어 가지 않고)를 더 쉽게 무시할 수 있도록 노력했습니다. (예를 들어, input_file = "/tmp/my_input_file.dat"을 설정하려면). 내 생각은 getoptions 기능을 사용하여 다음과 같은 것을 처리하는 것이 었습니다.

GetOptions(
    'input_directory=s'      => \$input_directory,
    'output_directory=s'     => \$output_directory,
    'database_directory=s'   => \$database_directory,
    'log_directory=s'        => \$log_directory,
    'database_scripts=s'     => \$database_scripts,
    'input_file=s'           => \$input_file,
    'output_file=s'          => \$output_file
);

getOptions는 한 번만 (내가 아는 한)라고 불릴 수 있습니다. 내 첫 Snippit의 첫 4 가지 인수는 필요하며, 마지막 7 개는 바로 선택 사항입니다. 이상적인 상황은 첫 번째 코드 Snippit에서와 같이 기본값을 설정 한 다음 명령 줄에서 인수가 전달 된 경우 설정된 모든 것을 무시하는 것입니다. 해시에 모든 옵션을 해시에 저장 한 다음 해시에 항목이 존재하지 않는 한 기본값으로 각 변수를 설정할 때 해시를 사용하는 것에 대해 생각했지만 많은 추가 로직을 추가하는 것 같습니다. 스크립트의 두 곳에서 getOptions를 호출하는 방법이 있습니까?

그것이 의미가 있는지 확실하지 않습니다.

감사!

도움이 되었습니까?

해결책

여기에 또 다른 접근법이 있습니다. 이름의 배열과 해시를 사용하여 옵션을 저장합니다. 모든 옵션을 진정으로 선택 사항으로 만들지 만 명령 줄에 "-debug"를 포함하지 않는 한 필요한 옵션을 확인합니다. "-debug"를 사용하든 상관없이 다른 사람을 무시할 수 있습니다.

물론 그것이 중요한지 더 명시적인 논리 검사를 할 수 있습니다. 어쨌든 "input_file"및 "output_file"변수를 무시하려는 경우 "mount_point"와 같은 기본 옵션을 생략하는 방법의 예로 "-debug"를 포함 시켰습니다.

여기서 주요 아이디어는 옵션 이름 세트를 배열로 유지함으로써 코드가 비교적 작은 그룹에 대한 논리 검사를 포함시킬 수 있다는 것입니다.

use Getopt::Long;

my @required_opts = qw(
    mount_point
    sub_dir
    database_name
    database_schema
);

my @internal_opts = qw(
    input_directory
    output_directory
    log_directory
    database_directory
    database_scripts
    input_file
    output_file
);

my @opt_spec = ("debug", map { "$_:s" } @required_opts, @internal_opts);

# Populate variables from the command line:
GetOptions( \(my %opts), @opt_spec );

# check required options unless 
my @errors = grep { ! exists $opts{$_} } @required_options;
if ( @errors && ! $opts{debug} ) {
    die "$0: missing required option(s): @errors\n";
}

################################################################################
# Directory variables
###############################################################################
my $opts{input_directory}    ||= "/$opts{mount_point}/$opts{sub_dir}/input";
my $opts{output_directory}   ||= "/$opts{mount_point}/$opts{sub_dir}/output";
my $opts{log_directory}      ||= "/$opts{mount_point}/$opts{sub_dir}/log";
my $opts{database_directory} ||= "/db/$opts{database_name}";
my $opts{database_scripts}   ||= "$opts{database_directory}/scripts";

################################################################################
# File variables
################################################################################
my $opts{input_file}    ||= "$opts{input_directory}/input_file.dat";
my $opts{output_file}   ||= "$opts{output_directory}/output_file.dat";
# ... etc

다른 팁

하드 코딩 된 구성 대신 구성 파일을 사용하도록 프로그램을 변경 해야하는 것 같습니다. 나는 전체 장을 바쳤다 마스터 링 Perl 이에. 프로그램을 테스트하기 위해 소스 코드를 변경하고 싶지 않습니다.

CPAN에는 구성 파일을 쉽게 추가 할 수있는 기능을 만드는 많은 Perl 모듈이 있습니다. 입력 데이터에 가장 적합한 것을 선택하십시오.

더 나은 구성 모델을 제자리에 올리면 기본값을 쉽게 설정하고 여러 장소 (파일, 명령 줄 등)에서 값을 가져오고 다른 값으로 프로그램을 쉽게 테스트 할 수 있습니다.

내가 할 일이 설정되었다고 생각합니다 input_directory et al은 "undef"로, 그리고 나서 그것들을 getopts에 넣은 다음 나중에 그것들이 여전히 undef인지 테스트 한 다음 그림대로 할당하는 경우를 테스트하십시오. 사용자가 기술적으로 정교하다면 "내가 상대적인 경로를 제공한다면 그것은 $mount_point/$sub_dir", 나는 초기"/"를 찾기 위해 추가 파싱을 할 것입니다.

배열로 입력 데이터로 GetOptions를 호출 할 수 있습니다. 읽기 선적 서류 비치.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top