principiantes para extension examples applescript

extension - applescript para principiantes



Cómo registrar objetos en una consola con AppleScript (5)

AppleScript no lo hace fácil:

  • log solo los registros mientras se ejecuta en el editor AppleScript o cuando se ejecuta mediante osascript (a stderr en ese caso): el resultado se perderá en otros casos, como cuando las aplicaciones ejecutan un script con la clase NSAppleScript Cocoa.

  • log solo acepta un argumento; si bien acepta cualquier tipo de objeto, no facilita la obtención de una representación significativa de los tipos no incorporados: intente con el log me para obtener información sobre el script, por ejemplo; frecuentemente, log (get properties of <someObj>) debe usar para obtener información significativa; tenga en cuenta la sintaxis engorrosa, que es necesaria, porque el solo uso de las log properties of <someObj> típicamente solo imprime el nombre de la forma de referencia en lugar de las propiedades a las que apunta (por ejemplo, las log properties of me generan salidas inútiles (*properties*) ) .

  • En general, AppleScript hace que sea muy difícil obtener representaciones de texto significativas de objetos de tipos no incorporados: <someObj> as text (igual que: <someObj> as string ) rompe molestamente - arroja un error de tiempo de ejecución - para tales objetos; pruébame me as text .

A continuación, se muestran las subrutinas de ayuda que abordan estos problemas :

  • dlog() es una subrutina que combina derivar representaciones de texto significativas de cualquier objeto con la capacidad de escribir en varios destinos de registro (incluidos syslog y archivos) en función de una variable de configuración global.
  • toString() (efectivamente incrustado en dlog() ) es una subrutina que toma un único objeto de cualquier tipo y deriva una representación significativa de texto de la misma.

Consejo del sombrero a @ 1.61803; su respuesta proporcionó indicadores para implementar los diversos objetivos de registro.

Ejemplos:

# Setup: Log to syslog and a file in the home dir. # Other targets supported: "log", "alert" # Set to {} to suppress logging. set DLOG_TARGETS to { "syslog", "~/as.log" } # Log properties of the front window of frontmost application. dlog(front window of application (path to frontmost application as text)) # Log properties of own front window; note the *list* syntax for multiple args. dlog({"my front window: ", front window}) # Get properties of the running script as string. toString(me) # ->, e.g.: [script name="sandbox"] {selection:insertion point after character 2475 of text of document "sandbox2.scpt", frontmost:true, class:application, name:"AppleScript Editor", version:"2.6"}

Vea los comentarios del código fuente sobre cada subrutina para más detalles.

Código fuente dlog ()

