14

在 Perl 5 中,我可以使用Getopt::Long一些验证来解析命令行参数(参见下面的http://perldoc.perl.org/Getopt/Long.html)。

use Getopt::Long;
my $data   = "file.dat";
my $length = 24;
my $verbose;
GetOptions ("length=i" => \$length,    # numeric
            "file=s"   => \$data,      # string
            "verbose"  => \$verbose)   # flag
or die("Error in command line arguments\n");

say $length;
say $data;
say $verbose;

这里=i在与和"length=i"关联的值上创建一个数字类型约束--length=s在其中"file=s"创建一个类似的字符串类型约束。

我如何在 Raku(née Perl 6)中做类似的事情?

4

2 回答 2

20

基本

该功能内置于 Raku(以前称为 Perl 6)中。这是您Getopt::Long在 Raku 中的代码的等价物:

sub MAIN ( Str  :$file    = "file.dat"
         , Num  :$length  = Num(24)
         , Bool :$verbose = False
         )
{
    $file.say;
    $length.say;
    $verbose.say;
}

MAIN是一个特殊的子例程,它根据其签名自动解析命令行参数。

StrNum提供字符串和数字类型约束。

Bool生成一个$verbose二进制标志,False如果不存在或调用为--/verbose. (/in--/foo一种常见的 Unix 命令行语法,用于将参数设置为False)。

:附加到子例程签名中的变量之前,使它们成为命名(而不是位置)参数。

使用$variable =后跟默认值提供默认值。

别名

如果你想要单个字符或其他别名,你可以使用:f(:$foo)语法。

sub MAIN ( Str  :f(:$file)    = "file.dat"
         , Num  :l(:$length)  = Num(24)
         , Bool :v(:$verbose) = False
         )
{
    $file.say;
    $length.say;
    $verbose.say;
}

:x(:$smth)在此示例中为--smth诸如短别名之类的附加别名。-x也可以使用多个别名和全名,这是一个示例::foo(:x(:bar(:y(:$baz))))将获取您--foo, -x, --bar,-y并且--baz如果它们中的任何一个将传递给$baz.

位置参数(和示例)

MAIN也可以与位置参数一起使用。例如,这里是Guess the number (from Rosetta Code)。它默认为最小值 0 和最大值 100,但可以输入任何最小值和最大值。Usingis copy允许在子例程中更改参数:

#!/bin/env perl6
multi MAIN
#= Guessing game (defaults: min=0 and max=100)
{
    MAIN(0, 100)
}

multi MAIN ( $max )
#= Guessing game (min defaults to 0)
{
    MAIN(0, $max)
}

multi MAIN
#= Guessing game
( $min is copy #= minimum of range of numbers to guess
, $max is copy #= maximum of range of numbers to guess
)
{
    #swap min and max if min is lower
    if $min > $max { ($min, $max) = ($max, $min) }

    say "Think of a number between $min and $max and I'll guess it!";
    while $min <= $max {
        my $guess = (($max + $min)/2).floor;
        given lc prompt "My guess is $guess. Is your number higher, lower or equal (or quit)? (h/l/e/q)" {
            when /^e/ { say "I knew it!"; exit }
            when /^h/ { $min = $guess + 1      }
            when /^l/ { $max = $guess          }
            when /^q/ { say "quiting"; exit    }
            default   { say "WHAT!?!?!"        }
        }
    }
    say "How can your number be both higher and lower than $max?!?!?";
}

使用信息

此外,如果您的命令行参数与签名不匹配MAIN,默认情况下您会收到有用的使用消息。请注意以 开头的子程序和参数注释如何#=巧妙地合并到此使用消息中:

./guess --help
Usage:
  ./guess -- Guessing game (defaults: min=0 and max=100)
  ./guess <max> -- Guessing game (min defaults to 0)
  ./guess <min> <max> -- Guessing game

    <min>    minimum of range of numbers to guess
    <max>    maximum of range of numbers to guess

这里--help没有定义命令行参数,因此触发了这个使用消息。

也可以看看

另请参阅2010、20142018 Perl 6 出现日历帖子 Perl 6中的帖子解析命令行参数,以及概要 6 关于 MAIN 的部分MAIN

于 2015-04-17T15:59:33.213 回答
5

或者,perl6 也有一个Getopt::Long。您的程序几乎无需修改即可在其中运行:

use Getopt::Long;
my $data   = "file.dat";
my $length = 24;
my $verbose;
get-options("length=i" => $length,    # numeric
            "file=s"   => $data,      # string
            "verbose"  => $verbose);  # flag

say $length;
say $data;
say $verbose;
于 2019-02-01T15:26:48.643 回答