Chrome 43 からは DOM attribute が prototype プロパティに変更される

DOM Attributes now on the prototype chain

それによって…

  • hasOwnProperty()/getOwnPropertyDescriptor()/JSON.stringify() で、DOM attribute が検出できなくなる
  • read-only な DOM attribute を上書きしようとすると例外を投げるようになる

だそうな。
他人が作ったフレームワークは特に、それで動かなくなったりするものも出てくるかもしれないので頭の片隅に置いておくとよい。

2015年からは「エッセンシャル思考」で

あけましておめでとうございます。本年もよろしくお願いいたします。
当サイトもしばらく更新しておりませんでしたが、私は元気に日々仕事し、悩み、そして楽しんでおります。

昨年の暮れに読んだ『エッセンシャル思考 最少の時間で成果を最大にする』という本が、自分にドストライクな内容だったので年始にかけて3回も読んでしまった。自分に思い当たることがズバズバと書かれてあり「これ俺のために書かれた本か!」となった。

その内容を3行で書くならば

  • 意識的に選択して生きること。あなたが選択しなければ他人があなたのすることを決めてしまうだろう
  • すべてやることはできない。減らして、少数に集中せよ
  • 時間には余裕を持って、健康的に、今を大切に生きなさい

ということだ。
そんな内容を簡潔に、とても分かりやすい構成で書いてある。

日本語訳も大変すぐれており、海外著作の翻訳本にありがちな難解な文章になっていない。最初から日本語で書かれていたかのように、内容が自然に頭に入ってくる。
たとえば上記の文において、「優れており」でなく「すぐれており」と書いたように、文中の漢字の利用が制限されており、それも読みやすさの一助となっている気がする。 (訳者は高橋璃子さんとある)

「時間がない」と嘆くビジネスマンには必読の書である。あるいはビジネスマンでなくとも「寝る時間がない」といつも睡眠不足に悩む紳士淑女も是非読むべきだ。

というわけで2015年はよりいっそう「意識的に」生きていこうと思う。

Maxのドキュメントを読む その2(Javascript in Max 02 – Basic Techniques)

JavaScript in Max ドキュメントの日本語備忘録的なエントリー第2弾。

Global Methods

Document

以下のメソッドはグローバルコンテキストにあり、どこでも使うことができる。


messnamed (Max object name, message name, any arguments)

Document

グローバルシンボルに紐付けてネーミングされた Max オブジェクトにメッセージを送る。例えば receive オブジェクトなど。 以下の例は “jsmessage” と名付けられたオブジェクトに “hogehoge” とメッセージを送る例である。

Test Code

function loadbang () {
    messnamed("jsmessage", "hogehoge");
}

messnamed


cpost (any arguments)

Document

コンソールにメッセージを出力する。引数とかは次項の post() と同じ。

Test Code

function foo(a, b, c) {
  cpost(a, b, c);
}
function loadbang() {
  foo('foo', [ 'a', 'b', 'c' ], { 'hoge': 'fuga' });
}

How Input to the js Object is Handled


なお、グローバルスコープは jsthis オブジェクト(ブラウザ JavaScript でいうwindow オブジェクト)とドキュメントには書いてあるが、jsthisオブジェクトを呼び出そうとしてもMAXウィンドウに Javascript ReferenceErrod: jsthis is not defined と出て怒られる。 一方、一般的な this オブジェクトは機能している。

function foo() { }
post(this.foo === foo); // 1 (true)

post (any arguments)

Document

MAXウィンドウにメッセージを出力する。 \n を含めると改行になる。 post() を新しい行から初めても改行が出力される。

Test Code

function foo(a, b, c) {
  post(a, b, c);
}
function loadbang() {
  foo('bar', [ 'a', 'b', 'c' ], { 'hoge': 'fuga' });
}

How Input to the js Object is Handled


The jsthis Object

Document

Browser JavaScript だと ”window” にあたるもの。 jsthis オブジェクトはグローバルコードにおける ”this” を表す。グローバルコードで関数を定義すればそれは jsthis のメソッドになり、変数を定義すれば jsthis のメソッドになる。jsthis オブジェクトは以下のようなビルトインプロパティとメソッドを持つ。

autowatch (Number, get/set)

Document

これはとりわけ、1つのソースファイルからいくつかの js インスタンスを作っていて、ソースファイルを変更したらすべてのインスタンスを更新したいような時に便利。外部のテキストエディタでソースファイルを書いている場合も、これを使えばパッチ中の js オブジェクトは自動的に再コンパイルされる。 デフォルトではこの autowatch は 0 (off) に設定されている。on にしたいときはグローバルコード中で行うことがベスト。

box (Maxobj, get)

Document

