データ構造

よく読むプログラミングの書籍の一つに『プログラミングの宝箱 アルゴリズムとデータ構造 (C magazine)』という書籍があります。

内容は C 言語なのですが、平易に書かれていてコンパクト(横になって読むときに腕が疲れない)なので個人的に気に入っています。で、できるのかな...という感じでリンクリストを作ってみました。AppleScript で。

 
on run
    set {firstCell, lastCell} to {missing value, missing value}

    repeat with i from 20 to 40 by 2
        set newCell to makeCell(i, missing value)

        if lastCell is not missing value then
            set nextCell of lastCell to newCell
            set lastCell to newCell
        else
            -- 最初のセルの場合
            set {firstCell, lastCell} to {newCell, newCell}
        end if
    end repeat

    set thisCell to firstCell
    repeat
        display dialog (counter of thisCell as text)
        set thisCell to nextCell of thisCell
        if thisCell is missing value then exit repeat
    end repeat
end run

on makeCell(int, cellObje)
    script Cell
        property counter : int
        property nextCell : cellObje
    end script
end makeCell

だからどうだといわれればそれまでなのですが、AppleScript でもリンクリストを作れますね。で、調子に乗って 2 分木も作ってみる。...特に問題もなく動きますね。処理速度的にどうかって問題はあるのですが(詳しく検証していないので分かりません)。

しかし、使いどころがない...。AppleScript の場合、データはアプリケーションが持っていて、だいたい次のようにしてデータを取得します。

tell application "iTunes"
    set trackList to tracks of library playlist 1
end tell

こうやって全体、または一部のデータをリストで取得し、そのリストに対して処理を行う、という感じ。なので、わざわざデータ構造を作る必要がなく、いかにリスト処理を高速に行えるか、ってことが問題になるのですが。

2 分木やマップが使えると、連想配列を作ることができます。AppleScript でこういうデータ構造を作って調べた人っているのでしょうか?

AppleScript はアプリケーションや言語(do shell script や call method を通してシェルや Perl や Objective-C 等)をつなげるためのスクリプト言語なのだから AppleScript 単体でデータ構造を作る必要もない、と言われればそうなのですが、どっちかというと『AppleScript で何かを作る』より、『AppleScript の限界は?AppleScript でどこまでできる』というどうしようもなく退廃的かつ非生産的な事柄に興味が向かってしまうんですね。

ところで。

property countList : {}

on run
    repeat 100 times
        set end of countList to random number
    end repeat
end run

このようなスクリプトをアプリケーションで保存し、暇をみては起動します。すると、サイズ(Finder の情報でみるサイズです)がどんどん増えていきます。counterList にどんどん実数を追加していくのだから当たり前です。では、この増えたサイズを元に戻すにはどうしたらいいのでしょうか?

set couterList to {}

このようにするといいのでしょうか?

AppleScript でよくわからないのはこういったメモリに関して。変数は使われなくなったらその変数に使われているメモリは解放される、と以前何かで目にした記憶があるのですが。では、次のような場合、この変数に使われているメモリは解放されているのでしょうか?

set thisValue to "abcdef"
-- 何らかの処理
set thisValue to missing value

または次のようなスクリプト。

set thisValue to "abcdef"
-- 何らかの処理
set thisValue to null

null ってなんですか?予約語になっているのですが。

thisValue をみてみるといずれも missing value と null が返ってくる。これで使ったメモリを解放できるのでしょうか? C 言語の free() みたいなことってできるのでしょうか?

ハンドラの中で使った変数は、ハンドラが終了したらメモリが解放されるというのも何かでみた記憶があります。だから、メモリ効率のために主要な処理は run ハンドラではなく、ハンドラ内で行う、と。

偉そうに AppleScript のことを書いていても、こういう基本的なことがいまいちよく分かっていません...。

Safari のメール送信

HAPPY Macintosh Developing TIME! さんを見ていたら、3 月 2 日の記事に Safari 2.0 のメール送信機能のことが書かれていた。Safari の 「ファイル」メニューにある「このページの内容をメールで送信」というメニューのことです。

Safari で表示しているページをそのままでメールで送ることができる機能...なんですが、これはどうやら AppleEvent でアプリケーション間通信を行っているらしいのです。

それはともかく、そういえばと思い Safari の用語説明を見てみると...ありました。

tell application "Safari"
    if not (front document exists) then return

    email contents of front document
end tell

email contents という命令が追加されているんでした。なんだろうなと思っていたのですが、これだったんですね。

実行すると Mail で新しいメールを作成します。ただ、デフォルトのメーラーが対応していないと実行できない模様。デフォルトのメーラーが Mail だとこのスクリプトが利用できます。