2005年 12月 04日

ECMAScript メモ

null == undefined; //=> true
null === undefined; //=> false
"1" == 1; //=> true
true == 1; //=> true
new String("aaa") == new String("aaa"); //=> false
String("aaa") == String("aaa"); //=> true
String(new String("aaa")) == String(new String("aaa")); //=> true
typeof (new String("aaa")) //=> "object"
typeof String("aaa") //=> "string"
typeof "aaa" //=> "string"
var aaa = "aaa";
aaa.prop = "aaa";
aaa.prop //=> undefined;
var aaa = new String("aaa");
aaa.prop = "aaa";
aaa.prop //=> "aaa";

nullundefined の関係がちょっと意外だった。true == 1 はキモい。

String 周りがちょっとよくわかってなくて一応いろいろやってみた。別に否直感的ではない感じ。

2005年 12月 02日

ECMAScript での var

前に書いた気がするけど、ECMAScript の var は Io の setSlot に似ている。

var foo; と書くと、既存のスコープの変数オブジェクトのプロパティに foo が作られる。そして foo = "1"; を書くと、スコープチェインの最初に、作られた foo プロパティを発見するため、そこに代入される。

一方 foo = "1";var 無しにいきなり書いた場合、スコープチェインの末 Global オブジェクトにいきつき Global オブジェクトのプロパティに新たに勝手に foo が作られて代入される。

// Global Code の開始
// Scope Chain: [Global]
// Variable Object: Global
//----
// Variable Object (Global)
// のプロパティ foo に "foo" が代入される。
var foo = "foo";
// 上に同じ
var bar = "bar";
function foobar() {
// Function Code の開始
// 新たに Activation Object (=このコンテキストでのVariable Object) が作られる。
//   (このとき arguments プロパティが自動的にセットされる。)
// Scope Chain: [foobarActivationObj, Global]
//     foobarActivationObj は仮の名前で実際にはアクセスできない。
// Variable Object: foobarActivationObj
// Variable Object (foobarActivationObj)
// のプロパティ foo に "fbfb" が代入される。
var foo = "fbfb";
// Identifier があると Scope Chain を辿る。
// この場合最初の foobarActivationObj に foo を発見できる。
foo = "bfbf";
// この場合最初の foobarActivationObj に bar を発見できないため
// Scope Chain を辿り、Global で bar を発見する。
bar = "bzbz";
// この場合 Scope Chain をたどって、Global に行き着いても発見できないため
// 勝手に Global に baz プロパティを作る。
baz = "baz";
baz.foo = "foo";
with (baz) {
// with は Scope Chain の先頭に
// 指定オブジェクトを突っ込む
// Scope Chain : [baz, foobarActivationObj, Global]
foo = "bar";
// Variable Object は変わらない
var f = "!!!";
}
baz.foo; //=> "bar"
baz.f //=> undefined
f; //=> "!!!"
}
foobar();
foo; //=> "foo" 最初にグローバルで代入したまま
bar; //=> "bzbz" 書き換えられている
baz; //=> "baz" グローバルで一切でてきていないのに存在する

Io の場合 = (updateSlot) はスコープチェインに Identifier を発見できない場合例外が発生する。現在の変数オブジェクトのスロットに突っ込むときは := (setSlot) を使用する。Io は明確な決まりがあるんだけど、ECMAScript は曖昧。気が付くと Global オブジェクトにプロパティがだらだらできたりする。

微妙にわかりにくいのは、Global Code においての Variable Object が Global で、変数に this.foo というようにアクセスできるのに対し、Function Code の Variable Object には一切触れないこと

ときどき関数中で var a = b = c = 0; って書いているのを見かけるけど、この場合の b, c は Global オブジェクトのプロパティ (または途中であるならその変数オブジェクトのプロパティ) になる。var a, b, c; a = b = c = 0; とか書くのが正解。

Prototype Chain もそうだけど、「見えないオブジェクト」がいくつかあってなかなか怖い。

2005年 11月 23日

暇つぶし。色、いろいろ

