Section 14.6. List Coercions


14.6. List Coercions

Anything may be coerced to a list . How it is treated depends on what you start with:


A list

The result is identically the same list.


A record

The result is a list of the values from the record:

 set R to {name:"Matt", age:51} R as list -- {"Matt", 51}


Anything else

The result is a list of one item, that item being the thing you started with.

Coercion to a list is very useful for making sure you have a list; if the thing you start with isn't a list, it becomes one, and if it is a list, it is unchanged. Recall, however, that this coercion might not work if the thing you start with belongs to an application, because that application might not implement it (see "Coercion by a Scriptable Application," earlier in this chapter).

Officially you can't coerce a list to a record, but there's a trick for doing it using a second level of evaluation. (Consider the warnings at "Second-Level Evaluation" in Chapter 19 before resorting to this trick; it involves a lot of overhead.) The value of every odd item of the list (which should be a string) becomes the name of a record item, whose value in turn is the corresponding even item of the list:

 on listToRecord(L)     script myScript         return {«class usrf»:L}     end script     return run script myScript end listToRecord set R to listToRecord({"name", "haha", "age", 51}) R -- {|name|:"haha", age:51} 

To understand the trickery involved here, see "Record" in Chapter 13. Observe that because we are forming a user record, the term name ends up in pipes; it is not the predefined name property, and its value cannot be accessed without pipes around the term name.

A list of one item may be coerced to the datatype of that item, and the result will be that item. Of course, the result can then be coerced to any datatype that it can be coerced to, so you can also coerce a list of one item to that datatype in a single step. For example:

 {true} as string -- "true" 

That's possible because the list of one boolean is first coerced to a boolean, and a boolean can be coerced to a string.

A list of multiple items may be coerced to a string, provided that every individual item may be coerced to a string. This coercion is performed using the current value of the text item delimiters. (See "String" in Chapter 13.) The rule is that every item of the list is coerced to a string, and the resulting strings are joined into a single string with the text item delimiters value between each pair. The text item delimiters value can be the empty string; this is in fact its default value. If an item of the list is a list, it is coerced to a string by the same rule; so this coercion in effect flattens a list, to any depth, into a single string.

So, assuming the text item delimiters is the empty string:

 {"Manny", {"Moe", "Jack"}} as string -- "MannyMoeJack" 

Or, assuming the text item delimiters is a comma followed by a space:

 {"Manny", {"Moe", "Jack"}} as string -- "Manny, Moe, Jack" 

A common technique is to transform a string to a list (using text items or some other element), process the list in some way, and then transform it back to a string by coercion. This technique can help you perform string manipulations, making up somewhat for the fact that AppleScript's native string functionality is so thin. (Also, a list, unlike a string, can be mutated in place, so operating on a list can be faster and more efficient.) As a simple example, here's how to get the containing folder from a Macintosh pathname:

 on containingFolder(s)     set text item delimiters to ":"     return (items 1 thru -2 of text items of s) as string end containingFolder containingFolder("feathers:Users:mattneub:Documents:someDoc") -- "feathers:Users:mattneub:Documents"

A list can be implicitly coerced to a string. (See Chapter 15 for the situations in which this can occur.) Beware of allowing this to happen without taking into account the current state of the text item delimiters.


A common complaint is that with display dialog you can't display a list as a list (that is, as it would be displayed as a result by the Script Editor). A workaround is to coerce the list to something impossible, such as a record, and capture the resulting error message. This trick is based upon the observation that the error message has somehow performed precisely the coercion you had in mind:

 on coerceForDisplay(L)     try         L as record     on error s         set c to characters of s         set u to count c         repeat with i from 1 to u             if item i of c is "{" then exit repeat         end repeat         repeat with j from u to 1 by -1             if item j of c is "}" then exit repeat         end repeat         set text item delimiters to ""         return (items i thru j of c) as string     end try end coerceForDisplay display dialog coerceForDisplay({"pep", 3, {"Mannie", "Moe", "Jack"}}) -- {"pep", 3, {"Mannie", "Moe", "Jack"}} 




AppleScript. The Definitive Guide
AppleScript: The Definitive Guide, 2nd Edition
ISBN: 0596102119
EAN: 2147483647
Year: 2006
Pages: 267
Authors: Matt Neuburg

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net