Skip to content

Commit 567fdcd

Browse files
author
hhas
committed
* in Objects, fixed bug in timer object constructor (direct parameters in library handlers can't be optional, so timer name now uses keyword parameter instead)
* Date library now runs tests in multiple time zones (and currently fails on them too) * revised various conversion handlers in TypeSupport for improved reuse and greater strictness (e.g. `asNumber[Parameter]`, `asInteger[Parameter]` etc now reject booleans, month and weekday constants, etc) * documentation improvements
1 parent 0a418e9 commit 567fdcd

File tree

13 files changed

+308
-161
lines changed

13 files changed

+308
-161
lines changed

Date.scptd/Contents/Info.plist

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
<key>WindowState</key>
1414
<dict>
1515
<key>bundleDividerCollapsed</key>
16-
<true/>
16+
<false/>
1717
<key>bundlePositionOfDivider</key>
18-
<real>0.0</real>
18+
<real>585</real>
1919
<key>dividerCollapsed</key>
2020
<false/>
2121
<key>eventLogLevel</key>
@@ -25,7 +25,7 @@
2525
<key>positionOfDivider</key>
2626
<real>493</real>
2727
<key>savedFrame</key>
28-
<string>338 33 884 744 0 0 1280 777 </string>
28+
<string>138 33 884 744 0 0 1280 777 </string>
2929
<key>selectedTab</key>
3030
<string>result</string>
3131
</dict>

Date.scptd/Contents/Resources/Date.sdef

Lines changed: 178 additions & 105 deletions
Large diffs are not rendered by default.
-3.12 KB
Binary file not shown.

List.scptd/Contents/Resources/List.sdef

Lines changed: 87 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
33
<dictionary>
44

5+
<!-- TO DO: finish `sort list` documentation -->
6+
57
<suite name="Modify" code="****">
68

79
<command name="insert into list" code="Lst:Inst" description="insert an item (or items) into the given list, returning a new list">
@@ -53,15 +55,15 @@ delete from list {1, 2, 3, 4, 5} to item 3 → {4, 5}</code></pre>
5355
<result type="list"/>
5456
<documentation>
5557
<html><![CDATA[
56-
<p>The <code>using</code> parameter's script object must implement a handler named <code>mapItem</code> that takes a value as its input and returns a new value as its output.</p>
58+
<p>The <code>using</code> parameter's script object must implement a handler named <code>mapItem</code> that takes a value as its input and returns a new value as its output. The following example demonstrates how to map a list of numbers to create a new list where each item is the square of its original value:</p>
5759
58-
<pre><code>script DoubleNumber
60+
<pre><code>script SquareNumbers
5961
to mapItem(aValue)
60-
return aValue * 2
62+
return aValue ^ 2
6163
end mapItem
6264
end script
6365
64-
map list {1, 2, 3} using DoubleNumber → {2, 4, 6}</code></pre>
66+
map list {1, 2, 3, 4, 5} using SquareNumbers → {1, 4, 9, 16, 25}</code></pre>
6567
]]></html>
6668
</documentation>
6769
</command>
@@ -73,7 +75,7 @@ map list {1, 2, 3} using DoubleNumber → {2, 4, 6}</code></pre>
7375
<result type="list"/>
7476
<documentation>
7577
<html><![CDATA[
76-
<p>The <code>using</code> parameter's script object must implement a handler named <code>reduceItem</code> that takes two values as its input and returns a new value as its output.</p>
78+
<p>The <code>using</code> parameter's script object must implement a handler named <code>reduceItem</code> that takes two values as its input and returns a new value as its output. The following example demonstrates how to reduce a list of numbers to the sum of all its items:</p>
7779
7880
<pre><code>script SumNumbers
7981
to reduceItem(partialResult, aValue)
@@ -92,7 +94,17 @@ reduce list {5, 1, 9, 3} using SumNumbers → 18</code></pre>
9294
<result type="list"/>
9395
<documentation>
9496
<html><![CDATA[
95-
<p>This uses AppleScript’s <code>is in</code> operator to determine if each item has already appeared in the list. When processing lists of text, wrap the <code>remove duplicates from list</code> command in <code>considering</code>/<code>ignoring</code> blocks as necessary.</p>
97+
<p>For example:</p>
98+
99+
<pre><code>remove duplicates from list {"A", "b", "c", B", "E", "b"} → {"A", "b", "c", "E"}</code></pre>
100+
101+
<p>Be aware that this command uses AppleScript’s standard <code>is in</code> operator to check if each item has previously appeared in the list. When working with lists of text, for example, you may want to wrap the <code>remove duplicates from list</code> command in an appropriate <code>considering</code>/<code>ignoring</code> block to ensure predictable behavior whenever that code is executed. For example, wrapping the previous command in a <code>considering case</code> block alters the way in which text items are compared:</p>
102+
103+
<pre><code>considering case
104+
remove duplicates from list {"A", "b", "c", B", "E", "b"} → {"A", "b", "c", "B", "E"}
105+
end considering</code></pre>
106+
107+
<p>(Similarly, when working with lists of real numbers, be aware that two fractional numbers that appear identical can sometimes compare as <code>false</code> due to the limited accuracy of that data type. For example, <code>0.7 * 0.7 ≠ 0.49</code>(!) due to tiny imprecisions in the CPU’s floating point math calculations.)</p>
96108
]]></html>
97109
</documentation>
98110
</command>
@@ -105,7 +117,21 @@ reduce list {5, 1, 9, 3} using SumNumbers → 18</code></pre>
105117
<result type="text"/>
106118
<documentation>
107119
<html><![CDATA[
108-
<p><code>slice list theList from i to j</code> is similar to <code>get items i thru j of theList</code>, except that it returns an empty list if the start index is greater than the end index, and doesn’t throw an error if an index is out of range.</p>
120+
<p>This command works similarly to <code>get items i thru j of theList</code>, except that it returns an empty list if the start index is greater than the end index, and doesn’t throw an error if an index is out of range. (Index 0 is still forbidden though, as AppleScript lists are 1-indexed.) For example:</p>
121+
122+
<pre><code>slice list {"a", "b", "c", "d", "e"} from item 4 → {"d", "e"}
123+
124+
slice list {"a", "b", "c", "d", "e"} from item 2 to item -2 → {"b", "c", "d"}
125+
126+
slice list {"a", "b", "c", "d", "e"} from item 3 to item 3 → {"c"}
127+
128+
slice list {"a", "b", "c", "d", "e"} to item 2 → {"a", "b"}
129+
130+
slice list {"a", "b", "c", "d", "e"} from item 10 to item 15 → {}
131+
132+
slice list {"a", "b", "c", "d", "e"} from item 4 to item 3 → {}
133+
134+
</code></pre>
109135
]]></html>
110136
</documentation>
111137
</command>
@@ -122,14 +148,24 @@ reduce list {5, 1, 9, 3} using SumNumbers → 18</code></pre>
122148
</result>
123149
<documentation>
124150
<html><![CDATA[
125-
<pre><code>transpose list {{1, 2, 3}, {4, 5, 6}} → {{1, 4}, {2, 5}, {3, 6}}</code></pre>
151+
<p>The <code>transpose list</code> command treats a list of lists as a 2D matrix, rearranging it so that rows become columns and columns become rows.</p>
126152
127-
<p>To obtain a list of {name, album, artist} sublists for each track in iTunes:</p>
153+
<pre><code>transpose list {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} → {{1, 4, 7}, {2, 5, 8}, {3, 6, 9}}</code></pre>
154+
155+
<p>This command is particularly useful when getting large amounts of data from scriptable applications, as it is much quicker to ask the application to <code>get <var>property</var> of every <var>element</var></code> than to get every element, then iterate over the returned list of references asking for each element’s properties one at a time. For example, to obtain name, album, and artist information for every track in iTunes, then rearrange it into an easier-to-use form:</p>
128156
129157
<pre><code>tell application "iTunes"
130-
set trackInfo to {name, album, artist} of every track
158+
tell every track
159+
set allNames to its name
160+
set allAlbums to its album
161+
set allArtists to its artist
162+
end tell
131163
end tell
132-
transpose list trackInfo</code></pre>
164+
set trackInfo to {allNames, allAlbum, allArtists}
165+
-- trackInfo is a list of form {{name, name, ...}, {album, album, ...}, {artist, artist, ...}}
166+
167+
set trackInfo to transpose list trackInfo
168+
-- trackInfo is now a list of form {{name, album, artist}, {name, album, artist}, ...}</code></pre>
133169
]]></html>
134170
</documentation>
135171
</command>
@@ -146,57 +182,69 @@ transpose list trackInfo</code></pre>
146182

147183

148184
<suite name="Search" code="****">
149-
150-
<command name="find in list" code="Lst:Find" description="return the index(es) of the specified value in a list">
185+
186+
<command name="filter list" code="Lst:Filt" description="check each item in the given list, returning a new list containing only those items that pass the test">
151187
<direct-parameter type="list"/>
152-
<parameter name="value" code="Valu" type="anything" optional="yes" description="the value to find (default: missing value)"/>
153-
<parameter name="using" code="Usin" type="script" optional="yes" definition="the test to perform on each item; if given, the ‘value’ parameter is ignored"/>
154-
<parameter name="returning" code="Retu" type="LFWh" optional="yes" description=""/>
155-
<result>
156-
<type type="integer" list="yes" description="a list of item index(es), or an empty list if no matches are found"/>
157-
</result>
188+
<parameter name="using" code="Usin" type="script"/>
189+
<result type="list"/>
158190
<documentation>
159191
<html><![CDATA[
160-
<pre><code>find in list {"a", "b", "c"} value "b" → {2}</code></pre>
192+
<p>The <code>using</code> parameter's script object must implement a handler named <code>filterItem</code> that takes a value as its input and returns <code>true</code> or <code>false</code> indicating whether or not the item should appear in the output list. The following example demonstrates how to filter a list of numbers to obtain a new list containing only the items that are greater than 18:</p>
193+
194+
<pre><code>script IsOverEighteen
195+
to filterItem(aValue)
196+
return aValue > 18
197+
end filterItem
198+
end script
161199
162-
<p>The <code>value</code> parameter uses AppleScript’s <code>is</code> operator to determine if a list item matches the specified value. e.g. When processing lists of text, wrap the <code>find in list</code> command in <code>considering</code>/<code>ignoring</code> blocks as necessary.</p>
200+
filter list {12, 23, 17, 22, 14} using IsOverEighteen → {23, 22}</code></pre>
163201
164-
<p>For more complex tests, use the <code>using</code> parameter instead. This takes a script object containing a <code>filterItem</code> handler that takes the item to check as its sole parameter and returns <code>true</code> or <code>false</code> to indicate a match or non-match.</p>
165202
]]></html>
166203
</documentation>
167204
</command>
168205

169-
<enumeration name="LFWh" code="LFWh">
170-
<enumerator name="first occurrence" code="LFWF"/>
171-
<enumerator name="last occurrence" code="LFWL"/>
172-
<enumerator name="all occurrences" code="LFWA"/>
173-
</enumeration>
174-
175206

176-
<command name="filter list" code="Lst:Filt" description="check each item in the given list, returning a new list containing only those items that pass the test">
207+
<command name="find in list" code="Lst:Find" description="return the index(es) of the specified value in a list">
177208
<direct-parameter type="list"/>
178-
<parameter name="using" code="Usin" type="script"/>
179-
<result type="list"/>
209+
<parameter name="value" code="Valu" type="anything" optional="yes" description="the value to find (default: missing value)"/>
210+
<parameter name="using" code="Usin" type="script" optional="yes" definition="the test to perform on each item; if given, the ‘value’ parameter is ignored"/>
211+
<parameter name="returning" code="Retu" type="LFWh" optional="yes" description="(default: all occurences)"/>
212+
<result>
213+
<type type="integer" list="yes" description="a list of item index(es), or an empty list if no matches are found"/>
214+
</result>
180215
<documentation>
181216
<html><![CDATA[
182-
<p>The <code>using</code> parameter's script object must implement a handler named <code>filterItem</code> that takes a value as its input and returns <code>true</code> or <code>false</code> indicating whether or not the item should appear in the output list.</p>
217+
<pre><code>find in list {"A", "b", "c", B", "E", "b"} value "b" → {2, 4, 6}
183218
184-
<pre><code>script Over18
219+
find in list {"A", "b", "c", B", "E", "b"} value "b" returning first occurrence → {2}
220+
221+
find in list {"A", "b", "c", B", "E", "b"} value "b" returning first occurrence → {2}</code></pre>
222+
223+
<p>The <code>value</code> parameter uses AppleScript’s standard <code>is equal to</code> operator to compare each list item to the specified value, adding the item’s index to the result list if true. As with <code>remove duplicates from list</code>, remember that AppleScript’s <code>is equal to</code> operation is subject to additional rules and restrictions when comparing certain types. For example, wrapping the previous command in a <code>considering case</code> block alters the way in which text items are compared:</p>
224+
225+
<pre><code>considering case
226+
find in list {"A", "b", "c", B", "E", "b"} value "b" → {2, 6}
227+
end considering</code></pre>
228+
229+
<p>For more complex tests than simple comparison, the <code>using</code> parameter can be used to supply a custom matching handler. Like the <code>filter list</code> command’s <code>using</code> parameter, this takes a script object containing a <code>filterItem</code> handler that takes the item to check as its sole parameter and returns <code>true</code> or <code>false</code> to indicate a match or non-match. For example:</p>
230+
231+
<pre><code>script IsOverEighteen
185232
to filterItem(aValue)
186233
return aValue > 18
187234
end filterItem
188235
end script
189236
190-
filter list {12, 42, 16, 21} using Over18 → {42, 21}</code></pre>
191-
192-
<p>Note that AppleScript specifiers can also be used to filter lists by item type, for example:</p>
193-
194-
<pre><code>every number of {true, -1, 2.5, "42", {99}, 1.0E+6} → {-1, 2.5, 1.0E+6}</code></pre>
195-
237+
find in list {12, 23, 17, 22, 14} using IsOverEighteen returning last occurrence → {4}</code></pre>
196238
]]></html>
197239
</documentation>
198240
</command>
199241

242+
<enumeration name="LFWh" code="LFWh">
243+
<enumerator name="first occurrence" code="LFWF"/>
244+
<enumerator name="last occurrence" code="LFWL"/>
245+
<enumerator name="all occurrences" code="LFWA"/>
246+
</enumeration>
247+
200248
</suite>
201249

202250

318 Bytes
Binary file not shown.

Objects.scptd/Contents/Resources/Objects.sdef

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@
1010
<result type="script"/>
1111
<documentation>
1212
<html><![CDATA[
13-
<h3>About Dictionaries</h3>
1413
1514
<p>Unlike AppleScript records, which are predefined groups of properties whose values are identified by keyword or identifier, dictionary objects are dynamic collections of key-value pairs that can be added and removed at any time. Dictionary keys are typically text values, though numbers, dates, and type and constant symbols can also be used.</p>
1615
1716
18-
<h3>Example Code</h3>
17+
<h3>Examples</h3>
1918
20-
<p>The following example uses a dictionary to store and retrieve RGB color values by name:</p>
19+
<p>The following script uses a dictionary to store and retrieve RGB color values by name:</p>
2120
22-
<pre><code>-- create a new dictionary
21+
<pre><code>use script "Objects"
22+
23+
-- create a new dictionary
2324
set obj to dictionary collection
2425
2526
-- add some key-value pairs
@@ -154,14 +155,15 @@ log obj's getItem("banana") -- Error -1728: "Item not found."</code></pre>
154155
<result type="script"/>
155156
<documentation>
156157
<html><![CDATA[
157-
<h3>About Queues</h3>
158158
159159
<p>Unlike a list, where any item can be accessed at any time, a queue is an ordered sequence of items where items can only be added (“pushed”) to the back of the queue and retrieved/removed (“pulled”) from the front – i.e. items are returned in the exact same order as they were added.</p>
160160
161161
162-
<h3>Example Code</h3>
162+
<h3>Examples</h3>
163+
164+
<pre><code>use script "Objects"
163165
164-
<pre><code>set obj to queue collection
166+
set obj to queue collection
165167
166168
obj's addItem("a")
167169
obj's addItem("b")
@@ -240,14 +242,15 @@ log obj's removeItem() -- Error -1728: "Queue is empty."</code></pre>
240242
<result type="script"/>
241243
<documentation>
242244
<html><![CDATA[
243-
<h3>About Stachs</h3>
244245
245246
<p>Unlike a list, where any item can be accessed at any time, a stack is an ordered sequence of items where items can only be added (“pushed”) and retrieved/removed (“popped”) from the top of the stack – i.e. the most recently added item is returned first, and the oldest added item returned last.</p>
246247
247248
248-
<h3>Example Code</h3>
249+
<h3>Examples</h3>
249250
250-
<pre><code>set obj to stack collection
251+
<pre><code>use script "Objects"
252+
253+
set obj to stack collection
251254
252255
obj's addItem("a")
253256
obj's addItem("b")
@@ -328,12 +331,35 @@ log obj's removeItem() -- Error -1728: "Stack is empty."</code></pre>
328331
<suite name="Timing" code="****">
329332

330333
<command name="timer object" code="Obj:Time" description="returns a new TimerObject">
331-
<direct-parameter type="text" optional="yes" description="an optional name, for reference (default: &quot;&quot;)"/>
334+
<parameter name="named" code="Name" type="text" optional="yes" description="an optional name, for reference (default: &quot;&quot;)"/>
332335
<result type="script"/>
333336

334337
<documentation>
335338
<html><![CDATA[
336-
<p><code>TimerObject</code> script objects define the following handlers:</p>
339+
340+
<h3>Examples</h3>
341+
342+
<p>The following script uses a timer object to measure the time it takes to create 1000 random numbers:</p>
343+
344+
<pre><code>use script "Objects"
345+
use scripting additions
346+
347+
set theTimer to timer object
348+
349+
set n to 1000
350+
theTimer's startTimer()
351+
repeat n times
352+
random number from -99999 to 99999
353+
end repeat
354+
theTimer's stopTimer()
355+
356+
set millisecs to theTimer's totalTime() * 1000 div 1
357+
display alert "Created " & n & " random numbers in " & millisecs & "ms." </code></pre>
358+
359+
360+
<h3>Object Commands</h3>
361+
362+
<p><code>TimerObject</code> script objects recognize the following commands:</p>
337363
338364
<dl>
339365
Binary file not shown.
Binary file not shown.

TypeSupport.scptd/Contents/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>bundleDividerCollapsed</key>
1616
<false/>
1717
<key>bundlePositionOfDivider</key>
18-
<real>682</real>
18+
<real>600</real>
1919
<key>dividerCollapsed</key>
2020
<false/>
2121
<key>eventLogLevel</key>
@@ -25,7 +25,7 @@
2525
<key>positionOfDivider</key>
2626
<real>516</real>
2727
<key>savedFrame</key>
28-
<string>327 33 931 744 0 0 1280 777 </string>
28+
<string>409 33 849 744 0 0 1280 777 </string>
2929
<key>selectedTab</key>
3030
<string>result</string>
3131
</dict>
Binary file not shown.

unittests/date.unittest.scpt

2.32 KB
Binary file not shown.

unittests/list.unittest.scpt

-290 Bytes
Binary file not shown.

unittests/objects.unittest.scpt

122 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)