我正在尝试编写一个 Raku 脚本来调用,例如
script 1.2 1.117 -2 0.037
即,想法是创建一个sub MAIN(@numbers)并以某种方式将数组@numbers作为 Real(不是 Str,不是 IntStr)。这样做的一种方法是将每个元素(如果可能)投射到 a 中for,但我确信有一个更优雅的解决方案。
I'll let readers judge whether the following is a technically atrocious hack, or looks hideously repugnant, or both. But it's the closest thing I'm aware of in current Raku syntax.
First, you need to accept a variable number of arguments. (You need that for even your code to work at all. I presume you typo'd.)
Rather than use * or similar I'll use |. We'll see why in a mo.
sub MAIN( |numbers ) { ... }
Run Code Online (Sandbox Code Playgroud)
Next, I add a sub-signature.
sub MAIN( |numbers ( *@, :@reals = numbers».Real )) { ... }
Run Code Online (Sandbox Code Playgroud)
This takes advantage of:
Named parameters being optional; and
Establishing a default value based on arguments bound to parameters to the left in a signature; and
Hiding this chicanery so the usage message is not affected, and so that (I think) the user cannot inject a value using --reals=... or similar. (Actually, saying I think they can't is far too strong. I hope they can't.)
This is either a pretty terrible hack or just plain evil. Don't do this at home work!
The code so far presumes that the arguments are indeed Reals. If they're not, things go wrong. We need to deal with that too.
So we add a subset and add that to the signature:
subset Reals where *».Real».defined.all;
sub MAIN( Reals |numbers ( *@, :@reals = numbers».Real )) { ... }
Run Code Online (Sandbox Code Playgroud)
Here we see the main reason I used | rather than *; it's the only way to write a type on the left of a slurpy, Without that I'd have to inline the where and the whole thing would be even more unspeakably ugly than it is.
Thus we end up with:
subset Reals where *».Real».defined.all;
sub MAIN( Reals |numbers ( *@, :@reals = numbers».Real )) { .WHAT.say for @reals }
Run Code Online (Sandbox Code Playgroud)
displaying, for your original command line:
(Rat)
(Rat)
(Int)
(Rat)
Run Code Online (Sandbox Code Playgroud)