Переменные и свойства

Переменные и свойства представлены в предыдущих главах в этом документе. Вы используете их в script объекты сохранить и управлять значениями.

Следующие разделы охватывают общие проблемы в работе с переменными и свойствами, включая то, как объявить их и как AppleScript интерпретирует их объем в сценарии:

Определение свойств

Метки свойства соблюдают правила, описанные в Идентификаторах.

Определения свойства используют следующий синтаксис:

property propertyLabel : выражение

propertyLabel

Идентификатор.

выражение

Выражение AppleScript, устанавливающее начальное значение для свойства. Определения свойства оценены перед переменными присвоениями, таким образом, определения свойства не могут содержать переменные.

Следующее является примерами допустимых определений свойства:

property windowCount : 0
property defaultName : "Barry"
property strangeValue : (pi * 7)^2

После определения свойства можно изменить его значение с copy или set команда.

Набор значений по определению свойства не сбрасывается каждый раз, когда сценарий выполняется; вместо этого, это сохраняется, пока сценарий не перекомпилирован.

Вы не можете объявить свойство в обработчике, но обработчик может получить доступ к свойству, определенному в его содержании script объект.

Объявление переменных

Имена переменной соблюдают правила, описанные в Идентификаторах.

Для создания переменной в AppleScript Вы присваиваете его значение с помощью copy или set команда. Например, следующие утверждения создают и инициализируют две переменные, один названный circumference и один названный savedResult:

set circumference to pi * 3.5 --result: 10.995574287564
copy circumference to savedResult --result: 10.995574287564 (copy of 1st variable)

Как показано в этом примере, переменное присвоение может использовать ранее определенную переменную. Это может также использовать свойства, объявленные в том же script объект.

Существуют некоторые очевидные, и некоторые более тонкие, различия в использовании copy и set для создания переменной — видят Используя копию и устанавливают Команды для получения дополнительной информации.

Если Вы присваиваете новое значение переменной, уже использующейся, это заменяет старое значение. Можно присвоить простое значение, выражение или объектный спецификатор — выражения оценены, и объектные спецификаторы разрешены для получения значения для присвоения. Создать переменную, значение которой является самим объектным спецификатором, а не значением указанного объекта, использование a reference to оператор.

Следующие два раздела описывают, как можно явно определить a local или a global переменная. Эти типы переменных отличаются прежде всего по их объему. Объем, относящийся туда, где переменная доступна в сценарии, описан подробно в пределах Переменных и Свойств.

Локальные переменные

Можно объявить явный local переменные с помощью следующего синтаксиса:

local variableName [, variableName] …

variableName

Идентификатор.

Следующее является примерами допустимых local объявления переменной:

local windowCount -- defines one variable
local agentName, agentNumber, agentHireDate -- defines three variables

Вы не можете присвоить начальное значение a local переменная в ее объявлении, и при этом Вы не можете объявить класс для переменной. Вместо этого Вы используете copy или set команда, чтобы инициализировать переменную и установить ее класс. Например:

set windowCount to 0 -- initialize to zero; an integer
set agentName to "James Smith" -- assign agent name; a text string
set agentNumber to getAgentNumber(agentName) -- call handler; an integer
copy current date to agentHireDate -- call current date command; a date

Глобальные переменные

Синтаксис для global переменные почти идентичны этому для local переменные:

global variableName [, variableName] …

variableName

Идентификатор.

Следующее является примерами допустимых global объявления переменной:

global gAgentCount
global gStatementDate, gNextAgentNumber

Как с local переменные, Вы используете copy или set команда для инициализации global переменные и набор их типы классов. Например:

set gAgentCount to getCurrentAgentCount() -- call handler to get count
set gStatementDate to current date -- get date from current date command
set gNextAgentNumber to getNextAvailNumber() -- call handler to get number

Используя копию и Команды набора

