รวม perl GetoptLong กับเคส ARGV เดี่ยวพิเศษหรือไม่

ฉันกำลังแปลเชลล์สคริปต์เป็นสคริปต์ Perl ที่ใช้ Getopt::Long และฉันต้องการรักษาความเข้ากันได้กับกรณีด้านล่าง โดยที่หากอาร์กิวเมนต์เดียวของสคริปต์คือไฟล์เดียว ไฟล์นั้นจะถูกใช้เป็นไฟล์ปรับแต่ง ในขณะที่ปกติคือการรับพารามิเตอร์เข้าสู่ GetoptLong

if [[ $# -eq 1 && -f $1 ]];
then 
    echo "Using config file $1"
    [...]
else 
    if [ $# -lt 2 ]; then usage "INCORRECT NUMBER OF PARAMETERS"; fi
    while getopts ":a:b:c:d:ef" opt;
    do
    [...]

ทางเลือกหนึ่งคือรักษา if/else ไว้ในสคริปต์ Perl ดังนี้:

if (1 == @ARGV && -f $ARGV[0]) {
  # use this config file
  config_file_method($ARGV[0]);
} else {
  # use GetOptions
  GetOptions(
         'a|foo:s' => \$foo,
         'b|bar:s' => \bar,
         [...]
        );
}

แต่ฉันสงสัยว่ากรณีพิเศษนี้สามารถรวมไว้ในฟังก์ชัน GetOptions ได้หรือไม่:

  GetOptions(
         'if only one element in @ARGV' => 'call config_file_method($ARGV[0])',
         'a|foo:s' => \$foo,
         'b|bar:s' => \bar,
         [...]
        );

มีความคิดอะไรบ้าง?


person 719016    schedule 26.09.2013    source แหล่งที่มา
comment
== เปรียบเทียบตัวเลข ตัวเลขเป็นสเกลาร์ ดังนั้น == กำหนดจึงเป็นบริบทสเกลาร์ของ args ทุกกรณีของ scalar ที่คุณมีไม่มีประโยชน์   -  person ikegami    schedule 26.09.2013
comment
@ikegami สังเกตว่าฉันได้เปลี่ยนมันแล้ว   -  person 719016    schedule 26.09.2013


คำตอบ (3)


ฉันไม่เห็นสิ่งใดในเอกสารประกอบ Getopt::Long ซึ่งสนับสนุนสิ่งที่คุณกำลังมองหา สำหรับ.

แนวทางที่ฉันจะใช้คือให้ GetOptions ประมวลผล @ARGV หากยังมีสิ่งใดอยู่ใน @ARGV แสดงว่านั่นคือไฟล์กำหนดค่า ดังนั้นจึงไม่จำเป็นต้องตรวจสอบ -f เพราะ config_file_method sub จะทำการตรวจสอบ open/die อยู่แล้ว

GetOptions(
    'a|foo:s' => \$foo,
    'b|bar:s' => \$bar,
);

config_file_method($ARGV[0]) if @ARGV;
person toolic    schedule 26.09.2013

ฉันค่อนข้างแน่ใจว่ามันเป็นไปไม่ได้ หากคุณส่ง config_file เป็นตัวเลือกแทนอาร์กิวเมนต์ คุณสามารถทำสิ่งที่คล้ายกัน:

GetOptions(
    'c|config_file' => sub { config_file_method($ARGV[0]) if 1 == scalar @ARGV } ,
    'a|foo:s' => \$foo,
    'b|bar:s' => \bar,
    [...]
);
person psxls    schedule 26.09.2013

ไม่มีตัวเลือกดังกล่าวใน Getopt::Long

และอย่างที่คุณได้แสดงให้เห็นแล้วว่า ไม่จำเป็นต้องมีอะไรเลย (มันไม่ได้ช่วยคุณประหยัดงานใดๆ แต่มันเพิ่มความซับซ้อนด้วยการประดิษฐ์ภาษาย่อยใหม่)

person ikegami    schedule 26.09.2013