Скрипт с переменным количеством вещественных аргументов - PullRequest
7 голосов
/ 15 апреля 2020

Я пытаюсь написать скрипт Raku, который будет называться, например,

script 1.2 1.117 -2 0.037

Т.е. идея состоит в том, чтобы создать sub MAIN(@numbers) и каким-то образом получить массив @numbers как реальный (не Str, не IntStr). Один из способов сделать это - привести каждый элемент (если возможно) в for, но я уверен, что есть более элегантное решение.

1 Ответ

8 голосов
/ 15 апреля 2020

Я позволю читателям судить, является ли следующее технически жестоким взломом, или выглядит отвратительно отвратительно, или и то, и другое. Но это самая близкая вещь, которую я знаю в текущем синтаксисе Raku.

Во-первых, вам нужно принять переменное количество аргументов. (Это нужно для того, чтобы даже ваш код работал вообще. Я полагаю, что вы опечатали.)

Вместо того, чтобы использовать * или подобное, я буду использовать |. Мы увидим, почему в мес.

sub MAIN( |numbers ) { ... }

Далее я добавляю подпись.

sub MAIN( |numbers ( *@, :@reals = numbers».Real )) { ... }

Для этого используются:

  • Именованные параметры являются необязательными; и

  • Установка значения по умолчанию на основе аргументов, привязанных к параметрам слева в сигнатуре; и

  • Скрытие этого чиканера, чтобы сообщение об использовании не затрагивалось, и чтобы (я думаю ) пользователь не мог ввести значение, используя --reals=... или аналогичный. (На самом деле, сказать, что я думаю, что они не могут, слишком сильно. Я надеюсь они не могут.)

Это либо довольно ужасный хак, либо просто простое зло Не делайте этого в home work!

Код до сих пор предполагает, что аргументы действительно Real s. Если это не так, вещи go не так. Нам нужно разобраться и с этим.

Поэтому мы добавляем subset и добавляем это к подписи:

subset Reals where *».Real».defined.all;
sub MAIN( Reals |numbers ( *@, :@reals = numbers».Real )) { ... }

Здесь мы видим основную причину, по которой я использовал |, а не *; это единственный способ написать тип слева от slurpy, без этого мне пришлось бы вставить where, и все это было бы еще более ужасно некрасиво, чем сейчас.

Таким образом, мы заканчиваем с отображением:

subset Reals where *».Real».defined.all;
sub MAIN( Reals |numbers ( *@, :@reals = numbers».Real )) { .WHAT.say for @reals }

для исходной командной строки:

(Rat)
(Rat)
(Int)
(Rat)
...