# Logs a text representation of the specified object or objects, which may be of any type, typically for debugging. # Works hard to find a meaningful text representation of each object. # SYNOPSIS # dlog(anyObjOrListOfObjects) # USE EXAMPLES # dlog("before") # single object # dlog({ "front window: ", front window }) # list of objects # SETUP # At the top of your script, define global variable DLOG_TARGETS and set it to a *list* of targets (even if you only have 1 target). # set DLOG_TARGETS to {} # must be a list with any combination of: "log", "syslog", "alert", <posixFilePath> # An *empty* list means that logging should be *disabled*. # If you specify a POSIX file path, the file will be *appended* to; variable references in the path # are allowed, and as a courtesy the path may start with "~" to refer to your home dir. # Caveat: while you can *remove* the variable definition to disable logging, you''ll take an additional performance hit. # SETUP EXAMPLES # For instance, to use both AppleScript''s log command *and* display a GUI alert, use: # set DLOG_TARGETS to { "log", "alert" } # Note: # - Since the subroutine is still called even when DLOG_TARGETS is an empty list, # you pay a performancy penalty for leaving dlog() calls in your code. # - Unlike with the built-in log() method, you MUST use parentheses around the parameter. # - To specify more than one object, pass a *list*. Note that while you could try to synthesize a single # output string by concatenation yourself, you''d lose the benefit of this subroutine''s ability to derive # readable text representations even of objects that can''t simply be converted with `as text`. on dlog(anyObjOrListOfObjects) global DLOG_TARGETS try if length of DLOG_TARGETS is 0 then return on error return end try # The following tries hard to derive a readable representation from the input object(s). if class of anyObjOrListOfObjects is not list then set anyObjOrListOfObjects to {anyObjOrListOfObjects} local lst, i, txt, errMsg, orgTids, oName, oId, prefix, logTarget, txtCombined, prefixTime, prefixDateTime set lst to {} repeat with anyObj in anyObjOrListOfObjects set txt to "" repeat with i from 1 to 2 try if i is 1 then if class of anyObj is list then set {orgTids, AppleScript''s text item delimiters} to {AppleScript''s text item delimiters, {", "}} # '' set txt to ("{" & anyObj as string) & "}" set AppleScript''s text item delimiters to orgTids # '' else set txt to anyObj as string end if else set txt to properties of anyObj as string end if on error errMsg # Trick for records and record-*like* objects: # We exploit the fact that the error message contains the desired string representation of the record, so we extract it from there. This (still) works as of AS 2.3 (OS X 10.9). try set txt to do shell script "egrep -o ''//{.*//}'' <<< " & quoted form of errMsg end try end try if txt is not "" then exit repeat end repeat set prefix to "" if class of anyObj is not in {text, integer, real, boolean, date, list, record} and anyObj is not missing value then set prefix to "[" & class of anyObj set oName to "" set oId to "" try set oName to name of anyObj if oName is not missing value then set prefix to prefix & " name=/"" & oName & "/"" end try try set oId to id of anyObj if oId is not missing value then set prefix to prefix & " id=" & oId end try set prefix to prefix & "] " set txt to prefix & txt end if set lst to lst & txt end repeat set {orgTids, AppleScript''s text item delimiters} to {AppleScript''s text item delimiters, {" "}} # '' set txtCombined to lst as string set prefixTime to "[" & time string of (current date) & "] " set prefixDateTime to "[" & short date string of (current date) & " " & text 2 thru -1 of prefixTime set AppleScript''s text item delimiters to orgTids # '' # Log the result to every target specified. repeat with logTarget in DLOG_TARGETS if contents of logTarget is "log" then log prefixTime & txtCombined else if contents of logTarget is "alert" then display alert prefixTime & txtCombined else if contents of logTarget is "syslog" then do shell script "logger -t " & quoted form of ("AS: " & (name of me)) & " " & quoted form of txtCombined else # assumed to be a POSIX file path to *append* to. set fpath to contents of logTarget if fpath starts with "~/" then set fpath to "$HOME/" & text 3 thru -1 of fpath do shell script "printf ''%s//n'' " & quoted form of (prefixDateTime & txtCombined) & " >> /"" & fpath & "/"" end if end repeat end dlog

código fuente toString ()