Когда Вы используете, поскольку его имя подразумевает copy команда для создания переменной это всегда создает отдельную копию (хотя примечание, что копия объектного спецификатора все еще указывает тот же объект). Однако, когда Вы используете set команда для создания переменной новая переменная всегда относится к исходному объекту или значению. Вы по существу создали другое имя для того же объекта.

Когда больше чем одна переменная отсылает к изменяемому (или непостоянный) объект, изменение в объекте заметно через любую из переменных. Типы объектов AppleScript, которые являются непостоянными, date, list, record, и script объекты.

Для объектов, которые не могут быть изменены (неизменные объекты), переменные, создаваемые с set команда может походить на копии — нет никакого способа изменить объект, на который указывают переменные, таким образом, они кажутся независимыми. Это продемонстрировано в примере в следующем разделе, создающем переменные myName и yourName.

Объявление Переменных с Командой набора

Можно использовать set команда для установки переменной в любой тип объекта. Если переменная не существует, она создается; если это действительно существует, его текущая стоимость заменяется:

set numClowns to 5 --result: 5
set myList to { 1, 2, "four" } --result: {1, 2, "four"}
tell application "TextEdit"
    set word1 to word 1 of front document --result: some word
end tell

Следующий пример использует непостоянный объект. Это создает две переменные, обращающиеся к тому же списку, затем изменяет список через одну из переменных:

set myList to { 1, 2, 3 }
set yourList to myList
set item 1 of myList to 4

После выполнения этих операторов, операторов item 1 of myList и item 1 of yourList оба дохода 4, потому что обе переменные обращаются к тому же списку.

Теперь предположите, что Вы работаете с неизменным объектом, таким как a text объект:

set myName to "Sheila"
set yourName to myName

Обе переменные относятся к тому же text объект, но text объекты не являются непостоянными, таким образом, нет никакого способа изменить значение myName таким образом, что это влияет на значение yourName. (При присвоении нового текста одной из переменных Вы просто создаете новое, отдельное text объект.)

set команда может присвоить несколько переменных сразу с помощью образца, который может быть списком или записью: список или запись переменных на одной стороне, и список или запись значений на другом. Значения являются соответствующими к переменным на основе их позиции для списка, или на основе их ключей для записи. Не наличие достаточного количества значений является ошибкой; если существует слишком много значений, дополнительные проигнорированы. Порядок, в котором значения оценены и переменные, присваивается, неуказанное, но все значения оценены, прежде чем любые присвоения сделаны.

Раздел Examples set команда показывает некоторые простые присвоения образца. Вот пример с более сложными образцами:

set x to {8, 94133, {firstName:"John", lastName:"Chapman"}}
set {p, q, r} to x
(* now p, q, and r have these values:
                p = 8
                q = 94133
                r = {firstName:"John", lastName:"Chapman"}  *)
set {p, q, {lastName:r}} to x
(* now p, q, and r have these values: p = 8
                                      q = 94133
                                      r = "Chapman" *)

В заключительном операторе присваивания выше, {lastName:r} запись, не использовавшаяся прежде в сценарии и содержащая элемент с меткой lastName и значение r (ранее определенная переменная). Переменная x был ранее установлен иметь запись, имеющую элемент с меткой lastName и значение "Chapman". Во время присвоения маркируется значение элемента lastName в новой записи установлен в значение маркированного элемента lastName в x— следовательно это теперь имеет значение "Chapman".

Как этот пример демонстрирует, свойства рекордной потребности не быть данным в том же порядке и не должен все использоваться при установке образца в образец, пока соответствие образцов. Для получения дополнительной информации посмотрите set команда.

Объявление Переменных с Командой копии

Можно использовать copy команда для установки переменной в любой тип объекта. Если переменная не существует, она создается; если это действительно существует, его текущая стоимость заменяется. copy команда создает новую копию, которая независима от оригинала — последующее изменение не изменяет исходное значение (хотя примечание, что копия объектного спецификатора все еще указывает тот же объект).

