<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>Mikrotik.moscow [тема: Несколько неофициальных операторов, которые довольно забавные.]</title>
		<link>http://mikrotik.moscow</link>
		<description>Новое в теме Несколько неофициальных операторов, которые довольно забавные. форума RouterOS на сайте Mikrotik.moscow [mikrotik.moscow]</description>
		<language>ru</language>
		<docs>http://backend.userland.com/rss2</docs>
		<pubDate>Fri, 31 Jul 2026 17:27:56 -0400</pubDate>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388977">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Я нормально отношусь к тому, чтобы оставить RouterOS (и эти парсероподобные штуки в стиле lex/yacc для CLI/API) самим Mikrotik. Сейчас бы лучше они открыли процесс загрузки с помощью ONIE, GRUB или чего-то подобного — потому что на данный момент очень сложно заставить что-то вроде cilium, NokiaSR, OpenWRT и тому подобное работать на железе Mikrotik. Модифицировать RouterOS… честно говоря, не уверен, что это кому-то действительно нужно. А вот запускать cilium или что-то подобное на более бюджетном железе Mikrotik — это я бы понял.<br /><br />Я бы давно подписался под петицией за открытый исходный код для Dude, если бы она не была такой бессмысленной. Главное, что меня волнует в плане открытости — это схема базы данных SQLite, которую использует Dude. Сегодня существует уйма инструментов, которые могут обрабатывать SQLite из данных Dude и показывать их в стильном и современном интерфейсе с графиками и прочим, и всё это без использования самого UI Dude. Но, как обычно у Mikrotik, все поля в базе закодированы или запутаны в какие-то короткие коды. Несколько лет назад кто-то пытался вытащить данные с помощью Python, но смог получить всего несколько полей. <br />
			<i>17.06.2024 15:45:00, Amm0.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388977</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388977</guid>
			<pubDate>Mon, 17 Jun 2024 15:45:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388976">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Настаиваю… <noindex><a href="http://forum.mikrotik.com/t/mikrotik-events-script-new-abroach/176282/10" target="_blank" rel="nofollow" >http://forum.mikrotik.com/t/mikrotik-events-script-new-abroach/176282/10</a></noindex> <br />
			<i>17.06.2024 15:17:00, rextended.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388976</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388976</guid>
			<pubDate>Mon, 17 Jun 2024 15:17:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388975">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Отлично! <br />
			<i>17.06.2024 13:36:00, Larsa.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388975</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388975</guid>
			<pubDate>Mon, 17 Jun 2024 13:36:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388974">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Я написал более практичный пример синтаксиса $(&gt;), «quote» / «op» вчера, $qkeys. Это позволяет назначать нажатия клавиш для выполнения команд в виде меню-дерева. Вы можете сделать массив $qkeymap, содержащий любые команды, которые регулярно используете. Затем просто запускайте «$qkeys» в CLI, и одна клавиша будет запускать любую команду, определённую в массиве. Что-то вроде «горячей клавиши», но команды задаются в массиве, который можно менять — используя тип «quote» (также известный как «op»). Функция $qkeys принимает массив с действиями, которые надо выполнять при нажатии клавиш, определённый в ($qkeymap). Для работы требуется версия 7.15, но только потому, что используется [:convert from=byte-array] — новая команда (хотя её можно заменить на функцию из @rextended, которая конвертирует ASCII-код в строку).<br /><br />:global qkeys<br />:global qkeysmap<br /><br />:set qkeysmap {<br /> &nbsp; &nbsp;c = {"container"; {<br /> &nbsp; &nbsp; &nbsp; &nbsp;l = (&gt;[/log/print follow-only proplist=message where topics~"container"])<br /> &nbsp; &nbsp; &nbsp; &nbsp;p = (&gt;[/container/print])<br /> &nbsp; &nbsp; &nbsp; &nbsp;e = (&gt;[/container/env/print])<br /> &nbsp; &nbsp; &nbsp; &nbsp;m = (&gt;[/container/mounts/print])<br /> &nbsp; &nbsp;}}<br /> &nbsp; &nbsp;"4" = {"ip"; {<br /> &nbsp; &nbsp; &nbsp; &nbsp;a = {"address"; (&gt;[/ip/address/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;r = {"route"; (&gt;[/ip/route/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;f = {"firewall"; {<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;f = {"filter"; (&gt;[/ip/firewall/filter/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;n = {"nat"; (&gt;[/ip/firewall/nat/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m = {"mangle"; (&gt;[/ip/firewall/mangle/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c = {"connections"; (&gt;[/ip/firewall/connection/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;}}<br /> &nbsp; &nbsp;}}<br /> &nbsp; &nbsp;"6" = {"ipv6"; {<br /> &nbsp; &nbsp; &nbsp; &nbsp;a = {"address"; (&gt;[/ipv6/address/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;r = {"route"; (&gt;[/ipv6/route/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;"-" = {"disable"; (&gt;[/ipv6/settings/set disable-ipv6=yes])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;"+" = {"enable"; (&gt;[/ipv6/settings/set disable-ipv6=no])}<br /> &nbsp; &nbsp;}}<br /> &nbsp; &nbsp;i = {"interfaces"; (&gt;[/interface/print])}<br /> &nbsp; &nbsp;v = {"vlans"; (&gt;[/interface/vlan/print])}<br /> &nbsp; &nbsp;b = {"bridge"; {<br /> &nbsp; &nbsp; &nbsp; &nbsp;"E" = {"export"; (&gt;[/interface/bridge/export])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;v = {"vlans"; (&gt;[/interface/bridge/vlan/print])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;p = {"ports"; (&gt;[/interface/bridge/port/print])}<br /> &nbsp; &nbsp;}}<br /> &nbsp; &nbsp;r = {"board"; (&gt;[/system/routerboard/print])}<br /> &nbsp; &nbsp;l = {"lte mon"; (&gt;[/interface/lte/monitor [find]])}<br /> &nbsp; &nbsp;e = {"export"; {<br /> &nbsp; &nbsp; &nbsp; &nbsp;f = {"file"; (&gt;[:export file=[/terminal/ask prompt="  \1B[1;33m?\1B[0m file name:"]])}<br /> &nbsp; &nbsp; &nbsp; &nbsp;p = {"print"; (&gt;[:export])}<br /> &nbsp; &nbsp;}}<br /> &nbsp; &nbsp;"`" = {"edit macros"; (&gt;[{/system/script/edit qkeys source; (&gt;[/system/script/run qkeys])}])}<br /> &nbsp; &nbsp;"C" = {"clear"; (&gt;[:put "\r\1Bc"])}<br />}<br /><br />:set qkeys do={<br /> &nbsp; &nbsp;:global qkeys<br /> &nbsp; &nbsp;:global qkeysmap<br /> &nbsp; &nbsp;:local loop true<br /> &nbsp; &nbsp;:local currmap $qkeysmap<br /> &nbsp; &nbsp;:local currpath ""<br /> &nbsp; &nbsp;:local printHeader do={<br /> &nbsp; &nbsp; &nbsp; &nbsp;:local cmds "\1B[1;36m$currpath &gt;\1B[0m"<br /> &nbsp; &nbsp; &nbsp; &nbsp;:foreach k,v in=($currmap, {q={"quit"}}, {"/"={"top"}}) do={<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:set cmds "$cmds &nbsp;\1B[1;32m($[:tostr $k]) \1B[2;39m$[:tostr ($v-&gt;0)] \1B[0m"<br /> &nbsp; &nbsp; &nbsp; &nbsp;}<br /> &nbsp; &nbsp; &nbsp; &nbsp;:put $cmds<br /> &nbsp; &nbsp;}<br /> &nbsp; &nbsp;:while (loop) do={<br /> &nbsp; &nbsp; &nbsp; &nbsp;# нормализуем имя, чтобы у всех ключей меню было название<br /> &nbsp; &nbsp; &nbsp; &nbsp;:foreach k,v in=$currmap do={<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:if ([:typeof $v]="op") do={<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:set ($currmap-&gt;$k) {"($[:pick [:tostr $v] 10 30])"; $v}<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br /> &nbsp; &nbsp; &nbsp; &nbsp;}<br /> &nbsp; &nbsp; &nbsp; &nbsp;$printHeader currmap=$currmap currpath=$currpath<br /><br /> &nbsp; &nbsp; &nbsp; &nbsp;# получаем нажатую клавишу<br /> &nbsp; &nbsp; &nbsp; &nbsp;:local kcode [/terminal/inkey]<br /> &nbsp; &nbsp; &nbsp; &nbsp;:local key ([:convert to=raw from=byte-array {$kcode}])<br /><br /> &nbsp; &nbsp; &nbsp; &nbsp;# ищем в текущем меню<br /> &nbsp; &nbsp; &nbsp; &nbsp;:local currval ($currmap-&gt;$key)<br /> &nbsp; &nbsp; &nbsp; &nbsp;:if ([:typeof $currval]!="nil") do={<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:local currname ($currval-&gt;0)<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:local currdata ($currval-&gt;1)<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:local currtype [:typeof $currdata]<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# нашли вложенный массив (следующий уровень меню)<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:if ($currtype="array") do={<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:set currpath "$currpath \1B[1;36m&gt; $currname\1B[0m"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:set currmap $currdata<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# нашли функцию (op) для запуска<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:if ($currtype="op") do={<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:put "$currpath \1B[1;31m&gt; $currname\1B[0m"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:local rv [$currdata]<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:put "\t# \1B[2;35m$[:pick [:tostr $rv] 0 64]\1B[0m"<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br /> &nbsp; &nbsp; &nbsp; &nbsp;} else={<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# клавиша не найдена в текущем меню<br /> &nbsp; &nbsp; &nbsp; &nbsp;}<br /> &nbsp; &nbsp; &nbsp; &nbsp;# если нажали «q» — выходим<br /> &nbsp; &nbsp; &nbsp; &nbsp;:if ($key~"(q|Q)") do={ :set loop false }<br /> &nbsp; &nbsp; &nbsp; &nbsp;# если нажали «/» — возвращаемся в главное меню<br /> &nbsp; &nbsp; &nbsp; &nbsp;:if ($kcode=47) do={ :set currmap $qkeysmap; :set currpath "" }<br /> &nbsp; &nbsp;}<br /> &nbsp; &nbsp;:return [:nothing]<br />}<br /><br />Если сохранить скрипт в /system/script под именем “qkeys”, в верхнем меню можно редактировать его, нажав на ` (обратную кавычку). Тогда будет подсветка синтаксиса, что помогает быстрее заметить ошибки при правке массива. Если хотите, чтобы макросы сохранялись, добавьте расписание, вызывающее скрипт qkeys при запуске роутера. Запускается всё просто — сперва запускаете скрипт qkeys, а потом вводите $qkeys в CLI.<br /><br /><img class="lazyload "  src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-src="/upload/forum/mikrotik/39379725af4f3fb33cfb3bdcdb2afbd6ff895918.png" alt="Пользователь добавил изображение" border="0" /><br /><br />Тут же есть связанная функция «TUI» — $INQUIRE и $CHOICES, которую я писал немного раньше, используя тип «op»: <noindex><a href="http://forum.mikrotik.com/t/inquire-prompt-user-for-input-using-arrays-choices-qkeys/167956/1" target="_blank" rel="nofollow" >http://forum.mikrotik.com/t/inquire-prompt-user-for-input-using-arrays-choices-qkeys/167956/1</a></noindex> <br />
			<i>17.06.2024 13:18:00, Amm0.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388974</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388974</guid>
			<pubDate>Mon, 17 Jun 2024 13:18:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388973">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			/console/inspect всегда рассказывает кое-что про скриптинг. Так, по поводу синтаксиса (&gt; )… Mikrotik действительно использует термин LISP «quote»… &nbsp;<br />/console/inspect request=completion input="(" &nbsp;<br />TYPE &nbsp; &nbsp; &nbsp; &nbsp;COMPLETION &nbsp;STYLE &nbsp; &nbsp; &nbsp; &nbsp;OFFSET &nbsp;PREFERENCE &nbsp;SHOW &nbsp;TEXT &nbsp;<br />completion &nbsp;( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; 1 &nbsp;75 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;нет &nbsp; &nbsp;начало подвыражения &nbsp;<br />completion &nbsp;$ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; 1 &nbsp;75 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;нет &nbsp; &nbsp;подстановка &nbsp;<br />completion &nbsp;[           syntax-meta       1  75          нет    начало подстановки команды  <br />completion &nbsp;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; 1 &nbsp;75 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;нет &nbsp; &nbsp;начало значения массива … &nbsp;<br />completion &nbsp;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; 1 &nbsp;75 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;нет &nbsp; &nbsp;&gt; quote &gt; &nbsp;<br />completion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;syntax-meta &nbsp; &nbsp; &nbsp; 1 &nbsp;75 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;нет &nbsp; &nbsp;quote &nbsp;<br />completion &nbsp; &nbsp; &nbsp; none &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp;-1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;нет &nbsp; &nbsp;буквальное значение, состоящее только из цифр, букв и символов ._ &nbsp;<br /><br />А по оператору &lt;%% — это термин «activate in environment»: &nbsp;<br />/console/inspect request=completion input="(\$fn &lt;" &nbsp;<br />Колонки: TYPE, COMPLETION, STYLE, OFFSET, PREFERENCE, SHOW, TEXT &nbsp;<br />TYPE &nbsp; &nbsp; &nbsp; &nbsp;COMPLETION &nbsp;STYLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OFFSET &nbsp;PR &nbsp;SHOW &nbsp;TEXT &nbsp;<br />#… completion &nbsp;&lt;%% &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp;75 &nbsp;нет &nbsp; &gt; activate in environment &gt; &gt; &nbsp;<br />completion &nbsp;( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;75 &nbsp;нет &nbsp; &nbsp;начало подвыражения &nbsp;<br />completion &nbsp;$ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;75 &nbsp;нет &nbsp; &nbsp;подстановка &nbsp;<br />completion &nbsp;[           syntax-meta              6  75  нет    начало подстановки команды  <br />completion &nbsp;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;75 &nbsp;нет &nbsp; &nbsp;начало значения массива &nbsp;<br />completion &nbsp;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syntax-meta &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;75 &nbsp;нет &nbsp; &nbsp;quote &nbsp;<br />completion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;syntax-meta &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp;75 &nbsp;нет &nbsp; &nbsp;quote &nbsp;<br />completion &nbsp;fn &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;variable-parameter &nbsp; &nbsp; &nbsp; 6 &nbsp;96 &nbsp;да &nbsp; &nbsp;… &nbsp;<br /><br />Например, с помощью «activate in environment» &lt;%% можно строить цепочки вызовов функций: &nbsp;<br />:global add do={ ($1 + 1) } &nbsp;<br />:put ($add &lt;%% $add &lt;%% $add &lt;%% $add &lt;%% $add &lt;%% {0}) &nbsp;<br />;5 &nbsp;<br /><br />И опять же, было бы в 1000 раз полезнее, если бы сами команды роутера, а не только пользовательские функции, принимали массивы как аргументы. Ведь всё тут — это список (или «массив»), включая «код». Здесь :put рассказывает ещё одну часть истории скриптинга. &nbsp;<br /><br />:global fn do={:put "$1 $2"} &nbsp;<br />:put $fn &nbsp;<br /> &nbsp; &nbsp;# вывод: &nbsp; &nbsp; &nbsp;;(evl (evl /putmessage=(. $1 &nbsp; $2))) &nbsp;<br />:put [:typeof $fn]  <br /> &nbsp; &nbsp;# вывод: &nbsp; &nbsp; &nbsp;array &nbsp;<br />:put [:len $fn]  <br /> &nbsp; &nbsp;# вывод: &nbsp; &nbsp; &nbsp;2 &nbsp;<br />:put [:typeof ($fn-&gt;1)]  <br /> &nbsp; &nbsp;# вывод: &nbsp; &nbsp; &nbsp;code &nbsp;<br /><br />А :put показывает эффект оператора (&gt;""): это «code»-тип и печатается, потому что оператор «quote» (&gt;) заставляет операцию объединения строк «пропускать» исполнение, в то время как добавление вызывает выполнение типа «code»: &nbsp;<br /><br />:put (&gt;"text $1") &nbsp;<br /> &nbsp; &nbsp;# вывод: &nbsp; &nbsp; (. text &nbsp;$1) &nbsp;<br />:put [(&gt;"text $1")]  <br /> &nbsp; &nbsp;# вывод: &nbsp; &nbsp; text &nbsp;<br /><br />Для другого примера с :put, чтобы понять, что происходит… Тут есть функция, и хоть она и не используется в скрипте, &lt;%%, похоже, является «примитивом» в типе кода: &nbsp;<br /><br />:global fn do={:global fn; $fn} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />:put $fn &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# вывод: &nbsp; &nbsp; &nbsp;;(evl (evl /globalname=$fn) (&lt;%% $fn (&gt; $fn))) &nbsp;<br /><br />:global fn do={:global fn; [$fn]}                      <br />:put $fn &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# вывод: &nbsp; &nbsp; &nbsp;;(evl (&lt;%% (evl (evl /globalname=$fn);(&lt;%% $fn (&gt; $fn))) )) &nbsp;<br /><br />И трилогия «секретов скриптинга» кроется в: &nbsp;<br />/environment/print — где показываются распарсенные :global переменные. Это всё забавные фишки… но я бы не рекомендовал использовать их в тех скриптах, «которые не должны давать сбой», ведь &lt;%% или &gt;[ в будущем могут просто убрать из какой-то схемы, показанной в /console/inspect, которая их сейчас поддерживает. <br />
			<i>14.06.2024 17:00:00, Amm0.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388973</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388973</guid>
			<pubDate>Fri, 14 Jun 2024 17:00:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388972">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Меня интересуют все секреты Mikrotik! <br />
			<i>14.06.2024 11:41:00, Sertik.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388972</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388972</guid>
			<pubDate>Fri, 14 Jun 2024 11:41:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388971">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Лучше проще. В конце концов, мы всё же говорим о роутере, а не о языке программирования для разработки кто знает какого приложения. <br />
			<i>14.06.2024 07:43:00, rextended.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388971</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388971</guid>
			<pubDate>Fri, 14 Jun 2024 07:43:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388970">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Нам нужны примеры оправданного и эффективного использования (&gt;[]) и (&lt;%%) <br />
			<i>14.06.2024 07:37:00, Sertik.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388970</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388970</guid>
			<pubDate>Fri, 14 Jun 2024 07:37:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388969">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			То есть, в массив можно поместить как данные, так и исполняемый код. Это известно уже давно. На самом деле оказывается, что всё можно уместить в одну структуру. <br />
			<i>14.06.2024 07:28:00, Sertik.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388969</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388969</guid>
			<pubDate>Fri, 14 Jun 2024 07:28:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388968">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Массив (см. мои предыдущие посты) всегда упорядочен так: сначала неназванные значения, упорядоченные по числу, затем именованные значения, упорядоченные по имени… поэтому {z=1;m=13;a=1} внутри упорядочены как {a=1;m=13;z=1}, но (“z”,“m”,“a”) на самом деле соответствуют -&gt;0=“z”, -&gt;1=“m” и -&gt;2=“a”, так что вот почему их считают неупорядоченными. Вот почему :put {“k”;“Name2”=“blah”;“~”=“last”;7=“j”;5;“z”;“name1”=“blah”;“!”=“first”} выводится как k;5;z;!=first;7=j;Name2=blah;name1=blah;~=last — неименованные значения остаются в исходном порядке, а именованные сортируются по ASCII. Ещё если добавить 20-й элемент, все пропущенные значения с 3 по 18 будут добавлены (пустые): &nbsp;<br />:local xtest {“k”;“Name2”=“blah”;“~”=“last”;7=“j”;5;“z”;“name1”=“blah”;“!”=“first”} &nbsp;<br />:set ($xtest-&gt;19) “tw” &nbsp;<br />:put $xtest &nbsp;<br />результат: k;5;z;;;;;;;;;;;;;;;;;tw;!=first;7=j;Name2=blah;name1=blah;~=last<br /><br />С этими примерами можно делать всё более сложные и интересные вещи… &nbsp;<br /><br />:global allMyFunctionsAndVariables [:toarray “”]  <br />:set ($allMyFunctionsAndVariables-&gt;“!!help”) do={ &nbsp;<br />:put “$[:typeof $0] 0=&gt;$0&lt;”  <br />:put “вы вызвали allMyFunctionsAndVariables напрямую…” &nbsp;<br />:put “немного помощи здесь…” &nbsp;<br />:return [:nothing]  <br />} &nbsp;<br />:set ($allMyFunctionsAndVariables-&gt;“testfunc”) do={ &nbsp;<br />:put “$[:typeof $0] 0=&gt;$0&lt;”  <br />:put “$[:typeof $1] 1=&gt;$1&lt;”  <br />:put “$[:typeof $2] 2=&gt;$2&lt;”  <br />:put “$[:typeof $3] 3=&gt;$3&lt;”  <br />:put “$[:typeof $4] 4=&gt;$4&lt;”  <br />:put “$[:typeof $5] 5=&gt;$5&lt;”  <br />:put “$[:typeof $6] 6=&gt;$6&lt;”  <br />:return [:nothing]  <br />} &nbsp;<br />:set ($allMyFunctionsAndVariables-&gt;“somenumber”) 77 &nbsp;<br />:set ($allMyFunctionsAndVariables-&gt;3) “:put 999” &nbsp;<br /><br />$allMyFunctionsAndVariables ($allMyFunctionsAndVariables-&gt;“testfunc”) &nbsp;5 4 3 &nbsp;<br />:put ($allMyFunctionsAndVariables-&gt;“somenumber”) &nbsp;<br />[:parse ($allMyFunctionsAndVariables-&gt;3)] <br />
			<i>13.06.2024 20:22:00, rextended.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388968</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388968</guid>
			<pubDate>Thu, 13 Jun 2024 20:22:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388967">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Не могу поверить, что раньше не замечал этого, хотя сам из целевой аудитории. Отличная находка. Некоторые ребята заметили тип (&gt; ) «op» некоторое время назад (возможно, именно здесь?). Но &lt;%% для меня новинка. Самый простой пример из ваших двух находок (&gt;[]) и (&lt;%%) вероятно такой:  <br />:global x (&gt;[:put "$0 $1 $2 $3 $named"])  <br />($x &lt;%% {1;2;3;4;named="blah"}) 1 2 3 4 blah &nbsp;<br /><br />Или, в основном для @rextended, порядок массива не важен — либо “безымянные” элементы используют $0 $1, а «именованные» (кортежи) не имеют $, потому что у них $name: &nbsp;<br />($x &lt;%% {1;named="blah";2;3;4}) 1 2 3 4 blah &nbsp;<br />Тот же порядок, что и выше… &nbsp;<br /><br />Если хотите углубиться, есть тема “Positional Arguments in Array Function - $0 vs $1 ?”: <noindex><a href="http://forum.mikrotik.com/t/positional-arguments-in-array-function-0-vs-1/154024/1" target="_blank" rel="nofollow" >http://forum.mikrotik.com/t/positional-arguments-in-array-function-0-vs-1/154024/1</a></noindex> &nbsp;<br /><br />Еще одна странность — любые массивы с ключ-значение сортируются по алфавиту, не знаю почему, возможно, из-за парсинга “s-выражений” (см. ниже): &nbsp;<br />:put {z=1;m=13;a=1} a=1;m=13;z=1 &nbsp;<br />В то время как обычные списки остаются упорядоченными: &nbsp;<br />:put ("z","m","a") z;m;a &nbsp;<br /><br />Если вы знакомы с LISP, скрипты RouterOS становятся понятнее: всё — это список, включая код. S-выражения из “:put” — это, можно сказать, главный признак. CLI и скрипты парсятся в S-выражения (с :global, превращающимся в переменные окружения для поведения, похожего на shell). В /console/inspect можно увидеть формируемое разрешенное AST для парсинга. &nbsp;<br /><br />На мой взгляд, &lt;%% должен просто работать с существующим оператором точка (.), если идти по этому пути. Он уже реализован, только не разрешён с функциями — вместо этого это просто путаница, когда пытаешься использовать . для конкатенации строк с типом массива. &nbsp;<br /><br />Понимаю, почему Mikrotik не документирует это и вряд ли будет. Это ниша, и только горстка пользователей найдёт практическое применение. Я даже не утверждаю, что у меня есть такое применение. Но это ещё один своеобразный инструмент для написания интересных скриптов, и меня радуют открывающиеся возможности. &nbsp;<br /><br />На сегодня команда RouterOS не принимает массив в виде аргументов — для «языка конфигурации», который поддерживает богатую работу со списками и массивами, невозможность использовать массив параметров для /ip/address или чего-то подобного — немного смешно… &nbsp;<br /><br />Это всегда меня раздражало. Т.е. с чисто теоретической точки зрения командe не должна требоваться [:parse], чтобы принимать массив: команды должны быть полноценными функциями для скриптинга. Я так и не понял, как избежать [:parse] в таких случаях. Используя :parse, ты вынужден возиться с экранированием и теряешь проверку синтаксиса — а это совсем не идеально.  <br /><br />Я думал, возможно, какой-то приём с этим “&lt;%%” сработает. Но не смог придумать, как сделать, в идеале, такое: &nbsp;<br />:global ipAddrSettings {numbers="*56;comment="blah"} &nbsp;<br />/ip/address/set &lt;%% $ipAddrSettings &nbsp;<br /><br />Но это не работает… Пытался и другие варианты с обёртками, порядком и так далее. &nbsp;<br /><br />Отсутствие этого усложняет написание более простых скриптов дефолтных конфигураций — ведь хотелось бы просто прокинуть массив в /ip/address/set (или куда угодно) и не расписывать вручную каждый параметр для каждой команды в дефолтном конфиге. <br />
			<i>13.06.2024 18:24:00, Amm0.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388967</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388967</guid>
			<pubDate>Thu, 13 Jun 2024 18:24:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388966">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			:global inc (&gt;[:set $counter ($counter+1)]) :global c {counter=0} :put ($inc &lt;%% $c) :put $c counter=1 ! <br />
			<i>13.06.2024 15:05:00, Sertik.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388966</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388966</guid>
			<pubDate>Thu, 13 Jun 2024 15:05:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388965">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			:global f1 do={:return 5} &nbsp;<br />:global f2 do={:return 7} &nbsp;<br />:global add (&gt;[:return ([$f1]+[$f2])])  <br />:put ($add &lt;%% {$f1;$f2}) 12 &nbsp;<br /><br />:global f1 do={:return $1} &nbsp;<br />:global f2 do={:return $1} &nbsp;<br />:global add (&gt;[:return ([$f1 2]+[$f2 3])])  <br />:put ($add &lt;%% {$f1;$f2}) 5 &nbsp;<br /><br />:global f1 do={:return [/system clock get time]}  <br />:global f2 do={:return [/system clock get date]}  <br />:global add (&gt;[:return ([$f1]." ".[$f2])])  <br />:put ($add &lt;%% {$f1;$f2}) 17:37:48 jun/13/2024 &nbsp;<br /><br />:global f1 do={:return [/system clock get time]}  <br />:global f2 do={:return [/system clock get date]}  <br />:global add1 (&gt;[:return ([$f1]." “.[$f2])])  <br />:global add2 (&gt;[:return ([$f2].” ".[$f1])])  <br />:put ($add1 &lt;%% {$f1;$f2}) &nbsp;<br />:put ($add2 &lt;%% {$f2;$f1}) &nbsp;<br />17:46:31 jun/13/2024 &nbsp;<br />jun/13/2024 17:46:32 &nbsp;<br /><br />Очень интересно! <br />
			<i>13.06.2024 14:33:00, Sertik.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388965</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388965</guid>
			<pubDate>Thu, 13 Jun 2024 14:33:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388964">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Извиняюсь за задержку, я не заметил этот пост раньше, отличная работа, спасибо. <br />
			<i>11.06.2024 06:57:00, rextended.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388964</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388964</guid>
			<pubDate>Tue, 11 Jun 2024 06:57:00 -0400</pubDate>
			<category>RouterOS</category>
		</item>
		<item>
			<title>Несколько неофициальных операторов, которые довольно забавные.</title>
			<description><![CDATA[<b><a href="http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388963">Несколько неофициальных операторов, которые довольно забавные.</a></b> <i>RouterOS</i> в форуме <a href="http://mikrotik.moscow/forum/forum57/">RouterOS</a>. <br />
			Этот пост будет интересен только ограниченному кругу людей. Если вы не знакомы со скриптингом Mikrotik или никогда не использовали функции, то, скорее всего, это сообщение не для вас, но всё равно можете почитать.<br /><br />Я рассмотрю два оператора, которые нашёл, нажав F1, находясь в скобках. Первый оператор называется quote. Это унарный оператор ‘&gt;’, который работает точно так же, как quote в LISP, если кто-то знаком с этим. Он возвращает то, к чему применяется, как литерал. Даже код. Это значит, что его можно использовать как альтернативный способ создания функций.<br /><br />Вот все три способа создания функции, которые я знаю, включая этот новый оператор в действии: &nbsp;<br />:global func1 do={:put "test1"} &nbsp;<br />:global func2 [parse ":put \"test2\""]  <br />:global func3 (&gt;[:put "test3"])  <br /><br />Интересно, что все три метода дают немного разные результаты. Вот что вы получаете, если вывести их все: &nbsp;<br />put $func1 &nbsp;<br /># ;(evl (evl /putmessage=test1)) &nbsp;<br />put $func2 &nbsp;<br /># (evl /putmessage=test2) &nbsp;<br />put $func3 &nbsp;<br /># (evl (evl /putmessage=test3)) &nbsp;<br /><br />func1 — это массив из 2 элементов, где второй — это объект кода. Два других — сами объекты кода. Если вы не понимаете, о чём речь, попробуйте применить typeof к ним. Практически все они обрабатываются одинаково, и не имеет значения, какой способ вы используете для создания функций. Технически parse даёт небольшое повышение производительности и занимает чуть меньше памяти, потому что нет лишних evl и массивов, но это, скорее всего, не имеет значения для большинства задач.<br /><br />Я точно ещё не полностью изучил возможности этого оператора, например, не пробовал использовать его со строкой, в которой есть вставки команд — это может быть интересно. Но я двигаюсь дальше.<br /><br />Следующий оператор, о котором я расскажу, называется «activate in environment». Я впервые наткнулся на него в июне прошлого года, когда коллега оставил о нём пост на форуме, и даже rextended был сбит с толку, так что я отложил это. Но теперь я наконец разгадал его, и мне кажется, что он довольно крутой.<br /><br />Оператор выглядит так: &lt;%%. Он требует небольшого объяснения. Под «окружением» здесь понимается просто «набор доступных переменных». Этот оператор запускает объект кода слева с добавлением массива справа в его окружение.<br /><br />Например, допустим, вы создаёте следующую функцию: &nbsp;<br />:global add (&gt;[:return ($0+$1)])  <br /># Теперь её можно вызвать так, чтобы вывести 3 &nbsp;<br />:put [$add 1 2]  <br /># Чтобы использовать новый оператор с тем же результатом, делаем так: &nbsp;<br />:put ($add &lt;%% {1;2})<br /><br />Правка: использовать скобки здесь не получится, потому что $0 — имя функции. Надо использовать $1+$2, и окружение, переданное в &lt;%%, было бы {“add”;1;2} для эквивалентности.<br /><br />Если вы внимательно посмотрели, то заметили, что содержимое массива обращается через $0 и $1. Массив, который передаётся, становится окружением (набором переменных) для функции, так что нулевой элемент доступен через $0, первый — через $1.<br /><br />Сам по себе этот приём не очень мощный, так что давайте посмотрим на другой пример: &nbsp;<br />:global f (&gt;[:put $output])  <br /># Мы нигде не определяли output. Его нет. И всё же: &nbsp;<br />($f &lt;%% {output="Я существую!"}) &nbsp;<br /># Это добавит переменную output из массива в окружение, позволяя функции получить к ней доступ &nbsp;<br /># Сейчас это всё равно что &nbsp;<br />[$f output="Я существую!"]<br /><br />Это гораздо интереснее! Мы можем создавать объекты, которые инкапсулируют параметры функции, и передавать их функции. Уверен, это уже вызывает у некоторых идеи. Но если вам это понравилось, у меня есть пример, который вас точно удивит.<br /><br />Что если я скажу, что массив, который вы передаёте, передаётся по ссылке? &nbsp;<br />:global inc (&gt;[:set $counter ($counter+1)])  <br />:global c {counter=0} &nbsp;<br /># Что, как вы думаете, произойдёт здесь? &nbsp;<br />($inc &lt;%% $c) &nbsp;<br /># Здесь уже нет эквивалента с использованием скобок &nbsp;<br /># Это уже НЕ эквивалент &nbsp;<br />[$inc $c]<br /><br />Поверьте или нет, это работает именно так, как вы думаете. Выведите значение $c после этого — увидите, что counter действительно увеличился до 1. Теперь мы можем передавать объект (массив), работать с его переменными и сохранять изменения. Это новая функциональность, уникальная для этого оператора. Это почти как объектно-ориентированное программирование, хотя и не настолько мощное.<br /><br />Я понимаю, почему Mikrotik не документирует эту возможность и не ожидаю, что так будет в будущем. Это нишевая функция, и лишь немногие пользователи смогут найти для неё полезное применение. Я даже не утверждаю, что у меня оно есть. Но это ещё один интересный инструмент для написания нестандартных скриптов, и я с нетерпением жду, какие возможности он откроет. <br />
			<i>13.01.2023 16:14:00, GreenDog72.</i>]]></description>
			<link>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388963</link>
			<guid>http://mikrotik.moscow/forum/forum57/84672-neskolko-neofitsialnykh-operatorov_-kotorye-dovolno-zabavnye./message388963</guid>
			<pubDate>Fri, 13 Jan 2023 16:14:00 -0500</pubDate>
			<category>RouterOS</category>
		</item>
	</channel>
</rss>
