Write and Run

it's a simple way, but the only way.

どうしてもObject.observeを使いたい場合

Object.observe とは

俺がダラダラ書くよりこちらを見たほうが素敵ですし、詳しいです。
次世代JavaScriptでデータバインディング: Object.observe() を試す - ぼちぼち日記

というわけで、使いたい。

上記の記事を読めば、とっても便利そうで、今すぐにでも使いたくなります。でもでも、実装されているのは V8 の ver.3.16.0 以降。最新版の Node.js v0.8.18 でも内蔵の V8 は ver.3.11.10 なので使えません(V8 のソース差し替えれば使えないこともない)。

"EXACTLY the same"なライブラリ

jdarling/Object.observe · GitHub
まさかなぁ、と思って検索したらありました。調べてみるもんですね。"Chromium build is MUCH faster"とのことなので、パフォーマンスを期待するのはお門違いですが、とりあえず処理系にネイティブ実装される前の逃げ道としては十分なんじゃないでしょうか。

ということで、これを使って TCP(というか WebSocket)経由でプロセス間でオブジェクトを共有するという何かをちょろっと書いてみようと思います。

JavaScriptのthis

どれがこれであれがどれだ。なんか JavaScript の this について揉めてるらしいので燃料投下することにした。これで何度目だよチキショー。早いとこ学習しやがれ。

this は4種類もない

this は1つだ。

「this はレシーバを指す」
これだけだ。

レシーバの指し方が複数ある

複数あるのはこっちだ。覚えておけ。

  • receiver.method()
  • method.call(receiver)
  • method.apply(receiver)
  • method.bind(receiver)()
  • new Constructor()

上4つは見たままだ。一番下は少し特殊だが、新しく生成されたオブジェクトがレシーバになる。以下の様なコードを思い浮かべるとわかりやすい。

function Constructor () {}

var receiver = Object.create(Constructor.prototype);
receiver.constructor = Constructor;
receiver.constructor();

最後に

こんな記事を書いても、きっと数ヶ月後にはまた同じようなまとめが発生して、それのツッコミエントリがワラワラと立つんだきっと……

ちなみにレシーバはオブジェクト指向用語なので Smalltalk とかを学ぶといい気がします(適当)。

ImageDataはCanvasImageSourceではない(そしてImageBitmapは未実装)

illustea 開発で問題になったことなど。

複数の ImageData を合成したい場合、愚直に for でコピーとかやると極端に遅いので、ネイティブの関数を使って高速化しようということになります。
ちなみに、CanvasRenderingContext2D#putImageData は領域すべてのビットマップを上書きするため、アルファブレンディングは行われず、望んだ結果にはなりません。
希望の結果が得られるのは CanvasRenderingContext2D#drawImage の挙動です。この関数は第1引数に CanvasImageSource 型のデータをとるのですが、ImageData は CanvasImageSource ではなく、直接描画はできません。そこで、CanvasImageSource である ImageBitmap は ImageBitmapSource をソースとして受けられ、ImageData は ImageBitmapSource であることから、ImageData を ImageBitmap に変換してから drawImage で描画することを考えます。
しかし、ImageBitmap は未だ実装されているブラウザがなく、使えません。

次回はこの問題を解決する方法を考えてみます。

illusteaという絵チャの開発をはじめた

環境の変化みたいな感じをきっかけにillusteaという絵チャの開発をスタートしました。

機能概要

  • Javaレスでの筆圧感知
  • 無段階かつユーザー別の Undo/Redo
  • アンチエイリアスの効いた描画
  • 表示倍率の変更
  • 完全なログ保存
  • 自由に変更可能なキャンバスサイズ

当たり前のことですが、大切なこと。その他の機能についても検討中ですが、まだ決定ではないのでここには書いてません。
JavaScriptの実行速度でどこまでのことができるかは不明ですが、やれるところまで粘ろうかと思います。HTML5とかJavaScriptとかNode.jsとか大嫌いなんですけど、それらを使ってやります。マゾです。
開発に際して一番つらいことといえば、ブラウザごとにプリミティブな描画関数の描画結果が違うことで、つまり、getImageData/putImageData を使ってピクセル単位での操作を全て自前で書く必要があるわけで、それが一番つらいです。もちろん、ピクセル単位での合成なんてことまで全部自前でやっていては速度的に全く追いつけないので、表示差が出てもいい場合、またはブラウザ間の差異がない場合にはネイティブの関数で処理をしたり、あるいはその他の手法(DOMによる重ねあわせなど)を駆使する必要があり、この辺の選定にも気を使います。
また、開発に進展があればまとめていこうと思います。

