элементы, классы и объекты applescript

Я пишу applescript для автоматизации утомительной работы в Aperture, и я чертовски долго разбираюсь в некоторых особенностях языка. В частности, мне очень трудно работать с коллекциями (списками и элементами). Меня ставят в тупик спецификаторы объектов, включающие коллекции и применяющие команды к элементам коллекции. Более того, меня смущают странные различия в спецификаторах объектов, которые, кажется, ведут себя по-разному при обращении к элементам объекта по их классу внутри класса, а не, ну, позвольте мне показать вам.

Вот начало скрипта.

prop Movies : {}

tell Application "Aperture"
     set Movies to every image version whose name of every keywords contains "Movie"
end tell

length of Movies   -- result => 601

Объект application в Aperture содержит набор элементов из image versions. Объекты image version содержат набор элементов из keywords. keyword — это объекты/списки со свойствами name и id.

Таким образом, глобальное свойство скрипта Movies теперь содержит все объекты image version в моей библиотеке Aperture, которые на самом деле являются видео. Теперь, когда я пытаюсь сделать это:

repeat with movie in Movies
    log ("Movie name is '" & name of movie & "'.")
    log ("  the class of this object is '" & class of movie & "'.")
end

вывод, как и ожидалось, таков:

Movie name is 'MOV03510.MPG'.
  the class of this object is 'image version'.
Movie name is 'MOV00945'.
  the class of this object is 'image version'.
Movie name is 'MOV03228.MPG'.
  the class of this object is 'image version'.
Movie name is 'MOV02448'.
  the class of this object is 'image version'.
...

Однако я застрял в том, как получить доступ к коллекции элементов в этих image versions. Когда я делаю это:

repeat with movie in Movies

    log ("Movie name is '" & name of movie & "'.")
    log ("  the class of this object is '" & class of movie & "'.")
    set kwnamelist to name of every keyword in movie
    if kwnamelist contains "Movie"
       log ("    Yes, '" & name of movie & "' is indeed a video.")
    end if
end

дает мне

find_videos.applescript:1089:1096: script error: Expected class name but found identifier. (-2741)

Для меня ошибка звучит так, будто applescript запутан спецификатором объекта name of every keyword in movie. НО, причина, по которой я так запутался в этом, заключается в том, что если я напишу этот код:

tell Application "Aperture"
    repeat with imageind from 1 to 1000
        set img to item imageind of image versions
        tell me to log ("Image name is '" & name of img & "'.")
        tell me to log ("  the class of this object is '" & class of img & "'.")
        set kwnamelist to name of every keyword in img
        if kwnamelist contains "Movie" 
            tell me to log ("    '" & name of img & "' is actually a video!")
        end if
    end
end tell

то я получаю ожидаемый результат:

...
Image name is 'DSC_4650'.
  the class of this object is 'image version'.
Image name is '104-0487_IMG'.
  the class of this object is 'image version'.
Image name is 'MOV02978.MPG'.
  the class of this object is 'image version'.
    'MOV02978.MPG' is actually a video!
Image name is '108-0833_IMG'.
  the class of this object is 'image version'.

...

Может ли кто-нибудь сказать мне, что не так с моим спецификатором объекта? Почему я могу применить get name к every keyword in img, когда image version находится в одном контексте, но не могу в другом контексте? Есть ли что-то, что мне здесь не хватает? Является ли класс keyword внутренним по отношению к объекту Aperture application? Как бы я указал что-то вроде application::keyword, если это так?

ОБНОВИТЬ:

Я решил эту конкретную проблему, но был бы очень признателен, если бы кто-нибудь точно объяснил, почему это решает ее. Я сделал это:

tell Application "Aperture"
    repeat with movie in Movies
        tell me to log ("Movie name is '" & name of movie & "'.")
        tell me to log ("  the class of this object is '" & class of movie & "'.")
        set kwnamelist to name of every keyword in movie
        if kwnamelist contains "Movie"
            tell me to log ("    Yes, '" & name of movie & "' is indeed a video.")
        end if
    end
end tell

дает ожидаемый результат:

...
Movie name is 'IMG_0359'.
  the class of this object is 'image version'.
    Yes, 'IMG_0359' is indeed a video.
Movie name is 'MOV02921.MPG'.
  the class of this object is 'image version'.
    Yes, 'MOV02921.MPG' is indeed a video.