Для копирования в приложении необходимо использовать приложение duplicate команда, если это имеет тот. Для копирования между приложениями можно использовать get команда для получения информации из одного приложения и set команда для установки его в другом.

copy команда создает глубокую копию — т.е. при копировании вложенной структуры данных, такой как список, содержащий другой список, вся структура копируется, как показано в следующем примере. Этот пример создает запись (alpha), затем список (beta), затем список, содержащий первую запись и список (gamma), тогда наконец копия gamma (delta). Это тогда изменяет свойство в исходной записи, alpha. Результат показывает, что свойство изменяется везде, где alpha появляется, кроме копии, delta:

set alpha to {property1:10, property2:20}
set beta to {1, 2, "Hello"}
set gamma to {alpha, beta, "Goodbye"}
copy gamma to delta
set property1 of alpha to 42
 
{alpha, beta, gamma, delta}  -- List variables to show contents
(*result: {{property1:42, property2:20}, {1, 2, "Hello"}, {{property1:42, property2:20}, {1, 2, "Hello"}, "Goodbye"}, {{property1:10, property2:20}, {1, 2, "Hello"}, "Goodbye"}} *)

Если Вы делаете копию a reference объект, это именует тот же объект как оригинал (потому что оба содержат тот же объектный спецификатор):

set windowRef to a reference to window 1 of application "Finder"
name of windowRef --result: "Script testing folder"
copy windowRef to currentWindowRef --result: a new object specifier
name of currentWindowRef --result: "Script testing folder"

Объем переменных и свойств

Объявление переменной или идентификатора свойства является первым допустимым возникновением идентификатора в a script объект. Форма и расположение объявления определяют, как AppleScript обрабатывает идентификатор в этом script объект.

Объем является диапазоном, по которому AppleScript распознает заявленный идентификатор в a script объект. Объем переменной зависит от того, где Вы объявляете его и объявляете ли Вы его как global или local. Объем свойства расширяется на все script объект, в котором это объявляется. После объявления свойства можно снова использовать тот же идентификатор как отдельная переменная, только если Вы сначала объявляете его как a local переменная.

Время жизни относится к промежутку времени, за который переменная или свойство являются существующими. Только значения свойств и global переменные могут сохраниться после того, как сценарий выполняется.

В обсуждениях, следующих, объявления и операторы в a script объект, которые происходят за пределами любых обработчиков или вложенный script объекты идентифицируются как снаружи.

Следующие примеры показывают эти четыре канонических формы для объявления переменных и свойств в AppleScript:

Если Вы хотите использовать тот же идентификатор в нескольких различных местах в сценарии, необходимо или объявить его как свойство или как a global переменная.

Часто удобно ограничить объем определенного идентификатора к единственному обработчику или вложенный script объект, который можно сделать путем определения его как a local переменная в обработчике или script объект. Снаружи, идентификатор не имеет никакого значения, связанного с ним, и может быть снова использован в другом месте в сценарии. Когда используется этот путь, a local переменная сказана тени (или блокируйте доступ к), a global переменная или свойство с тем же именем, делая глобальную версию недоступной в пределах обработчика или script возразите где local переменная объявляется.

Следующие разделы предоставляют дополнительную информацию об объеме:

Объем свойств и переменных, заявленных в объекте сценария

Таблица 3-1 показывает объем и время жизни для переменных и свойств, объявляющихся на верхнем уровне в a script объект (вне любых обработчиков или вложенный script объекты).

Табличный 3-1  Объем свойства и объявлений переменной на верхнем уровне в объекте сценария

Тип объявления

Объем (видимость)

Время жизни

property x: 3

Везде в сценарии

Сброс, когда перекомпилирован сценарий

global x

Везде в сценарии

Сброс, когда повторно инициализировано в сценарии или когда перекомпилирован сценарий

local x

В run обработчик только

Сброс, когда выполняется сценарий

set x to 3

В run обработчик только

Сброс, когда выполняется сценарий