2013年になりました

JSTに生きる方々は時を同じくして2013年を迎えたかと思います。こんな奴ですが今年もよろしくしてやってください。

2012年を振り返って

みんな書いてるみたいですけどめんどいので割愛。なんかいろいろあった気がします。

2013年の抱負

「鼻くそほじりながらアプリケーションをデプロイする」という夢を実現すべくあらゆる努力をしていきます。
とにかく、進学とか就職とか、受験勉強とか研究とか開発とかまぁいろいろ選択しやら進路やらありますが、俺のモットーは「極力怠けて死なない」ことなので、今年もそのとおりに生きようと思います。

CombConfという中高生しか発表しないITカンファレンスを主催してしまった #combconf

あけおめことよろ。人類滅亡にともなってクリスマスなんてものはない。ついでに CombConf2 なんてものもない。
さて、遡ること数日前、具体的には12月23日(日) 13:00-18:00(JST)、人類が滅亡している中、総勢70名ほどの非人類が集まって CombConf が開催されました。真面目な開催報告は公式サイトに掲載するので、ここでは裏話的なことを多めに。

発端

CombConf 自体の発端は去年の夏くらいなのですが、元となる構想については2年ほど前からありました。はじめは id:oidong1 の学校と交流できたらいいなー、なんてことを思ってました。で、そのまま話が流れて去年の夏、CombConf(零)の計画が動きました。参加校は3校。Twitter でお誘いしたら最終的に会場までお貸しくださった開成高校さんと、id:oidong1聖光学院さん、そしてうちの東京電機大学高等学校(長い)です。参加者数的には30弱ほど。場所は開成高校の実験室。それはそれで楽しかったのですが、「終わり際に第2回(というか第1回)もやりたいと思ってます!」とか俺が言っちゃって、帰り際に id:oidong1 と「次は一般人も巻き込んで公に参加者を募ろう」とか盛り上がっちゃって。まさかその場のノリの責任をマジで取ることになろうとは。

第1回、本格始動

真面目に第1回の準備が始まったのは9月末、うちの学校の文化祭が終わった直後でした。そのころはスタッフも俺と id:oidong1 の2人だけで、足らない頭を酷使してだいたいの構想を練りました。開催日や会場、名札の案やコンセプトなどはこのタイミングで決まりました。

id:yosida95 の参加

個人的にはこれが一番大きかったんじゃないかなとおもいます。
CombConf の運営スタッフは基本的に適当な場所のルノアール(渋谷、秋葉原、新宿)でミーティングをしていた、というのがまず前提条件。では id:yosida95 参加当日の話を。
まず、俺と id:oidong1id:yosida95 の学校である東京工業大学附属科学技術高等学校(こっちも長いな)の文化祭にCombConfの広報として来ていました。そして帰り際に「秋葉原のルノアールにいるから放課後来いよ」と声をかけ、俺と id:oidong1 は秋葉原へ。しばらくして id:yosida95 が現れ、俺が「CombConfってのをやってんだけどさ」「あーでこーでさ」と話をしたら、やれ「そうじゃねぇ」だの「あれはどうなってんだ」などとツッコミを入れてくるので、俺が「じゃあスタッフになっちゃいなよ」と言って Google Apps から id:yosida95 のアドレスを作成。wiki のスタッフ名簿にも追加して参加完了。

地獄のクローラー

さて、参加校を集めるためにはどうすりゃいいかと考えた結果、ブルートフォースしかないんじゃないかという結論に。というかレインボーテーブルだったのですが。
まず、レインボーテーブル(中高一貫校偏差値表)を持ってきて、そこから1校ずつ検索。部活紹介ページに「コンピュータ部」またはそれに準じる部活があるかどうかを確認し、wiki にまとめていきました。
さすがに3桁オーダーの数ですから、1人じゃ間に合いません。ここで @ (うちの部の副部長)が参加。スタッフが4人に。で、id:yosida95 以外の3人、3スレッドで検索し続けました。
なかなかおもしろい発見としては、女子校のコンピュータ部率が高いことでしょうか。まぁ、結局1校も来ませんでしたけど。

地獄の内職

地獄シリーズ第2弾。上のクローラーで集めた情報を元に、実際にその学校に案内状を郵送しました。この時の送料はなんと id:oidong1 の部活が部費から捻出してくれました(顧問了解済)。マジありがたい。
さて、内職というのはどういうことかというと、クローリングで集まった学校がちょうど100校ほどあるわけですが、それはつまり100枚の案内状を刷って、100枚のそれを折って、100枚の封筒に入れなければいれないということで……自動化できないんだよなーこれ。
宛名の印刷は id:yosida95プロプライエタリ・ソフトウェアでよしなにやってくれたので俺が書いた LaTeX -> PDF スクリプトは使われませんでした。やれやれ。