Movie name is 'MOV02249'.
  the class of this object is 'image version'.
    Yes, 'MOV02249' is indeed a video.
...

Кажется, что здесь работает очень своеобразная проблема масштаба. Может ли кто-нибудь объяснить мне, как объекты keyword находятся в области видимости в этой новой версии, но выходят за рамки в предыдущей версии, где мы не были в блоке tell? Я думал, что блоки tell предназначены только для управления командами без прямых параметров? Они также определяют область действия типа? Или где-то здесь в построении/выполнении спецификатора объекта скрыта команда, которая зависит от отправки объекту Application "Aperture"?


person Ted Middleton    schedule 14.04.2011    source источник


Ответы (3)


Если я правильно понимаю суть вашего вопроса, потому что вы решили практическую часть, странное разыменование, которое является чем-то вроде старого каштана для яблочных скриптов, вы должны использовать терминологию только внутри соответствующих блоков сообщений, поэтому, если ваше приложение (Aperture) предоставляет терминологию «ключевое слово», вы не можете ссылаться на «ключевое слово», если вы не находитесь внутри блока tell application "Aperture".

ИЛИ, если по какой-то причине вы хотите использовать терминологию из данного приложения без использования блока сообщения, вы можете обернуть свой код следующим образом:

using terms from application "Aperture"
  -- blah blah about 'keyword' and other Aperture terminology
end using terms from
person brennanyoung    schedule 29.05.2011
comment
«использование терминов из» обычно используется для присоединяемых приложений, то есть тех, которые могут запускать сценарии «изнутри», что обычно обозначается тем фактом, что у них есть собственное меню сценариев. Хороший пример — BBEdit. Когда вы запускаете сценарий из собственного меню сценариев BBEdit, то BBEdit является целью сообщения по умолчанию, поэтому, строго говоря, приложение сообщения не требуется для запуска сценария, однако вам все равно нужно указать компилятору, где найти терминологию, чтобы он мог скомпилировать, следовательно, необходимо использовать термины для блока. Они также используются для компиляции сценариев для приложений, которые не установлены. - person brennanyoung; 30.05.2011
comment
Спасибо, Бреннан. Я думаю, это то, что вам нужно делать, когда вы разрабатываете язык и вам не нужен оператор «импорт». - person Ted Middleton; 30.05.2011

К сожалению, Applescript довольно забавен, и часто он попадает или промахивается. В этом случае repeat with item in list, элемент является ссылкой на содержимое, а не на само содержимое. Часто AppleScript будет разыменовывать это для вас, но не всегда. Обычно я всегда использую метод repeat with x from 1 to count, чтобы избежать этой проблемы.

person dscl    schedule 14.04.2011
comment
Это не похоже на решение проблемы. Когда я заменяю repeat with movie in Movies на repeat with movieind from 1 to movielen, а затем на set movie to item movieind in Movies, цикл функционально идентичен. IOW, он все еще работает, когда я комментирую бит цикла с помощью спецификатора объекта name of every keyword in movie, а затем включаю спецификатор объекта name of every keyword in movie, он все равно дает мне ту же ошибку о путанице класса/идентификатора. - person Ted Middleton; 14.04.2011

О скриптинге ключевых слов Aperture

Скрипты ключевых слов в Aperture 3 довольно неинтуитивны. Вот что я узнал:

  • id ключевого слова – это строка с путем от имени ключевого слова до его родительского элемента верхнего уровня, при этом имени каждого родительского элемента предшествует табуляция.
  • Значением свойства parents является просто идентификатор без имени и, если ключевое слово не на верхнем уровне, вкладка после имени.
  • Ключевые слова не сравниваются равными, даже если их значения совпадают; на самом деле, keyword 1 of animage != keyword 1 of anImage.
  • Изображение может иметь несколько ключевых слов с одинаковым названием, если у них разные родители. Однако имя будет отображаться только один раз, где бы ни отображались метаданные изображения.
  • Чтобы добавить ключевое слово в anImage с именем aName и родителями theParents, используйте tell anImage to make new keyword with properties {name:aName, parents:theParents, id:aName&tab&theParents}.

См. мою запись здесь для более полного объяснения, а также добавление и удаление обработчиков.

person Mitchell Model    schedule 24.09.2011