5

Script Editor を使用して自動化のための新しい JS で遊んでいます。次の最後の行でエラーが発生します。

var iTunes = Application("iTunes");
var sources = iTunes.sources();
var library = sources.whose({name : "Library"});

ソース配列が期待どおりであることを確認しました (2 つの要素、1 つはname「ライブラリ」、もう 1 つは「インターネット ラジオ」)。しかし、その最後の行はError on line 3: TypeError: undefined is not a function (evaluating 'sources.whose({name : "Library"})').

私が知る限り、 functionの正しい構文を使用していwhoseます。(私も同じ結果に明示的な句を試しました_equals。) 私は何が間違っていますか?

4

4 に答える 4

8

私は何を間違っていますか?

簡単な答え: それはあなたのせいではありません。JXA のドキュメントは嘘の袋です。

より長い説明: オブジェクトの要素は配列とは何の関係もありません。これらは、オブジェクト グラフ内の 1 対多の関係を表します。この場合は、sourceオブジェクトと 0 個以上のlibraryオブジェクトの間です。

多くの関係は、基礎となる実装の包含階層を反映している可能性がありますが、そうする義務はありません。たとえば、Finder を使用すると、デスクトップ上のオブジェクトを複数の方法で識別できます。

items of folder "Desktop" of folder "jsmith" of folder "Users" of disk "Macintosh HD" of app "Finder"
items of folder "Desktop" of folder "jsmith" of folder "Users" of startup disk of app "Finder"
items of folder "Desktop" of home of app "Finder"
items of folder "Macintosh HD:Users:jsmith:Desktop" of app "Finder"
items of desktop of app "Finder"
items of app "Finder"
[etc.]

Apple イベント ベースのアプリケーション スクリプトは、リモート プロシージャ コールと単純なファースト クラス クエリに基づいています。表面的な外観に関係なく、OOP ではありません。これは、クエリを読みやすく、書きやすくするための構文糖衣にすぎません。

...

sourceこの場合、2 行目は、iTunes アプリケーション内の各オブジェクトを識別するクエリ オブジェクト (ObjectSpecifiers) のリスト (配列) を取得するように iTunes に指示しています。

var iTunes = Application("iTunes");
var sources = iTunes.sources();

配列を取得すると、それを使用してさらにクエリを作成することはできません。これは、JavaScript 自体がクエリを作成する方法を認識していないためです。あなたが実際に欲しいのはこれです:

var iTunes = Application("iTunes");
var sourcesSpecifier = iTunes.sources;
var librarySpecifier = sourcesSpecifier.whose({name : "Library"});

sourceこれにより、 「Library」という名前のすべてのオブジェクトを識別するオブジェクト指定子が得られます。( 「Library」という名前の最初の オブジェクトのみを指定する場合は、 の代わりに メソッドを使用します。より簡単です。)sourcebyNamewhose

--

個人的には、JXA の Apple イベント ブリッジの実装は、そのドキュメントと同様に、ほとんどが Lame と Fail で構成されているため、これはやや学術的であると考えています。ほとんどの場合、ある程度までは機能し、それを超えるとうんちをします。あなたのニーズがささやかなものであり、それで「十分」である場合は、より多くの機能を実行できますが、AppleScript に固執する重要な場合は、適切に機能する唯一のサポートされているソリューションです。

(AppleScript/JXA チームも、そのようながらくた作業の言い訳はできません。数か月前にほぼ完成した JavaScriptOSA 参照実装を彼らに送り、彼らが望むように勉強したり盗んだりしましたが、彼らはそれを完全に無視しました。これはずっと前に解決された問題です。)

于 2014-11-23T19:12:28.220 に答える
0

JavaScript for Automation リリース ノート Mail.inbox.messages.whose(...)の例に基づいて、次のように動作するはずです。

var iTunes = Application('iTunes');
var filtered = iTunes.sources.whose({name : 'Library'});

「クエリを含むオブジェクト」を使用した「特別なwhoseメソッド」の明らかな目標は、OS X オブジェクト階層から選択した項目 (または項目参照) のみを結果の JavaScript 配列に取り込むことによって効率化することです。

ただし、... whoseJXA の機能には、以前の OS X v10.10 リリースでいくつかのバグがあるように見えました。

したがって、問題の配列は小さい (つまり 2 項目) ため、要素を JS 配列として取得した後、JavaScript 側でフィルタリングを高速かつ確実に行うことができます。

回避策の例 1

var iTunes = Application('iTunes');
var sources = iTunes.sources();
var librarySource = null;
for (key in sources) {
    var name = sources[key].name();
    if (name.localeCompare("Library") == 0) {
        librarySource = sources[key];
    }
}

回避策の例 2

var iTunes = Application('iTunes');
var sources = iTunes.sources();
function hasLibraryName(obj) {
    var name = obj.name();
    if (name.localeCompare("Library") == 0) {
        return true;
    }
    return false;
}
var filtered = sources.filter(hasLibraryName); 
于 2015-05-01T10:14:57.537 に答える