基本的なテクニック

このセクションでは、js および jsui オブジェクトの Javascript コードを書くことに関する、いくつかの一般的な情報を述べようと思います。

アーギュメント

js の後にファイル名を続けた後、追加のアーギュメントをタイプすることができます。これらのアーギュメントはスクリプトのグローバルコード、または任意の関数中で jsarguments[]と呼ばれる配列のプロパティから得ることができます。jsarguments[0] はスクリプトのファイル名、jsargument[1] が最初のタイプされたアーギュメントにあたります。 jsargumemts.length はタイプされたアーギュメントの数 + 1になります。言い換えると、タイプされたアーギュメントがない場合、jsarguments.length の値は 1 になります。

jsui インスペクタには、arguments フィールドがあります。必要なアーギュメントをここに入力します。フィールドに入力した最初のアーギュメントは、jsarguments[1] でアクセスできます。

js オブジェクトへの入力の取り扱い

Max の js オブジェクトのインレットで受け取るほとんどのメッセージは、同じ名前のメソッドの呼び出しです。これは、Javascript の jsthis オブジェクトのために定義されているもので、最初のシンボルの後に、関数へのアーギュメントとして任意の値を渡すことができます。Max の中で、メッセージ foo 1 2 3 を js オブジェクトに送ると、js オブジェクトの foo() メソッド を呼び出します。言い換えると、これは、foo という jsthis の関数プロパティを探し、1,2,3 をアーギュメントとしてその関数に渡すということになります。foo が次のように定義されている場合、Max ウィンドウへの出力は 1 2 3 になります。

function foo(a,b,c) { post(a,b,c); }

post() は、1つまたはそれ以上の Javascript アイテムを Max ウィンドウに書き出す js オブジェクトの関数です。より詳しくは、後述の jsthis メソッドセクションで述べています。

特別な関数名

msg_int, msg_float

数値に応答する関数を定義する場合、関数には、msg_int、あるいは msg_float という名前を付ける必要があります。

function msg_int(a) { post(a); }

msg_int() だけが定義されている場合、受け取られた float は小数点以下の値を切り捨てられて msg_int() に渡されます。同様に、msg_float() だけが存在する場合、受け取られた整数は、msg_float() 関数に渡されます。

list

Max の リスト、すなわち数値で始まるメッセージを扱うためには、 list という 関数を定義し、これを呼び出します。list 関数の実装では、おそらく Javascript の arguments プロパティを使う必要があるでしょう。そうでないと、様々な長さの入力を扱うことができなくなります。

function list(a) { post("the list contains",arguments.length, "elements"); }

js オブジェクトで受け取られたメッセージシンボルと合致する特定の関数が見つからない場合に実行される anything() 関数を定義することができます。関数を呼び出すメッセージの名前を知りたい場合には、messagename プロパティを使います。どのインレットがメッセージを受け取ったかを知りたい場合には、inlet プロパティを使います。これらの2つのプロパティに関しては、後ほど、「jsthis プロパティ」セクションで検討します。

loadbang

jsjsui オブジェクトを含んだパッチャーファイルがロードされたときに関数を呼出すために、loadbang() という関数を定義します。この関数は、新しい jsjsui オブジェクトをインスタンス化したり、それをパッチャーに追加した時には呼び出されません。これは、jsオブジェクトを含む既存のパッチャーファイルがロードされたときにのみ呼び出されます。言い換えれば、パッチャーにある loadbang オブジェクトが bang を出力するのと同じときということです。max オブジェクトの loadbangdisabled プロパティをテストして、それが true であれば loadbang 関数が何も行わないようにしたいと考えるかもしれません。詳しい情報は、後述の 「Max オブジェクト」というタイトルのセクションを参照して下さい。

getvalueof

getvalueof() という関数を定義することによって、pattr および 関連したオブジェクトを結びつけて、オブジェクトのカレント(現時点)の値を問い合わせることができます。返されるオブジェクトの値は数値、文字列、或いは数値 および(または)文字列による配列が可能です。次はその例です。

var myvalue = 0.25; function getvalueof() { return myvalue; }

setvalueof

setvalueof() という関数を定義することによって、pattr および 関連したオブジェクトを結びつけて、オブジェクトのカレント(現時点)の値をセットすることができます。この値は関数へのアーギュメントとして渡されます。