番外: 印刷屋

チーフという偉そうな肩書きを冠している俺ですが、実際の仕事は印刷屋です。
当日皆さんが首から下げていた名札、それに貼っていたタグステッカー、入り口で書いた記帳表、スタッフが配っていた名刺、すべて俺の印刷でした。名刺の印刷はガチでやったのでなかなかだと思います(熱い自画自賛)。

まとめ

当日のことはここに書いていないので、当日追加された @ とかいうそうめん職人とか、よさげな写真を大量に撮ってくれた @ とかがどんな仕事をしていたのか紹介できなくて残念ですが、それはまた別の人が書いてくれる気がします。
最後になりましたが、CombConf2はありません。

Gehirn Web Services を使ってみた

※この記事はどうにもステマのように見えます。

お久しぶりです。KOBA789 です。石狩データセンターツアーの帰りの電車の中でこんなエントリを思い出したように書いてます。まるで、誰かに書くことを頼まれたかのように。(※頼まれてません)

正直な話、サーバーなら家にあるし、超自由だし性能いいし Node.js 動くし、別にサーバーとか借りる必要なんて、IP アドレスをあんなことやこんなことに浪費する以外ではまったくないわけですが、それでも申し込んで借りてみようかな、と思ったのは、社長と知り合いだったからと、Node.js が動くらしいからと、それとなんといっても月額315円という安さで、すっかり1050円という初期費用を忘れていたからであります。(これ、マジであとから気づいて焦った)

ということで

まずは Node.js が走らなければお話にならないので、とりあえずインストール方法を……なんて思ったら、いやー、便利なもんですね。

$ rs2 install node

はい、完了。マジかよ。wget, configure, make, make install する気でいたよ。

ということでとりあえず 80 番ポートで Listen してみたいですよね。

$ node
> require('http').createServer(function (req, res) {res.end('hello');}).listen(80);
{ domain: null,
  _events: 
   { request: [Function],
     connection: [Function: connectionListener] },
  _maxListeners: 10,
  _connections: 0,
  connections: [Getter/Setter],
  allowHalfOpen: true,
  _handle: null,
  httpAllowHalfOpen: false }
> 
events.js:71
        throw arguments[1]; // Unhandled 'error' event
                       ^
Error: listen EACCES
    at errnoException (net.js:769:11)
    at Server._listen2 (net.js:892:19)
    at listen (net.js:936:10)
    at Server.listen (net.js:985:5)
    at repl:1:71
    at REPLServer.self.eval (repl.js:109:21)
    at rli.on.self.bufferedCmd (repl.js:258:20)
    at REPLServer.self.eval (repl.js:116:5)
    at Interface.<anonymous> (repl.js:248:12)
    at Interface.EventEmitter.emit (events.js:96:17)

当たり前だった。これ、VPS じゃねーから。

さて、気を取り直して。

f:id:koba789:20121118234527p:plain

f:id:koba789:20121118234514p:plain

なるほどね。開いてるポートはそこですか。

$ node
> require('http').createServer(function (req, res) {res.end('hello');}).listen(61148);
{ domain: null,
  _events: 
   { request: [Function],
     connection: [Function: connectionListener] },
  _maxListeners: 10,
  _connections: 0,
  connections: [Getter/Setter],
  allowHalfOpen: true,
  _handle: 
   { writeQueueSize: 0,
     onconnection: [Function: onconnection],
     owner: [Circular] },
  httpAllowHalfOpen: false,
  _connectionKey: '4:0.0.0.0:61148' }
>

うむ。今度はエラーもないので、別のマシンから確認をして、

$ curl http://koba789.gehirn.ne.jp:61148/
hello
$

こんな感じで良い感じ。

感想

まぁ、315yen/month で IP はもらえないよねー、と思いつつも 80 番で Node.js にアクセス出来ないのはアレだなーと思いました。というかそういう用途なら VPS とか Node.js 専門の PasS なり使えってことですが。ただ、Node.js を何かのバックエンドとして使ったり、内部の WebSocket だけ別ポートで繋げる、なんて使い方はできるので自由度の高いレン鯖として楽しい感じがします。すみません、早とちりでした。ちゃんと 80 番ポートで使えます。WebSocket の実験とかはしてないのでアレですが、その辺も近いうちに調べて記事を書く予定です。

あー、1050円、見落としてたの痛かったわー。