Объем свойства в a script объект расширяется на любые последующие операторы где угодно в сценарии. Рассмотрите следующий пример:

property currentCount : 0
increment()
 
on increment()
    set currentCount to currentCount + 1
    display dialog "Count is now " & currentCount  & "."
end increment

Когда это встречается с идентификатором currentCount где угодно в этом сценарии, AppleScript связывает его с currentCount свойство.

Значение свойства сохраняется после того, как сценарий, в котором определяется свойство, был выполнен. Таким образом, значение currentCount 0 в первый раз, когда этот сценарий выполняется, 1 в следующий раз, когда он выполняется и т.д. Текущая стоимость свойства сохраняется с script возразите и не будьте сброшены к 0, пока сценарий не будет перекомпилирован — т.е. изменен и затем выполнен снова, сохранен или проверен на синтаксис.

Значение a global переменная также сохраняется после того, как сценарий, в котором она определяется, был выполнен. Однако в зависимости от того, как это инициализируется, a global переменная может быть сброшена каждый раз, когда сценарий выполняется снова. Следующий пример показывает, как инициализировать a global переменная так, чтобы это было инициализировано только в первый раз сценарий, выполняется, и таким образом приводит к тому же результату как использование свойства в предыдущем примере:

global currentCount
increment()
 
on increment()
    try
        set currentCount to currentCount + 1
    on error
        set currentCount to 1
    end try
        display dialog "Count is now " & currentCount  & "."
end increment

В первый раз сценарий выполняется, оператор set currentCount to currentCount + 1 генерирует ошибку потому что global переменная currentCount не был инициализирован. Когда ошибка происходит, on error блок инициализирует currentCount. Когда сценарий выполняется снова, переменная была уже инициализирована, таким образом, ошибочное ответвление не выполняется, и переменная сохраняет свое предыдущее значение. Персистентность выполняется, но не так просто как в предыдущем примере.

Если Вы не хотите, чтобы значение, связанное с идентификатором, сохранилось после того, как сценарий выполняется, но Вы хотите использовать тот же идентификатор всюду по сценарию, объявить a global переменная и использование set команда для установки ее значения каждый раз сценарий выполняется:

global currentCount
set currentCount to 0
on increment()
    set currentCount to currentCount + 1
end increment
 
increment() --result: 1
increment() --result: 2

Каждый раз on increment обработчик вызывают в сценарии, global переменная currentCount увеличения 1. Однако, когда Вы выполняете весь сценарий снова, currentCount сбрасывается к 0.

В отсутствие a global объявление переменной, объем объявления переменной с помощью set команда обычно ограничивается run обработчик для сценария. Например, этот сценарий объявляет два отдельных currentCount переменные:

set currentCount to 10
on increment()
    set currentCount to 5
end increment
 
increment() --result: 5
currentCount --result: 10

Объем первого currentCount объявление переменной ограничивается run обработчик для сценария. Поскольку этот сценарий имеет не явный run обработчик, вне операторов часть его неявного run обработчик, как описано в выполненных Обработчиках. Объем второго currentCount объявление, в on increment обработчик, ограничивается тем обработчиком. AppleScript отслеживает каждую переменную независимо.

Связать переменную в обработчике с той же переменной, объявленной с set команда вне обработчика, можно использовать a global объявление в обработчике, как показано в следующем примере. (Этот подход также работает для соединения переменной во вложенном script объект.)

set currentCount to 0
on increment()
    global currentCount
    set currentCount to currentCount + 1
end increment
 
increment() --result: 1
currentCount --result: 1

Ограничить контекст переменной к сценарию run обработчик независимо от последующего global объявления, необходимо объявить его явно как a local переменная, как показано в этом примере:

local currentCount
set currentCount to 10
on increment()
    global currentCount
    set currentCount to currentCount + 2
end increment
 
increment() --error: "The variable currentCount is not defined"