js オブジェクトを含む Maxobj を返す。jsui オブジェクトからオブジェクトボックスの長方形を取得する際に便利。 詳しくは the Max Object を参照のこと

editfontsize (Number, get/set)

Document スクリプトを編集するウィンドウのフォントサイズを制御する。グローバルコードで書くと、テキスト編集のデフォルトフォントサイズ(Maxウィンドウのフォントサイズ)が変更される。

inlet (Number, get)

Document 関数の実行中、 inlet プロパティには、その関数を呼び出したメッセージを受け取ったインレット番号が格納されている。 この番号は一番左のインレットから0で始まる。 グローバルコード中ではこのプロパティは 0 になる。

inlets (Number, get/set)

Document インスタンスがいくつのインレットを持つべきかを指定する。”inlets” プロパティはグローバルコード中で指定しなければ効果がない。指定されなかった場合、インレットを1つ持ったオブジェクトが作られる。

Test Code 1

function msg_int(a) { // a == 1
  post(a); // 1
}

msg_int

Test Code 2

function msg_int(a) { // a == 1
  post(a); // 1
}
function msg_float(a) { // a == 1.23456
  post(a); // 1.23
}

msg_float


list

Document

inlet に最初の値が int もしくは float の list が入力されると list() が呼ばれる。 上記の例のように最初の値が String の list はその String 名の関数が呼ばれる。

Test Code 1

function list(a, b, c) { // a == 1, b == 2, c == hoge
  post(a, b, c); // 1 2 hoge
  post(arguments.length); // 3
}

list


anything

inlet に入力されたものに該当する function が定義されていなかった場合、anything() で受け取ることができる。例えば int が入力されたときに msg_int() が未定義だったら anything() が呼ばれる。float や list でも同様。
anything() 内部では messagenameinlet 変数が定義されており、それぞれ inlet に入ったメッセージの種類と、inlet 番号を参照できる。

Test Code 1

function anything(a, b, c) { // a == 1, b == 2, c == hoge
  post("messagename", messagename); // messagename list
  post("inlet", inlet); // inlet 0
  post("anything", a, b, c); // anything 1 2 hoge
}

anything


loadbang

Document

loadbang() はパッチ起動時に呼ばれる。js オブジェクトや jsui オブジェクトを追加した時ではなく、あくまでそれを予め含むパッチ起動時に呼ばれることに注意。
Cmd+Shiftを押しながらパッチを起動すると loadbang を無効化できるが、無効になっているかどうかは max.loadbangdisabled プロパティに 1 が入っているかどうかで分かる。

Test Code 1

function loadbang() {
  if (max.loadbangdisabled == 1) {
    post("no loadbang");
  } else {
    post("loadbang!");
  }
}
function bang() {
  post("bang!");
}

普通にパッチを起動した場合
loadbang

Cmd+Shiftを押しながらパッチを起動した場合
noloadbang


getvalueof

Document

JavaScript 内で定義した変数の値(String か Number)を pattr 関連オブジェクトから呼び出せるようにする関数。 → pattr オブジェクトのことがよく分からないので、テストコードが書けない。後で復習する。


setvalueof

Document

pattr 関連オブジェクトから JavaScript 内に変数(Number か String)をパスできるインターフェースを提供する関数。 value が複数の場合、jsthis オブジェクトの arrayfromargs() メソッドで引数を扱うと良いとのこと。
→ pattr オブジェクトのことがよく分からないので、テストコードが書けない。後で復習する。


save

Document

save() を定義すると、JavaScript 内の状態をパッチに保持することができる。 パッチが再読み込みされると、JavaScript 内の状態が復元される。

save() 内だけで使える embedmessage() を使い、値を保存する。

  • embedmessage() の第1引数には保存された値を渡したいコールバック関数名を文字列で渡す
  • embedmessage() の第2引数以降には保存したい値を渡し、これがコールバック関数の引数に渡される

Test Code 1

var valuetosave = 0;
function foo(v) {
  valuetosave = v;
}
function save() {
  embedmessage("callback", valuetosave);
}
function callback(v) {
  valuetosave = v;
  post(v);
}

foo 1 メッセージを送ったあと、パッチを再起動した場合
save

foo 2 メッセージを送ったあと、パッチを再起動した場合
save


notifydeleted

Document

js オブジェクトが削除されたときに呼ばれる

Test Code 1

function notifydeleted() {
  post('js object was deleted.');
}

notifydeleted


Global Code

Document

