• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Unwinding the containment hierarchy of a reference
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Unwinding the containment hierarchy of a reference


  • Subject: Re: Unwinding the containment hierarchy of a reference
  • From: Michael Terry <email@hidden>
  • Date: Sat, 11 Dec 2004 12:20:09 -0800


On Dec 8, 2004, at 3:31 PM, Paul Berkowitz wrote:

If you wanted to
create a more universally useful handler, and have it work with multiple
applications, that'd require some extra work. For example, some objects might
be specified with a name reference, so could contain the " of " string.

I don't follow here.


I mean that if you wanted to make a routine which used vanilla AS to parse an object specifier, you'd have to be careful not to treat all cases of " of " in the entire object specifier string the same. If the application supports name references, e.g., Finder, " of " could appear in the specifier, and breaking on " of " in the name string would be a problem.


So I decided to try to write a general handler that would return all the specifiers--from the bottom to the top--given some reference. Problems encountered:

1. Evaluating references--even references fully qualified up to the application object--in the 'run script' context resulted in having the root application object lopped off, and were unusable. So, you'd get back:

word 1 of document 1

... rather than:

word 1 of document 1 of application "TextEdit"

And even if you tried to use them in an application 'tell', they still didn't work.

One way to avoid that is the way you did it, getting the application reference first, then doing the 'run script''s inside it:

On Dec 9, 2004, at 9:42 AM, Paul Berkowitz wrote:

set appRef to run script "application \"TextEdit\""
--> application "TextEdit"
tell appRef
    set docRef to run script "ref to document 2"
    --> document 2 of application "TextEdit"
    set wordRef to run script "ref to word 12 of document 2"
    --> word 12 of document 2 of application "TextEdit"
    set wordRef to run script "ref to word 12"
    --> word 12 of application "TextEdit"
end tell

2. When evaluating a list of references inside 'run script' that point to AS types, the contents would always be returned, no matter how many 'ref to''s you prefixed them with:


run script "{ref to word 1 of document 1 of app \"TextEdit\"}"
--> {"hello"}

-----

It turns out, though, that both those problems are neatly solved by returning a script from 'run script', so that you can do the evaluations in the original context. My routine was taking like a half second or more to run before incorporating this technique. So, here's the handler:

--

on parseObjSpec(objSpec)
try
objSpec as reference
try
set objSpec to ({hack:objSpec} as string)'s text from character 8 to end
on error eMsg
set objSpec to eMsg's text from character 18 to -17
end try

-- scan for delimiter matches
set {noMatch, fullMatch, matchedSoFar, quote, backslash, escaped} ¬
to {"", " of ", "", "\"", "\\", false}
set {eachAncestor, scanningOutsideOfStrings} to {"", true}
repeat with thisPos from 1 to objSpec's length
set thisChar to objSpec's character thisPos
if scanningOutsideOfStrings then
set matchedSoFar to matchedSoFar & thisChar
if matchedSoFar is fullMatch then
set eachAncestor to eachAncestor & ", ref to" & objSpec's text thisPos thru end
set matchedSoFar to noMatch
else if fullMatch does not start with matchedSoFar then
set matchedSoFar to noMatch
if thisChar is quote then set scanningOutsideOfStrings to false
end if
else
if thisChar is quote then
if not escaped then set scanningOutsideOfStrings to true
set escaped to false
else if thisChar is backslash then
set escaped to not escaped
end if
end if
end repeat

return run (run script "script
{" & "ref to " & objSpec & eachAncestor & "}
end")
on error eMsg number eNum
error "parseObjSpec can't continue: " & eMsg number eNum
end try
end parseObjSpec


--

tell application "TextEdit" to get a reference to word 1 of document 1
parseObjSpec(result)

--> {word 1 of document 1 of application "TextEdit", document 1 of application "TextEdit", application "TextEdit"}

It should work with standard canonical object specifiers returned by most applications, such as ID, index, and name reference forms. That's what I wanted it for anyway. If one intended to pass it any old reference one could make up, it will surely fail on complex, compound specifiers. I can't think of a good reason to do that, so I didn't bother accounting for it.

I ran the following tests on it:

set testResults to {}

-- uses id reference form
tell application "Address Book" to get my card
set end of testResults to parseObjSpec(result)

-- uses index reference form
tell application "iCal" to get some calendar
set end of testResults to parseObjSpec(result)

-- uses name reference form with folder name containing
-- quote and " of "
tell application "Finder"
	tell (make folder with properties {name:"\"Hall of Fame\""})
		set end of testResults to my parseObjSpec(it)
		delete it
	end tell
end tell

-- reference to object that evaluates as AS built-in type
tell application "TextEdit" to get a reference to word 1 of document 1
set end of testResults to parseObjSpec(result)
set end of testResults to get contents of first item of result

-- invalid argument
try
	parseObjSpec(7)
on error eMsg number eNum
	set end of testResults to (eNum as string) & ": " & eMsg
end try

return testResults

--> {{person id "4909FCE2-AD59-11D8-9D0D-000393D8A740:ABPerson" of application "Address Book", application "Address Book"}, {calendar 5 of application "iCal", application "iCal"}, {folder "\"Hall of Fame\"" of folder "Desktop" of folder "ellyagg" of folder "Users" of startup disk of application "Finder", folder "Desktop" of folder "ellyagg" of folder "Users" of startup disk of application "Finder", folder "ellyagg" of folder "Users" of startup disk of application "Finder", folder "Users" of startup disk of application "Finder", startup disk of application "Finder", application "Finder"}, {word 1 of document 1 of application "TextEdit", document 1 of application "TextEdit", application "TextEdit"}, "hello", "-1700: parseObjSpec can't continue: Can't make 7 into a reference."}


Michael _______________________________________________ Do not post admin requests to the list. They will be ignored. Applescript-users mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
References: 
 >Re: Unwinding the containment hierarchy of a reference (From: Paul Berkowitz <email@hidden>)

  • Prev by Date: Re: Image Events Errors
  • Next by Date: Re: Image Events Errors
  • Previous by thread: Re: Unwinding the containment hierarchy of a reference
  • Next by thread: RE: Unwinding the containment hierarchy of a reference
  • Index(es):
    • Date
    • Thread