リスト以外をループで分割

repeat with 〜 in 〜 の基本

カウンタの参照渡し」にも書いていますが、「repeat with 〜 in 〜 」を細かく見ると、面白いことに気付きます。

repeat with curItem in theValue
	-- 処理
end repeat

 履歴を見ても分かる通り、ループの前にcount命令を内部的に実行しています。さらにcurItemを結果で見てみると、item n of theValue、という値が表示されます。つまり、内部的には次のような処理をしているものと考えられます。

repeat with n from 1 to count theValue
	set curItem to ref (item n of theValue)
	-- 処理
end repeat

 つまり、theValueの部分はリストじゃ無くても、itemとcount命令を受け付ける値ならば、分割されるしループも成立するということです。
 実用的に使う方法はあまり無いと思いますが、変数にリストを入れているつもりで単体の値を設定している場合、思わぬバグを産むことがありますから、丁寧に書くならばinの後の値は「as list」でリストに変換して使った方が安全と言えます。
 具体的には、次のような感じです。

repeat with curItem in theValue as list
	-- 処理
end repeat

文字列を分割する

 itemとcount命令を受け付ける値となると、まず浮かぶのは文字列です。

repeat with curItem in "一文字ずつ取り出します"
	display dialog curItem
end repeat

 内部的には次のようなスクリプトになっていると考えられます。

set theString to "一文字ずつ取り出します"
repeat with n from 1 to count theString
	set curItem to ref (item n of theString)
	display dialog curItem
end repeat

「every item of "一文字ずつ取り出します"」と書けば済むんですが、まーこういうこともできるということです。
 微妙に速度は違うと思いますが。

レコードを分割する

 実はレコードも、itemを持っていてcount命令を受け付けます。
 しかし、受け付けるのevery itemという形式だけです。ですから、次のスクリプトは動きそうで動きません。

set theRecord to {a:1,b:2,c:3}
repeat with curItem in theRecord
	display dialog curItem
end repeat

 inの後を「every item of theRecord」とすれば動きます。

set theRecord to {a:1, b:2, c:3}
repeat with curItem in every item of theRecord
	display dialog curItem
end repeat

 この場合、結局リストに変換しているわけですから、「as list」を使って、次のように書いても同じ動作をします。

set theRecord to {a:1, b:2, c:3}
repeat with curItem in theRecord as list
	display dialog curItem
end repeat

フォルダを分割する

 Finderのフォルダオブジェクトもitemとcount命令を受け付けます。

tell application "Finder"
	repeat with curItem in (choose folder)
		set label index of curItem to 1
	end repeat
end tell

 これも内部的な処理を、スクリプトに書き直してみると、以下のようになると考えられます。

tell application "Finder"
	set theFolder to choose folder
	repeat with n from 1 to count theFolder
		set curItem to (a reference to (item n of theFolder))
		set label index of curItem to 1
	end repeat
end tell

「every item of theFolder」とやればいいだけなんですけど、微妙に楽ができます。
 はっきりいって知らなくても困ることは無いと思います。
 むー、このページって役にたたねぇ。

スクリプトオブジェクト

 先に書いた2つは使える場面もあるとおもいますが、これはちょっと使い方を思い付きません。
 count命令を受け付けるスクリプトオブジェクトは作れますが、itemを受け付けるものは作れません。

repeat with curItem in contents of ScrObj
	curItem -- 値を取りだせない参照(そもそも値を用意してない)
end repeat

script ScrObj	
	on count
		return 4
	end count
end script

と言うことは。このスクリプトは、次のスクリプトと同じ意味しか持たないと言うことになります。

repeat 4 times
end repeat

 最初に発見した時は面白いと思ったんですが、良く考えたら力一杯役に立ちません。悔しいので紹介しました。AppleScriptマニアの人だけでも「ほう」と思っていただければ幸いです。
 もし、「item n of scrObj」に値を設定する方法を思い付いた方は、BBSででも発表していただけると幸いです。


2000-07-27 -2000-11-16 -2002-01-06