# Converts the specified object - which may be of any type - into a string representation for logging/debugging. # Tries hard to find a readable representation - sadly, simple conversion with `as text` mostly doesn''t work with non-primitive types. # An attempt is made to list the properties of non-primitive types (does not always work), and the result is prefixed with the type (class) name # and, if present, the object''s name and ID. # EXAMPLE # toString(path to desktop) # -> "[alias] Macintosh HD:Users:mklement:Desktop:" # To test this subroutine and see the various representations, use the following: # repeat with elem in {42, 3.14, "two", true, (current date), {"one", "two", "three"}, {one:1, two:"deux", three:false}, missing value, me, path to desktop, front window of application (path to frontmost application as text)} # log my toString(contents of elem) # end repeat on toString(anyObj) local i, txt, errMsg, orgTids, oName, oId, prefix set txt to "" repeat with i from 1 to 2 try if i is 1 then if class of anyObj is list then set {orgTids, AppleScript''s text item delimiters} to {AppleScript''s text item delimiters, {", "}} set txt to ("{" & anyObj as string) & "}" set AppleScript''s text item delimiters to orgTids # '' else set txt to anyObj as string end if else set txt to properties of anyObj as string end if on error errMsg # Trick for records and record-*like* objects: # We exploit the fact that the error message contains the desired string representation of the record, so we extract it from there. This (still) works as of AS 2.3 (OS X 10.9). try set txt to do shell script "egrep -o ''//{.*//}'' <<< " & quoted form of errMsg end try end try if txt is not "" then exit repeat end repeat set prefix to "" if class of anyObj is not in {text, integer, real, boolean, date, list, record} and anyObj is not missing value then set prefix to "[" & class of anyObj set oName to "" set oId to "" try set oName to name of anyObj if oName is not missing value then set prefix to prefix & " name=/"" & oName & "/"" end try try set oId to id of anyObj if oId is not missing value then set prefix to prefix & " id=" & oId end try set prefix to prefix & "] " end if return prefix & txt end toString

Solo intento registrar el estado de los objetos a lo largo de la vida de mi AppleScript. En otros lenguajes, los métodos toString () del objeto representarán el texto equivalente y puedo usarlos. En AppleScript, este no parece ser el caso.

convert applescript object to string (similar to toString)

Dará salida al objeto buscador (y sus propiedades) a la ventana "Resultados" del Editor de AppleScript, pero solo si es la última instrucción que se ejecuta.

Si tengo una instrucción trace () (que toma un mensaje para fines de registro):

on trace(message) do shell script "cat >>~/log/applescript.txt <<END_OF_THE_LOG " & (message as text) & " END_OF_THE_LOG" end trace

e intento registrar el mismo objeto, obtengo

Can’t make properties of application "Finder" into type text.

Estoy abierto a mejores formas de iniciar sesión en una consola, pero me gustaría saber cómo escribir las propiedades de un objeto (como el Editor de AppleScript) en el medio de un script para probar de cualquier manera.


Pruebe cualquiera de los siguientes:

# echo to file do shell script "echo " & quoted form of (myObj as string) & ¬ " > ~/Desktop/as_debug.txt" # write to file set myFile to open for access (path to desktop as text) & ¬ "as_debug2.txt" with write permission write myObj to myFile close access myFile # log to syslog do shell script "logger -t ''AS DEBUG'' " & myObj # show dialog display dialog "ERROR: " & myObj

Si lo que intentas registrar no es texto, puedes intentar:

quoted form of (myObj as string)


Similar a toString() ...

on TextOf(aVariable) try return "" & aVariable on error errm if errm begins with "Can’t make " ¬ and errm ends with " into type Unicode text." then ¬ return text 12 through -25 of errm return "item of class " & (class of aVariable) & return & errm end try end TextOf


Simplemente use la declaración de log en el Editor de AppleScript. Cuando vea los resultados en Applescript Editor, en la parte inferior de la ventana, presione el botón "Eventos". Normalmente, se presiona el botón "Resultados" y solo se ve el resultado de la última declaración como mencionas. Cambie el botón a "Eventos". Esto le mostrará todo lo que está sucediendo a medida que se ejecuta el script, y además todas las declaraciones de log que coloca a lo largo del código también. Tenga en cuenta que las instrucciones de log no tienen que ser texto. Puede registrar cualquier objeto.

Esta es la mejor manera de depurar su script y ver qué está sucediendo. Como ejemplo prueba esto y mira los "Eventos". ¡Realmente pensaste que no necesitas muchas declaraciones de log si ves los Eventos porque todo ya está registrado!

set someFolder to path to desktop log someFolder tell application "Finder" set someItem to first item of someFolder log someItem set itemProps to properties of someItem log itemProps end tell


do shell script "echo ''" & (current date) & ": Found " & Thisfilename & "'' >> ~/logs/MyGreatAppleScript.log"