グローバルスコープに書かれたコードは編集された後、スクリプトがロードされるかコンパイルされたタイミングで評価される。 js / jsui オブジェクトが完全に作られる前に評価される。 js オブジェクトがいくつ inlet / outlet を持つかはグローバルコードからは分からない。これはグローバルコードから inlet / outlet をいくつにするか定義できることを意味する。しかし言い換えれば、まだ outlet が存在しなければ、使うことはできない。 初期化処理を書きたい場合は loadbang() の中に書くべし。

グローバルコードでやるべきこと

  • inlet / outlet の数を定義する
  • jsarguments[] プロパティ(js オブジェクトの引数)にアクセスする
  • inlet / outlet の値の操作
  • グローバル変数の定義と初期化
  • グローバルアプリケーション環境にアクセス&操作するため、Max オブジェクトを使う

グローバルコードでやるべきでないこと

  • outlet から何か出力すること
  • js オブジェクトが置かれたパッチ側を参照しようとすること

Private (Local) Function

Document

js オブジェクトへの inlet メッセージから参照されたくないローカル関数を作りたい場合、local プロパティに 1 をセットする。

Test Code 1

function foo() {
  post("Welcome to 'foo' method!");
}
foo.local = 1;

private function


未完

Maxのドキュメントを読む その1 (Javascript in Max 01 – Basic Techniques)

最近 Max というビジュアルプログラミング言語を学んでいる。js / jsui オブジェクトというのがあり、その中で JavaScript が書ける、ということでドキュメントを読んでいる。 正直流行っていない言語なので情報が少なく、とにかく公式ドキュメントを読むしかないのである。

読んだドキュメントを備忘録的にエントリーしておく。その第1弾。


注意事項

  • JavaScriptファイルを更新した場合、MAXパッチを開き直さないと変更が反映されない

Arguments

Document

js オブジェクトに渡した引数は JavaScript 内では jsarguments[] 配列で参照できる。

  • jsarguments[0] => ファイル名 (required)
  • jsarguments[1] 以降 => その他の引数 (optional)

ということになる。

Test Code

function bang() {
  post(jsarguments[0], jsarguments[1], jsarguments[2], jsarguments[3]);
}

Arguments test


How Input to the js Object is Handled

Document

js オブジェクトの inlet に foo 1 2 3 というメッセージを送った場合、グローバルスコープの foo() 関数を引数 1,2,3 と共に実行するということになる。

Test Code

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

How Input to the js Object is Handled

なお、グローバルスコープは jsthis オブジェクト(ブラウザ JavaScript でいう window オブジェクト)とドキュメントには書いてあるが、jsthisオブジェクトを呼び 出そうとしてもMAXウィンドウに Javascript ReferenceErrod: jsthis is not defined と出て怒られる。なんだこれは。 一方、一般的な this オブジェクトは機能している。

function foo() { }
post(this.foo === foo); // 1 (true)

Special Function Names

Document

msg_int, msg_float

Document

inlet に int が入力されると msg_int() が呼ばれる。inlet に float が入力されると msg_float() が呼ばれる。msg_float() が未定義の場合、 msg_int() が代用で呼ばれるが、少数点以下は切り飛ばされる。 なお msg_float() は少数点第3位以下を受け取ることができない。

Test Code 1

function msg_int(a) { // a == 1
  post(a); // 1
}

msg_int

Test Code 2

function msg_int(a) { // a == 1
  post(a); // 1
}
function msg_float(a) { // a == 1.23456
  post(a); // 1.23
}

msg_float


list

Document

inlet に最初の値が int もしくは float の list が入力されると list() が呼ばれる。 上記の例のように最初の値が String の list はその String 名の関数が呼ばれる。

Test Code 1

function list(a, b, c) { // a == 1, b == 2, c == hoge
  post(a, b, c); // 1 2 hoge
  post(arguments.length); // 3
}

list


anything

inlet に入力されたものに該当する function が定義されていなかった場合、anything() で受け取ることができる。例えば int が入力されたときに msg_int() が未定義だったら anything() が呼ばれる。float や list でも同様。
anything() 内部では messagenameinlet 変数が定義されており、それぞれ inlet に入ったメッセージの種類と、inlet 番号を参照できる。

Test Code 1

function anything(a, b, c) { // a == 1, b == 2, c == hoge
  post("messagename", messagename); // messagename list
  post("inlet", inlet); // inlet 0
  post("anything", a, b, c); // anything 1 2 hoge
}

anything


loadbang

Document

loadbang() はパッチ起動時に呼ばれる。js オブジェクトや jsui オブジェクトを追加した時ではなく、あくまでそれを予め含むパッチ起動時に呼ばれることに注意。
Cmd+Shiftを押しながらパッチを起動すると loadbang を無効化できるが、無効になっているかどうかは max.loadbangdisabled プロパティに 1 が入っているかどうかで分かる。

Test Code 1

