如何在 sub MAIN 中获取强制命名参数?

zen*_*nix 9 raku

这是我能得到的最好的:

sub MAIN(Int :p($parm)!)
{
  say "* parm=", $parm;
}
Run Code Online (Sandbox Code Playgroud)

但:

$ raku test-par.raku
Usage:
  test-par.raku -p[=Int]
Run Code Online (Sandbox Code Playgroud)

它说参数是可选的!
确实如此:

 $ raku test-par.raku -p
 * parm=True
Run Code Online (Sandbox Code Playgroud)

那么,什么给出了?

uge*_*exe 4

ABool也恰好是Int

$ raku -e 'say True.Int'
1

$ raku -e 'say True ~~ Int'
True
Run Code Online (Sandbox Code Playgroud)

因为-p是 aBool它也是一个Int

$ raku -e 'sub MAIN(Int :p($param)) { say $param.raku; say $param ~~ Int; say $param.Int }' -p=42
IntStr.new(42, "42")
True
42

$ raku -e 'sub MAIN(Int :p($param)) { say $param.raku; say $param ~~ Int; say $param.Int }' -p
Bool::True
True
1

$ raku -e 'sub MAIN(Int :p($param)) { say $param.raku; say $param ~~ Int; say $param.Int }' --/p
Bool::False
True
0
Run Code Online (Sandbox Code Playgroud)

该参数仍然是可选的;-p只是被视为(可以说是不直观的)像-p=1. 不幸的是,要实际执行请求的约束,需要添加额外的过滤器:

$ raku -e 'sub MAIN(Int :p($param) where * !~~ Bool) { say $param.raku; say $param ~~ Int; say $param.Int }' --p=1
IntStr.new(1, "1")
True
1

$ raku -e 'sub MAIN(Int :p($param) where * !~~ Bool) { say $param.raku; say $param ~~ Int; say $param.Int }' -p
Usage:
  -e '...' [-p[=Int where { ... }]]
Run Code Online (Sandbox Code Playgroud)