: ランダムにてきとーな色を発生させるだけのブックマークレット。長時間連打すると眼が疲れる。Firefox でしか見てない。

さぁ! これで新しい色との出会いを体験してみませんか☆

出会い系スパム、のように。

2005年 11月 13日

ECMAScript RegExp $

"\n\n".replace(/$/, "!") //=> "\n\n!"
"\n\n".replace(/$/m, "!") //=> "!\n\n"
"\n\n".replace(/$/mg, "!") //=> "!\n!\n!"

問答無用で \n の前にマッチすると思ってた。m つけなければ \Z っぽく使えるのね。

2005年 11月 12日

entries_kache & wikieditish.cgi

某サイトに entries_kache を導入したんだけど、改行コードが混ざっていてうまく動かない。wikieditish.cgi を使って Win から更新してるせい。めんどくせーなー、とか思いつつ、entries_kache 側で強制的に改行コードを統一させるようにして (if の条件いぢって強制再書き込みさせた) 一件落着……と思いきや動かなかったんだけどプラグインの実行順だった。

wikieditish.cgi.unite_crlf.patch
常に LF で保存するように。
entries_kache.unite_crlf-keep_utime.patch
LF になるように保険。デフォルトの wikieditish.cgi は \n と \r\n が混ざるので。上のやつ修正したあとじゃいらない。あとは、メタデータ書き込むときにファイルの時刻変えるのがうざいので設定しなおす。メタデータ読むんだから関係ないんだけど、精神衛生上よくない。
alternate
全然関係ないけど、代替フレーバーのリンク用プラグイン。<link rel="alternate" type="text/plain" title="Plain Text" href="/$alternate::path.text"/> とかやる。

特定のディレクトリ以下を例外的にトップページとか、一覧に表示させないようにしたい。プラグインがあるだろうけど探すのがめんどい。かといって書こうと思っても Perl のツン具合に萎える。

exclude Not Found

excludez

2005年 11月 11日

Io (iolanguage) いぢくる。

学校で暇つぶしにドキュメント眺めていたらメソッドが増えていたのでちょっといぢってみる。cygwin 版が微妙に古く、mingw 版はまともに動かないとか言ってたら kiyoya さん がビルドしてくれた。ありがたう。

結論から言えば何もできなかった。blosxom 劣化クローンを作れないかなぁと思っていたんだけど、途中で完全にめんどうになってやめた。んで、もうちょい楽なのを考えていたら Tropy が浮かんだので作ってたんだけど、もうちょいってとこで強制終了連打されたので諦めた。Win32 だからかもしれないが。

join の位置がおかしいのはどうにかならないんだろうか。List にあるべきメソッドだよなぁ。

SequenceString の区別がかなりうざい。"literal" は immutable Sequence とか言われて、直接 "literal" replaceSeq("li", "il") とかやることができない。エラーがでる。Sequence clone appendSeq("literal") replaceSeq("li", "il") とかやる必要がある。しかしながら appendSeq にバグがあるっぽく強制終了をよく食らう。よくわからん。

Tropio: Tropy クローン試行の残骸。動きません。動くかもしれないけど俺にはムリ。

2005年 11月 09日

GreaseMonkey スクリプトのデバッグが激しく面倒くさい

はてなの入力欄で動く xml-modeそれのナロー化 css-mode

バグバグだけどなんか今日はもうやる気しない。留年しそうなんだもん。一個単位数え間違えてた。これから軽く必死こいても、あがれる確立20%ぐらい。はぁーうまくいかない。

  • インデントしないエリアにバグ。閉じた直後の RET がおかしい。いままでずっと CDATA で囲ってたから気付かなかった。
  • css-mode の開き括弧直後の RET がおかしい。
  • 補完リストの位置がおかしい。offsetLeft がおかしいのか?
  • はてなのエリアだと右下の広げるやつを一回やっとかないと横に伸びる。はてなの JS とのコンフリクト

物好きの方がいたらどうぞ。eta.user.js

余計なことしなくていいよモード (謎) は M-x c RET

2005年 11月 06日

Event.which, Event.charCode, Event.keyCode