function loadbang() {
  if (max.loadbangdisabled == 1) {
    post("no loadbang");
  } else {
    post("loadbang!");
  }
}
function bang() {
  post("bang!");
}

普通にパッチを起動した場合
loadbang

Cmd+Shiftを押しながらパッチを起動した場合
noloadbang


getvalueof

Document

JavaScript 内で定義した変数の値(String か Number)を pattr 関連オブジェクトから呼び出せるようにする関数。 → pattr オブジェクトのことがよく分からないので、テストコードが書けない。後で復習する。


setvalueof

Document

pattr 関連オブジェクトから JavaScript 内に変数(Number か String)をパスできるインターフェースを提供する関数。 value が複数の場合、jsthis オブジェクトの arrayfromargs() メソッドで引数を扱うと良いとのこと。
→ pattr オブジェクトのことがよく分からないので、テストコードが書けない。後で復習する。


save

Document

save() を定義すると、JavaScript 内の状態をパッチに保持することができる。 パッチが再読み込みされると、JavaScript 内の状態が復元される。

save() 内だけで使える embedmessage() を使い、値を保存する。

  • embedmessage() の第1引数には保存された値を渡したいコールバック関数名を文字列で渡す
  • embedmessage() の第2引数以降には保存したい値を渡し、これがコールバック関数の引数に渡される

Test Code 1

var valuetosave = 0;
function foo(v) {
  valuetosave = v;
}
function save() {
  embedmessage("callback", valuetosave);
}
function callback(v) {
  valuetosave = v;
  post(v);
}

foo 1 メッセージを送ったあと、パッチを再起動した場合
save

foo 2 メッセージを送ったあと、パッチを再起動した場合
save


notifydeleted

Document

js オブジェクトが削除されたときに呼ばれる

Test Code 1

function notifydeleted() {
  post('js object was deleted.');
}

notifydeleted


Global Code

Document

グローバルスコープに書かれたコードは編集された後、スクリプトがロードされるかコンパイルされたタイミングで評価される。 js / jsui オブジェクトが完全に作られる前に評価される。 js オブジェクトがいくつ inlet / outlet を持つかはグローバルコードからは分からない。これはグローバルコードから inlet / outlet をいくつにするか定義できることを意味する。しかし言い換えれば、まだ outlet が存在しなければ、使うことはできない。 初期化処理を書きたい場合は loadbang() の中に書くべし。

グローバルコードでやるべきこと

  • inlet / outlet の数を定義する
  • jsarguments[] プロパティ(js オブジェクトの引数)にアクセスする
  • inlet / outlet の値の操作
  • グローバル変数の定義と初期化
  • グローバルアプリケーション環境にアクセス&操作するため、Max オブジェクトを使う

グローバルコードでやるべきでないこと

  • outlet から何か出力すること
  • js オブジェクトが置かれたパッチ側を参照しようとすること

Private (Local) Function

Document

js オブジェクトへの inlet メッセージから参照されたくないローカル関数を作りたい場合、local プロパティに 1 をセットする。

Test Code 1

function foo() {
  post("Welcome to 'foo' method!");
}
foo.local = 1;

private function

grunt-contrib-jshint の設定

Gruntfile.coffee に以下のように書く。

grunt.loadNpmTasks 'grunt-contrib-jshint'
grunt.initConfig(
  jshint:
    main:
      options:
        jshintrc: true
      src: [ 'app' + sitePath + 'js/script.js' ]
  ...
  watch:
    js:
      options:
        livereload: true
      files: [ 'app' + sitePath + 'js/*' ]
      tasks: [ 'jshint' ]
)

options.jshintrc = true を設定するとそれ以外の options は無視され同階層に置かれた .jshintrc ファイルを参照するようになる。

.jshintrc はJSON形式で記述する。
結果的に以下のような設定に。

{
  "node": true,
  "esnext": true,
  "bitwise": true,
  "camelcase": true,
  "curly": true,
  ...
  "globals": {
    "window": true,
    "document": true,
    "jQuery": true,
    "$": true,
    "_": true,
    "Backbone": true
  },
  "-W116": true,
  "-W041": true
}

globals には「XXXグローバルオブジェクトがない」的な警告が出るときに、予め「このグローバルオブジェクトはあるから、警告出すな」とJSHint側に伝えておく設定。
-WXXX: true は特定のエラーを無視したいときに追加する設定。このエラーコード(ドキュメントの原文では warning code)は grunt --verbose(もしくは grunt -v)として verbose モードで Grunt タスクを起動すると表示されるようになる。

表示例:

^ [W116] Expected '!==' and instead saw '!='.

ここでは W116 というのが warning code なのでそれを "-W116": true のように options に追加すると、警告は出なくなる。