2010-08-25 24 views
1

Je suis confus par les références AppleScript ... Je ne développe presque jamais en AppleScript, et j'ai du mal à trouver une bonne documentation sur la façon dont AppleScript gère les références. Le code suivant échoue parce que AppleScript Can’t make firstValue of hash into type reference.:Pourquoi AppleScript ne peut-il pas faire de firstValue de hash dans la référence de type dans ce code de test?

on run 
    foo() 
end run 

on foo() 
    set the hash to {firstValue:1, secondValue:2} 
    set the hashRef to a reference to the hash 
    return the firstValue of hashRef 
end foo 

Mais le code suivant fonctionne - même code, mais je suis en cours d'exécution à l'intérieur du gestionnaire run au lieu du gestionnaire foo:

on run 
    set the hash to {firstValue:1, secondValue:2} 
    set the hashRef to a reference to the hash 
    return the firstValue of hashRef 
end run 

Pourquoi la premier exemple de code échouer tandis que le deuxième exemple de code fonctionne? Une meilleure question, quelqu'un peut-il me diriger vers la documentation expliquant ceci afin que je puisse apprendre quelle est mon erreur?

EDIT: La réponse de Philip m'a orienté dans la bonne direction et je vois maintenant ce qui m'a dérouté. The official AppleScript docs indique que «AppleScript transmet tous les paramètres par référence, ce qui signifie qu'une variable passée est partagée entre le gestionnaire et l'appelant, comme si le gestionnaire avait créé une variable à l'aide de la commande set». Cependant, cela ne signifie pas que AppleScript transmet un AppleScript Reference Object en tant que paramètre!

Voici le suivant, exemple de code plus détaillé, pour montrer la solution de travail finale, j'ai développé:

on run 
    foo() 
end run 

on isRef(someValue) 
    try 
     someValue as reference 
     return true 
    on error 
     return false 
    end try 
end isRef 

on foo() 
    log "In foo()" 
    set the objectList to makeObjectList() 
    log "objectList isRef =" & isRef(objectList) 
    set theObject to makeObject given id:0, name:"Test" 
    addObjectToObjectList(theObject, objectList) 
    log "foo(): object name =" & name of theObject 
    log item 1 of allItems of objectList 
    log item 1 of goodItems of objectList 
    set the name of item 1 of allItems of objectList to "Test3" 
    log item 1 of allItems of objectList 
    log item 1 of goodItems of objectList 
end foo 

on makeObjectList() 
    set the hash to {allItems:{}, goodItems:{}, badItems:{}} 
    return the hash 
end makeObjectList 

on makeObject given name:theName, id:theId 
    set theObject to {name:theName, id:theId} 
    return theObject 
end makeObject 

on addObjectToObjectList(object, objectList) 
    log "In addObjectToObjectList" 
    log "object isRef =" & isRef(object) 
    copy object to the end of allItems of the objectList 
    set objectRef to a reference to the last item in allItems of the objectList 

    set name of objectRef to "Test2" 
    log "object name =" & name of object 


    log "objectRef isRef =" & isRef(objectRef) 
    log "objectRef name =" & name of (contents of objectRef) 
    copy objectRef to the end of goodItems of the objectList 
end addObjectToObjectList 

La sortie de c'est la suivante:

 
(*In foo()*) 
(*objectList isRef =false*) 
(*In addObjectToObjectList*) 
(*object isRef =false*) 
(*object name =Test*) 
(*objectRef isRef =true*) 
(*objectRef name =Test2*) 
(*foo(): object name =Test*) 
(*name:Test2, id:0*) 
(*name:Test2, id:0*) 
(*name:Test3, id:0*) 
(*name:Test3, id:0*) 

Le point étant, je Je ne peux pas faire de références aux variables locales dans un gestionnaire - mais je peux faire des références à des parties d'un enregistrement tant que ces références sont stockées dans cet enregistrement, qui est la fonctionnalité que je recherchais.

Je doute que quelqu'un sera jamais lu ce loin sur cette question dans :-)

+0

Qu'est-ce que vous essayez de faire qui nécessite des références? Je demande seulement parce que je travaille dans Applescript depuis des années, et je n'ai jamais eu besoin d'une référence, en particulier dans une situation aussi simple que celle-ci. Vous n'avez pas besoin de créer une référence à l'enregistrement pour accéder à la valeur demandée. Ma compréhension rudimentaire d'une référence est qu'elle est similaire à un pointeur. –

+0

@Philip - Je ne pensais pas avoir besoin de références non plus, mais mon code ne semblait pas fonctionner sans eux ...Ce que je fais (essaye de faire) est de maintenir une structure de données complexe en mémoire et de la passer (byref) à différents gestionnaires pour la manipuler. J'ai aussi lu que l'utilisation de références est beaucoup plus rapide ... – Josh

+0

@Philip: Voir [Apple's Docs] (http://developer.apple.com/mac/library/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_classes.html# // apple_ref/doc/uid/TP40000983-CH1g-BBCDBHIE) plus particulièrement la partie "Pour les grandes listes, il est plus efficace d'utiliser la référence à l'opérateur lors de l'insertion d'un grand nombre d'éléments dans une liste". Je vais voir si je peux faire fonctionner mon code sans refs. – Josh

Répondre

0

Je pense vraiment que c'est une question de portée ici. Si je déclare une référence à une sélection dans Finder et InDesign depuis foo() en obtenant une référence et des valeurs contenues dans les travaux. Mais puisque vous ne travaillez pas dans une application spécifique, la cible doit être dans la portée du script. Connaissant Applescript - et son fainéant légendaire - cela pourrait être la façon «correcte» d'utiliser l'opérateur de référence.

j'ai pu faire ce travail si je faisais le hachage d'un property global du script, comme ce qui suit: property hash : {firstValue:1, secondValue:2}. J'étais alors en mesure d'appeler la valeur avec succès à partir foo(). Exemple d'un code complet:

property hash : {firstValue:1, secondValue:2} 

on run 
    foo() 
end run 

on foo() 
    set the hashRef to a reference to the hash 
    return the firstValue of hashRef 
end foo 

Pas une réponse spécifique à la question, mais une réponse à votre question.

+0

Merci @Philip! Comme je continue à déboguer mon script, je suis en train de tomber sur un problème de référence beaucoup plus complexe, mais vous méritez l'acceptation de celui-ci. Si je n'arrive pas à comprendre mon problème plus complexe, je posterai une nouvelle question. – Josh

+0

Je vois maintenant ce qui m'a dérouté. Je vais éditer ma réponse et poster quelques détails supplémentaires, mais apparemment ce qui m'a dérouté était que "AppleScript passe tous les paramètres * par référence *", mais cela ne signifie pas ** la même chose que "AppleScript passe les références pour tous les paramètres ". En d'autres termes, il existe deux types de références dans AppleScript! – Josh

+0

Si vous voulez que votre cerveau fasse mal, lisez ma question éditée. Je pense que je quitte pour la journée maintenant, HA! – Josh