渡すことができる値の型は、数値、または文字列です。複数の数値または文字列を含む値のためには、setvalueof() メソッドは複数のアーギュメントを受け取ります。jsthis オブジェクトの arrayfromargs() メソッドは含まれる要素の数が変化するような値を取り扱う場合に役立ちます。次はその例です。

function setvalueof(v) { myvalue = v; }

save

save() という関数を定義することによって、スクリプトは js オブジェクトを含んでいるパッチャーファイルにステート(状態)を埋め込むことができます。パッチャーが再ロードされた時に、ステートを復元することができます。

ステートの保存とは、 js オブジェクトが再生成された直後にあなたのスクリプトが受け取るためのメッセージの集合を格納することです。これらのメッセージは、save 関数の中でだけ動作する embedmessage という jsthis の特別なメソッドを使って格納されます。サンプルを見ればこの仕組みがわかるでしょう。

この例では、cowbells というメッセージがあり、このメッセージがオブジェクトが現在持っている カウベル(cowbell)の数をセットするものであると仮定しています。

var numcowbells = 1; function cowbells(a) { numcowbells = a; }

js オブジェクトを含むパッチが保存される場合、その時点でのカウベルの数を保存したいと考えるでしょう。そのためには、save() 関数は次のように定義します。

function save() { embedmessage("cowbells",numcowbells); }

保存されるカウベルの数が 5 だと仮定すると、js オブジェクトは、再ロードされる際に cowbell 関数にアーギュメント 5 を与えて呼び出します。

embedmessage への第1のアーギュメントは、呼び出したい関数の名前の文字列です。それに続く embedmessage へのアーギュメントは、この関数へのアーギュメントを提供するものです。これらの、embedmassage に追加されるアーギュメントは、通常、保存しようとするステートの値になります。

jsthis オブジェクトに対する embedmessage に関する記述は、後述の追加情報を参照して下さい。

予約語

Max の js オブジェクトはオブジェクト自身をコントロールする、openread などのような特別なメッセージに応答します。詳しくは、Max リファレンスマニュアルの js および jsui に関するページを参照して下さい。仮に read という名前の関数をスクリプトの中で定義した場合でも、これは js オブジェクトに送られるメッセージによって直接には実行されません。しかし、関数に read という名前をつけ、その関数を別に定義された Javascript 関数から呼び出すことは可能です。

グローバルコード

既に述べたように、グローバルコードは、定義されている関数の外に存在する Javascript の文からできています。グローバルコードは、スクリプトがロードされたとき、または、それを編集して再コンパイルしたとき、常に実行されます。jsjsui オブジェクトが作られるとき、グローバルコードはオブジェクトが完全に生成される前に実行されます。それは、まだインレットやアウトレットを持たず、パッチャー内で他のオブジェクトとの関係についても知らない状態です。このことは、グローバルコードを使って、必要なインレットやアウトレットの数を定義できるということを意味しています。しかし、同時に、アウトレットはまだ存在していないため、それを使うこともできません。アウトレットが作られた後、何かの初期化処理を行いたい場合、前のセクションで述べた loadband() 関数を書く必要があります。

グローバルコードでは、次のことを行ないます。

  • 必要なインレットとアウトレットの数を設定します( js オブジェクトのプロパティを参照して下さい)
  • ユーザがタイプ入力したアーギュメントに jsarguments[] プロパティによってアクセスします。
  • インレットとアウトレットのためのアシスタンスをセットアップします。
  • グローバル変数を作り、初期化します。
  • Max オブジェクトを使って、グローバルなアプリケーション環境にアクセスし、それをコントロールします。
  • 関数プロパティ local の宣言を(下記参照)、直ちに行ないます。(「実行時における関数スレッドのコントロール」)で説明します)

グローバルコードでは次のことは行ないません。

  • アウトレットからの送信
  • オブジェクトのパッチャーの参照(後述の、Patcher オブジェクトの機能に関する内容を参照して下さい)。

プライベート(ローカル)関数

Max から js へメッセージを送信することによる、Javascript の外部からの関数呼び出しを行ないたくない場合には、その local プロパティを 1 にセットします。例えば、関数 foo() を外部に公開したくないと仮定した場合、次のように行ないます。

foo.local = 1; function foo() { post("what does Pd *really* stand for?"); }

このようにすると、js オブジェクトにメッセージ foo を送った場合、Max ウィンドウに次のようなエラーが表示されるのがわかります。

error: js: function foo is private