如何从 Raku 命令行获取多个文件名?
How do I take multiple filenames from the Raku command line?
这个 Raku 程序按我的预期工作:
sub MAIN($name) { say "Got $name" }
我可以在命令行中传递一个名字:
$ raku m1.raku foo
Got foo
明显的扩展,但是,
sub MAIN(@names) { say "Got $_" for @names }
无效:
$ raku mm.raku foo
Usage:
mm.raku <names>
$ raku mm.raku foo bar
Usage:
mm.raku <names>
我做错了什么?
您必须为此使用 slurpy array 签名:
sub MAIN(*@names) { say "Got $_" for @names }
按需工作:
$ raku mm.raku
$ raku mm.raku foo
Got foo
$ raku mm.raku foo bar
Got foo
Got bar
@cjm 说的。
但是,您可以更进一步,检查您指定的名称是否实际上是文件。如果不是,则产生一条错误消息。诀窍是使用多分派:
subset File of Str where *.IO.f;
multi sub MAIN(*@files where @files.all ~~ File) {
say "These are all files: @files.join(",")";
}
multi sub MAIN(*@files) {
say "These are *NOT* files: @files.grep(* !~~ File).join(",")";
}
如果命令行中指定的所有名称实际上都是文件,则第一个候选者将是 运行。如果第一个没有触发,第二个候选者将是 运行,这意味着并非所有指定的名称实际上都是文件。
有一个特殊的 $*ARGFILES
变量,它提供了一种方法来遍历通过命令行传递给程序的文件。
#!/usr/bin/raku
for $*ARGFILES.handles -> $fh {
say $fh;
}
$ ./enum_files.raku links.txt words.txt
IO::Handle<"links.txt".IO>(opened)
IO::Handle<"words.txt".IO>(opened)
我们可以使用它的 lines
方法来读取给定文件的行。
#!/usr/bin/raku
.say for $*ARGFILES.lines
$ ./read_lines.raku words.txt words2.txt
sky
cloud
cup
rock
war
tea
coffee
falcon
...
@cjm 的回答对你的问题是正确的。但正如 Jan 所说,还有另一种方式:
说“得到:”@*ARGS
其中@*ARGS 是在命令行上定义为 args 的动态变量。
$*ARGFILES 有一些额外的细微差别。如果没有 args,则在 main 之外从 @*ARGS 或 $*IN 获取其值。在 main 里面它只是做 $*IN.
这个 Raku 程序按我的预期工作:
sub MAIN($name) { say "Got $name" }
我可以在命令行中传递一个名字:
$ raku m1.raku foo
Got foo
明显的扩展,但是,
sub MAIN(@names) { say "Got $_" for @names }
无效:
$ raku mm.raku foo
Usage:
mm.raku <names>
$ raku mm.raku foo bar
Usage:
mm.raku <names>
我做错了什么?
您必须为此使用 slurpy array 签名:
sub MAIN(*@names) { say "Got $_" for @names }
按需工作:
$ raku mm.raku
$ raku mm.raku foo
Got foo
$ raku mm.raku foo bar
Got foo
Got bar
@cjm 说的。
但是,您可以更进一步,检查您指定的名称是否实际上是文件。如果不是,则产生一条错误消息。诀窍是使用多分派:
subset File of Str where *.IO.f;
multi sub MAIN(*@files where @files.all ~~ File) {
say "These are all files: @files.join(",")";
}
multi sub MAIN(*@files) {
say "These are *NOT* files: @files.grep(* !~~ File).join(",")";
}
如果命令行中指定的所有名称实际上都是文件,则第一个候选者将是 运行。如果第一个没有触发,第二个候选者将是 运行,这意味着并非所有指定的名称实际上都是文件。
有一个特殊的 $*ARGFILES
变量,它提供了一种方法来遍历通过命令行传递给程序的文件。
#!/usr/bin/raku
for $*ARGFILES.handles -> $fh {
say $fh;
}
$ ./enum_files.raku links.txt words.txt
IO::Handle<"links.txt".IO>(opened)
IO::Handle<"words.txt".IO>(opened)
我们可以使用它的 lines
方法来读取给定文件的行。
#!/usr/bin/raku
.say for $*ARGFILES.lines
$ ./read_lines.raku words.txt words2.txt
sky
cloud
cup
rock
war
tea
coffee
falcon
...
@cjm 的回答对你的问题是正确的。但正如 Jan 所说,还有另一种方式:
说“得到:”@*ARGS
其中@*ARGS 是在命令行上定义为 args 的动态变量。
$*ARGFILES 有一些额外的细微差别。如果没有 args,则在 main 之外从 @*ARGS 或 $*IN 获取其值。在 main 里面它只是做 $*IN.