Две переменные в AppleScript, как и в Python, могут иметь одинаковое значение. Каждая переменная имеет ссылку на свое значение, но слово «ссылка» имеет другое значение. Строка "https://stackoverflow.com/"
является ссылкой на веб-сайт; целое число 42
является ссылкой на работы Дугласа Адамса; и объект класса reference
в AppleScript - это другой тип ссылки.
Объект класса reference
откладывает доступ к элементу или свойству какого-либо объекта. Это почти как лямбда в Python, потому что AppleScript
set v to {11, 22, 33}
set r to a reference to item 2 of v
действует как Питон
v = [11, 22, 33]
r = lambda: v[1]
, отложив доступ ко 2-му пункту списка. Тогда contents of r
в AppleScript или r()
в Python получит элемент. AppleScript также может установить элемент с помощью set contents of r to 99
; Python не может установить элемент с помощью этой лямбды. Лямбда Python может делать много вещей, которые не могут делать ссылки AppleScript.
a reference to
оператор
Руководство по языку AppleScript описывает оператор a reference to
, но пропускает некоторые важные детали . Оператор имеет один операнд; компилятор также принимает reference OPERAND
или ref OPERAND
, а затем переписывает их как a reference to OPERAND
.
Если операнд является выражением вида A of B
или B's A
, то оператор переносит выражение в объект класса reference
. Это выражение может быть элементом, например item 2 of q
, или свойством, например length of q
.
Если операнд является переменной, то оператор присоединяет неявный my
или of me
. Например, a reference to q
в обработчике запуска совпадает с a reference to my q
. Это сбивает с толку в областях, где q
и my q
отличаются.
Для других операндов оператор возвращает только операнд . Например, a reference to 3
возвращает 3, что не является объектом класса reference
.
Оператор фиксирует текущее значение переменных . Например, a reference to item i of q
фиксирует значения i и q. Для сравнения, a reference to q
не захватывает значение q, потому что оно совпадает с a reference to my q
, поэтому он видит q как свойство, а не переменную.
to demo()
set q to {11, 22, 33}
set rq to a reference to q
set i to 2
set ri to a reference to item i of q
set i to 3
set item 2 of q to 55
set q to {77, 88, 99}
{contents of rq, contents of ri}
end demo
set q to "a string"
demo()
Результатом этого сценария является {"строка", 55}. Ссылка rq игнорировала локальный q и использовала my q
из обработчика запуска. Ссылка ri захватывает локальные значения i и q, игнорирует последующие присвоения i и q, но не игнорирует присвоение элементу 2 из q.
Использование ссылок с большими списками
Руководство по языку AppleScript также содержит примеры использования оператора a reference to
для увеличения скорости доступа к большому списку. Guide использует
set bigListRef to a reference to bigList
, но не может объяснить, что ссылка неявно a reference to my bigList
, поэтому доступ осуществляется через объект сценария me
. Это работает только потому, что код находится в обработчике запуска, где bigList
и my bigList
- это один и тот же список.
Оказывается, доступ к большому списку происходит быстро, если ссылка проходит через какой-либо объект сценария. Другие доступы медленные. Следующий скрипт показывает это, создав список из 7000 элементов с использованием быстрого доступа, а затем прочитав список с использованием как медленного, так и быстрого доступа.
to bench(what)
set start to current date
repeat with i from 1 to 7000
if item i of what is not 42 then
error "wrong value"
end if
end repeat
(current date) - start
end bench
to bench2()
script box
property nums : {}
end script
repeat 7000 times
set end of box's nums to 42
end repeat
{bench(box's nums), bench(a reference to box's nums)}
end bench2
bench2()
Я запустил этот скрипт на моей старой машине под управлением PowerPC Mac OS X 10.4.11. Результат составил {19, 0}, поэтому медленный доступ занял 19 секунд, а быстрый - 0 секунд.
Линия set end of box's nums to 42
делает быстрый доступ без использования оператора a reference to
. Это быстро, потому что доступ осуществляется через box
, объект сценария.