Справочные объекты AppleScript - помогите мне понять их - PullRequest
3 голосов
/ 29 апреля 2011

Почему они вообще существуют? Это кажется абсурдным. Как и в большинстве динамических языков, типы AppleScript кажутся либо неизменяемыми примитивными типами, такими как integer s и real s, которые будут передаваться по значению и не имеют никакого смысла для использования с a reference to или объектом -подобные типы, такие как application s, script s или record s, которые уже передаются по ссылке. Как a reference to не является полностью избыточным? Вот пример, взятый из руководства AppleScript по языку Apple (http://developer.apple.com/library/mac/#documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html, если вы потеряли ссылку):

tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"

Так вы хотите сказать мне, что если я сделаю это вместо этого,

tell app "Finder" to set diskObj to startup disk
--result: startup disk of application "Finder"

что среда исполнения applecript отправит событие apple, отправленное процессу Finder, и скажет: «Эй, какой-то парень только что попросил вас вернуть мне поток октетов / dev / disc01! Ха-ха! Я думаю, он должен был попросить a reference to это! Давайте начнем! Это займет некоторое время! "

Я программирую на Python и делаю это:

m = fileHandle.read( 1000000000 ) #and then wait a little while
n = m 

Я только что скопировал данные в память? Конечно, нет. Но существование a reference to в AppleScript подразумевает, что присвоение объектов новым переменным является операцией по значению. И если это так, то в чем дело с командой copy?

Что здесь происходит?

ОБНОВЛЕНИЕ: Ну, просто посчитайте меня запутанным программистом Python. Просто чтобы сделать это немного яснее, я все еще думаю

tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"

- плохой пример (взято из путеводителя по appleScript). Но @ Chuck's пример a reference to самого свойства, содержащего примитивный тип, который затем может быть переназначен, является лучшим. IOW, объект reference на самом деле является переменной / свойством, которое содержит указатель на другую переменную или свойство.

Ответы [ 2 ]

3 голосов
/ 29 апреля 2011

Насколько я понимаю, вы можете рассматривать ссылки как указатели.

set x = 5
set y to reference to x
set contents of y to 10
log x -- 10

Как правило, вы не создаете ссылки вручную.Библиотеки и словари AppleScript могут возвращать их, но затем вы работаете со свойствами возвращаемого элемента (например, name of startup disk).

Честно говоря, я бы их проигнорировал.За двадцать лет работы с AppleScript мне, вероятно, приходилось искать документацию по ссылкам один раз.Если вы пытаетесь что-то сделать в AppleScript и считаете, что вам нужно создать ссылочную переменную, вы, вероятно, делаете это не самым простым способом.

Ознакомьтесь с этой статьей MacTech для более подробного обсуждения ссылок AppleScript.

1 голос
/ 24 октября 2017

Две переменные в 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, объект сценария.

...