You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AppleScript编译与解释执行时枚举属性输出差异问题咨询

AppleScript解释执行与编译执行时枚举属性输出差异问题

我写的这段AppleScript代码:

on collectionToJson(_collection)
  tell application "Capture One 22" to return "{\"name\": " & "\"" & name of _collection & "\", \"id\": " & id of _collection & ", \"kind\": " & "\"" & kind of _collection & "\", \"user\": " & user of _collection & "}"
end collectionToJson

在解释执行和编译执行时输出结果不一致:

解释执行(直接运行.applescript源文件):

> osascript target/classes/Collections.applescript --byId 14659
{"name": "StoppingDown", "id": 14659, "kind": "project", "user": true}

编译执行(运行编译后的.scpt文件):

> osascript target/classes/Collections.scpt --byId 14659
{"name": "StoppingDown", "id": 14659, "kind": "«constant ****CCpj»", "user": true}

可以看到,作为枚举类型的kind属性输出形式有明显差异:解释执行时输出可读字符串"project",编译执行时却变成了内部常量标识«constant ****CCpj»。

请问这种差异是因为我对AppleScript的理解有误,还是和交互的Capture One 22应用有关?

完整脚本如下:

on run (_args)
    tell front document of application "Capture One 22"
        set _command to item 1 of _args
        
        if _command is "--byId" then
            set _collection to my findCollectionByIdPath(_args)
            my collectionToJson(_collection)
            
        else if _command is "--byName" then
            set _collection to collection named (item 2 of _args)
            
            repeat with _i from 3 to count of _args
                tell _collection to set _collection to collection named (item _i of _args)
            end repeat
            
            my collectionToJson(_collection)
            
        else if _command is "--children" then
            set _collection to my findCollectionByIdPath(_args)
            tell _collection to my collectionsToJson(collections)
            
        else if _command is "--variants" then
            set _collection to my findCollectionByIdPath(_args)
            tell _collection to my variantsToJson(variants)
        else
            log "Unknown command: " & _command
        end if
    end tell
end run

on findCollectionByIdPath(_args)
    tell front document of application "Capture One 22"
        set _collection to first collection whose its id is item 2 of _args
        
        repeat with _i from 3 to count of _args
            tell _collection to set _collection to (first collection whose its id is (item _i of _args))
        end repeat
        
        return _collection
    end tell
end findCollectionByIdPath

on collectionsToJson(_collections)
    set _result to "[" 
    set _separator to ""
    repeat with _collection in _collections
        set _result to _result & _separator & my collectionToJson(_collection)
        set _separator to ","
    end repeat
    return _result & "]"
end collectionsToJson

on collectionToJson(_collection)
    tell application "Capture One 22" to return "{\"name\": " & "\"" & name of _collection & "\", \"id\": \"" & id of _collection & "\", \"kind\": " & "\"" & kind of _collection & "\", \"user\": " & user of _collection & "}"
end collectionToJson

on variantsToJson(_variants)
    set _result to "[" 
    set _separator to ""
    repeat with _variant in _variants
        set _result to _result & _separator & my variantToJson(_variant)
        set _separator to ","
    end repeat
    return _result & "]"
end variantsToJson

on variantToJson(_variant)
    -- FIXME: it seems that this 'tell' slows down a lot
    tell application "Capture One 22" to return ("{\"name\": \"" & (name of _variant) as text) & "\", \"id\": \"" & id of _variant & "\", \"rating\": " & rating of _variant & ", \"colorTag\": " & color tag of _variant & "}"
end variantToJson

问题原因分析

这种差异是AppleScript编译机制与Capture One 22脚本字典实现共同作用的结果:

  1. 解释执行的行为:直接运行.applescript源文件时,AppleScript解释器会实时查询Capture One 22的脚本字典,将枚举类型的内部常量(如«constant ****CCpj»)动态转换为对应的可读字符串(如"project")。

  2. 编译执行的行为:编译成.scpt文件时,AppleScript编译器会将枚举值替换为对应的内部常量标识,而非保留可读名称。这是为了提升执行效率,编译后的脚本会存储应用定义的常量内部ID,不再依赖运行时的字典查询,但代价是无法自动转换为可读名称。

  3. Capture One的影响:不同应用对AppleScript枚举的实现存在差异,部分应用会确保编译后的脚本仍能解析枚举的可读名称,但Capture One 22的脚本字典处理方式导致编译后只能输出内部常量标识。

解决方法

要让两种执行方式都输出可读的kind字符串,可以手动建立内部常量与可读名称的映射:

on getCollectionKindName(_kindConstant)
    -- 根据Capture One实际枚举值补充完整映射
    set kindMap to {«constant ****CCpj»:"project", «constant ****CCpt»:"album", «constant ****CCpf»:"folder"}
    if _kindConstant is in kindMap then
        return kindMap's item _kindConstant
    else
        return "unknown"
    end if
end getCollectionKindName

修改collectionToJson函数,调用上述映射函数:

on collectionToJson(_collection)
    tell application "Capture One 22"
        set kindName to my getCollectionKindName(kind of _collection)
        return "{\"name\": \"" & name of _collection & "\", \"id\": \"" & id of _collection & "\", \"kind\": \"" & kindName & "\", \"user\": " & user of _collection & "}"
    end tell
end collectionToJson

内容的提问来源于stack exchange,提问作者Fabrizio Giudici

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:25:31