Уроки AppleScript
Изучение AppleScript — часть 4
Делаем скрипты читабельными, надежными и пригодными для повторного использования
Скрипты становятся более надежными, если мы ждем завершения операций, они становятся более пригодными для повторного использования и читабельными, если мы используем функции. При этом мы хотим избежать некоторых неожиданных ловушек.

Весь код, показанный в этой статье, доступен через связанный репозиторий GitHub.
Ранее на…
В предыдущих частях мы сосредоточились на создании коротких скриптов, которые могли бы служить инструментами, и на изучении некоторых поставляемых инструментов, которые могли бы помочь нам изучить AppleScript. В этом эпизоде мы сосредоточимся на написании более надежного, многократно используемого и читабельного сценария.
Ранее мы создали этот скрипт:

Надежность
Первое, что я хочу сделать, это сделать его более надежным. Как написано, вполне возможно, что этот скрипт попытается щелкнуть переключатель Scaled до того, как отобразится правильная панель Systems Preferences и вкладка. Было бы лучше, если бы мы проверили наличие ожидаемого элемента пользовательского интерфейса. Глагол exists, определенный в Standard Suite из System Preferences, сделает именно это.

Проблема в том, что нам нужно многократно вызывать exists, пока окно не появится. Один из самых простых способов сделать это — использовать оператор repeat until, как показано ниже:

Я использовал свое имя окна здесь. Вам нужно будет заменить имя окна, если вы не хотите ждать вечно. Если вы устали ждать вечно, вспомните эту кнопку Stop на панели инструментов. Такой подход может быть приемлемым, но в зависимости от того, как выполняется сценарий, может быть неудобно ждать вечно. Мы также можем подождать определенное время с помощью команды delay. Мы можем объединить два подхода и немного подождать, а затем сдаться. Помимо того, что это быстрее, чем вечное ожидание, мы можем изучить и использовать оператор exit. Ниже мы задерживаемся в каждом цикле повторения, но сдаемся после заданного количества попыток. Обратите внимание, что я изменил имя окна, которое я жду, на окно, которое не существует в моей системе, чтобы убедиться, что код выхода работает. Я верну это обратно в последующих сценариях.

Возможность повторного использования с помощью обработчика (также известного как функция)
Со всем этим добавленным встроенным кодом мы начинаем запутывать основную логику нашего скрипта. Давайте немного рефакторим наш код, чтобы сделать его более читабельным и простым в обслуживании.
Я воспользуюсь наивным подходом и перенесу код ожидания прямо в функцию, также известную как handler. Я специально использую обработчик с позиционным параметром. На изображении ниже я создал обработчик с именем waitFor(), который принимает имя окна для ожидания.

Обратите внимание, что в основном скрипте я вызываю свой обработчик в блоке сообщения. Я использую ключевое слово my перед именем моего обработчика, иначе сценарий подумает, что я пытаюсь вызвать (несуществующий) waitFor() для System Preferences, который является целью моего внутреннего блока сообщения.
Добавление возвращаемых значений
Этот код работает, потому что он может щелкнуть кнопку Scaled, но не находит окно так, как мы ожидаем. Мы можем добавить возвращаемое значение в обработчик, чтобы доказать, что это так. В приведенном ниже коде я выделил изменения, чтобы показать, что я возвращаю false, если я достиг предела счетчика, и true в противном случае. В основном скрипте я фиксирую результат waitFor и регистрирую его. На панели Messages мы видим, что возвращается false.

Что случилось?
Почему этот код работал, когда был в основном скрипте, но не работал, когда мы переместили его в обработчик? Проблема связана с целью основного скрипта tell. waitFor фактически потерял из виду тот факт, что использовал System Preferences. К счастью, в AppleScript есть ключевые слова это и я. Мы можем передать it нашей функции, чтобы отслеживать текущую цель. В приведенном ниже коде мы теперь передаем it, и получаем его как параметр с именем target. (Шаги 1 и 2). Был добавлен блок сообщения с использованием нашего нового параметра target (шаг 3). Код внутри блока tell target/end tell не изменился.

Попробуйте оператор управления
AppleScript предоставляет оператор управления попыткой для обработки непредвиденных ошибок, и мы можем добавить его, чтобы сделать нашу окончательную функцию немного более надежной. Нам нужно обернуть интересующий код в блок a try/end try (показан стрелками) и добавить раздел об ошибках для обработки всего, что пойдет не так (показано рамкой).

Следующий
Я начал это путешествие по AppleScript, потому что пытался решить конкретную проблему. В следующей статье мы, наконец, создадим полный сценарий для решения этой проблемы и воспользуемся многими методами, которые мы изучили до сих пор.
Смотрите обзор всех статей (на данный момент) в этой серии.
Спасибо за прочтение и кодируйте спокойно.