違いがわからんうえに、ちゃんとキーボードと対応してない。英語キーボードだとちゃんと対応してんのか?

e.which, e.charCode, e.keyCode, String.fromCharCode(e.which) の順で、前者が keydown、後者が keypress。環境は Firefox 1.0.7

;
61 0 61 = / 59 59 0 ;
C-;
61 0 61 = / 61 61 0 =
C-+ (Ctrl+Shidt+;) テンキー側の C-+ は問題なし
61 0 61 = / 61 61 0 =
C-:
59 0 59 ; / 59 59 0 ;
C-| (Ctrl+Shift+\)
220 0 220 テ・ / 発生しない
C-a
65 0 65 A / 97 97 0 a
C-F1
112 0 112 p / 0 0 112

差が一定ってわけじゃないし、どうやってマッピングすればいいか見当がつかない。さらに IE だとイベントが発生するタイミングがまた全然違う。帰れ。

Gecko_DOM_Reference:Examples#Example_7:_Displaying_Event_Object_Constants

つまり、正確に処理するにはキーボード配置を自分で作らないとダメなわけか。入力された文字を取得したいのに、入力されたキーしか取得できない。Gecko の e.charCode って charCode じゃないだろ。

それにしてもなんでセミコロンの位置でDOM_VK_EQUALSなんだろう。わからん。

2005年 11月 05日

*-mode in textarea

似非 xyzzy

テキストエリアの管理部分と、モード用機能を分離してみた。似非ミニバッファ搭載!

新しくモード用のオブジェクト (関数) をつくればいい感じに。まぁあんまり綺麗な実装じゃないんだけど……

似非ミニバッファは M-x でフォーカス移動。入力した内容を eval した結果を挿入。M-x new Date() RET とかやれば Sat Nov 05 2005 06:57:29 GMT+0900 みたいに挿入される。ただの eval なのでグローバルに見えてる関数じゃないと使いにくい。

モードはテスト用に xmlc (中身は未実装)。M-x c RET とかやるとモード変更。これは特別に判定させてる。

余談だけど M-x (new Date()).w3cdtf() RET とか眠い。

再び Firefox 限定になりました。IE と Gecko とだと、イベント起きたときの e.which とか e.keyCode とかがバラバラなんだもん。IE は Ctrl+* で keypress が発生しないし。

まぁ色分けできない textarea ではかなり微妙な感じになってきました。XML はインデントさえまともなら色ついてなくてもいい (逆にインデントがまともじゃないと色がついてても読めない) んだけどねぇ。

リージョンをサポート。C-SPC でマーク。C-w (kill-region), M-w (copy-region-as-kill), C-y (yank), C-x n (narrow-to-region), C-x w (widen)

2005年 11月 04日

動的補完 in textarea

textarea で動く劣化コピー xml-mode 続き。

TAB 入力時動的補完リストを表示させてみる。たいして意味がない気がする。xyzzy の dabbrev に相当。

デフォルトの内容で j[TAB] とすると ja, javascript, js が候補にあがる。Down/Up で選択してもう一度 TAB を押すと補完される。

「動的」なので、適当に vfsgergfherkgr とか入力したあと、vfs[TAB] とかやれば補完される。

似非 xml-mode じゃホント意味ないなぁ。っていうかほんとはタグの予測補完をやろうと思ったんだけどめんどくてやめたんです。動的補完のが簡単だけどソレなりの面白さはあるかなと。

関係ないところでは C-x h を入力したときキーバインド一覧をだすようにしてみた。微妙。

直前に動的補完できそうな文字がない場合は、親要素に合わせて開始タグ候補をリストするようにしてみた。

xml.complementList = {
"head" : ['<meta name="" content=""/>', '<link rel="" href=""/>'],
"body" : ['<div class="section"', "<p>", "<address>"],
"div"  : ['<div class="section"', "<p>"],
"p"    : ['<abbr title', "<span class"],
"ul"   : ["<li>"],
"ol"   : ["<li>"],
"dl"   : ["<dt>", "<dd>"]
"pre"  : ["<![CDATA["]
};