Поскольку currentCount переменная в этом примере объявляется как локальная для сценария, и следовательно для его неявного run обработчик, любая последующая попытка объявить ту же переменную как global результаты по ошибке.

Если Вы объявляете внешнюю переменную с set команда и затем объявляет тот же идентификатор как свойство, объявление с set команда переопределяет определение свойства. Например, следующий сценарий возвращается 10, не 5. Это происходит, потому что AppleScript оценивает определения свойства, прежде чем он оценит set объявления команды:

set numClowns to 10 -- evaluated after property definition
property numClowns: 5 -- evaluated first
numClowns --result: 10

Следующий пример, показывает, как использовать a global объявление переменной в a script возразите для соединения a global переменная с внешним свойством:

property currentCount : 0
script Paula
    property currentCount : 20
    script Joe
        global currentCount
        on increment()
            set currentCount to currentCount + 1
            return currentCount
        end increment
    end script
    tell Joe to increment()
end script
run Paula --result: 1
run Paula --result: 2
currentCount --result: 2
currentCount of Paula --result: 20

Этот сценарий объявляет два отдельных currentCount свойства: одна внешняя сторона любые обработчики (и script объекты) в основном сценарии и один в script объект Paula но за пределами любых обработчиков или script объекты в Paula. Поскольку сценарий Joe объявляет global переменная currentCount, AppleScript ищет currentCount на верхнем уровне сценария, таким образом обрабатывая Джо currentCount и currentCount на верхнем уровне сценария как та же переменная.

Объем переменных, заявленных в обработчике

Обработчик не может объявить свойство, несмотря на то, что он может относиться к свойству, объявляющемуся вне любого обработчика в script объект. (Обработчик может содержать объекты сценария, но он не может содержать другой обработчик, кроме содержавшего объекта сценария.)

Таблица 3-2 суммирует объем переменных, объявленных в обработчике. Примеры каждой формы объявления следуют.

Табличный 3-2  Объем объявлений переменной в обработчике

Тип объявления

Объем (видимость)

Время жизни

global x

В обработчике только

Сброс, когда перекомпилирован сценарий; если инициализировано в обработчике, то сброшенный, когда выполняется обработчик

local x

В обработчике только

Сброс, когда выполняется обработчик

set x to 3

В обработчике только

Сброс, когда выполняется обработчик

Объем a global переменная, объявленная в обработчике, ограничивается тем обработчиком, несмотря на то, что AppleScript смотрит вне обработчика, когда это пытается определить местоположение более раннего возникновения той же переменной. Вот пример:

set currentCount to 10
on increment()
    global currentCount
    set currentCount to currentCount + 2
end increment
 
increment() --result: 12
currentCount --result: 12

Когда AppleScript встречается currentCount переменная в on increment обработчик, это не ограничивает свой поиск предыдущего возникновения тем обработчиком, но продолжает смотреть, пока это не находит объявление вне никакого обработчика. Однако использование currentCount в любом последующем обработчике в сценарии локально для того обработчика, если обработчик также явно не объявляет currentCount как a global переменная.

Объем a local даже если тот же идентификатор был объявлен как свойство вне обработчика, объявление переменной в обработчике ограничивается тем обработчиком:

property currentCount : 10
on increment()
    local currentCount
    set currentCount to 5
end increment
 
increment() --result: 5
currentCount --result: 10

Объем объявления переменной с помощью set команда в обработчике ограничивается тем обработчиком:

script Henry
    set currentCount to 10 -- implicit local variable in script object
    on increment()
        set currentCount to 5-- implicit local variable in handler
    end increment
    return currentCount
end script
 
tell Henry to increment() --result: 5
run Henry --result: 10

Объем первого объявления первого currentCount переменная в script объект Henry ограничивается run обработчик для script объект (в этом случае, неявное run обработчик, состоя из последних двух операторов в сценарии). Объем второго currentCount объявление, в on increment обработчик, ограничивается тем обработчиком. Два экземпляра currentCount независимые переменные.