JavaScript で Blosxom, Rhino
http://svn.coderepos.org/share/lang/javascript/blosxom.rhino/
Java との連動が結構たのしい。Java に足りない部分とかめんどうくさい部分と、JS にないシステムの部分とかをうまくくみあわせられてたのしい。
Java がよくわかんなくて文字化けしていたんだけど、結局 js.jar を叩くときの java コマンドに -Dfile.encoding=UTF-8 いれてうまくいった。ただこれって、プログラム側から設定しても反映されない? っぽくてよくわからない……
本体は完全に Rhino に依存してるけど、テンプレートエンジンは依存せずに書いてある
- http://svn.coderepos.org/share/lang/javascript/blosxom.rhino/ejs.js
- http://svn.coderepos.org/share/lang/javascript/blosxom.rhino/template.html
JS のテンプレートエンジンなんて腐るほどあるけど、自分で書いてみるのはやっぱ面白い。今回は new Function("stash", templatecode") みたいにして、ハッシュをわたすとテンプレートをプロセスする関数を動的に生成してみてる (toSource すればコンパイルされた結果をキャッシュできる)。new Function による eval はなんかなんともいえない楽しさがあるなぁと思った。
JS 1.6 相当の関数 (filter とか) ってほぼ必須だよなぁと思った……ないと書けない。
toSource と uneval の出力からわかる Object と Primitive
ためしてみるとすぐわかる違い。前提として、JavaScript では「全てオブジェクトというわけではない」ことを覚えておく必要があります (Ruby との違い)。
uneval("foo");
//=> "\"foo\""
"foo".toSource();
//=> "(new String(\"foo\"))"なぜこのような違いが生まれるか、というと 11.2.1 プロパティアクセス演算子 (Property Accessors) にある
生成規則 MemberExpression : MemberExpression [ Expression ] は次のように評価される:
- MemberExpression を評価。
- GetValue(Result(1)) を呼出す。
- Expression を評価。
- GetValue(Result(3)) を呼出す。
- ToObject(Result(2)) を呼出す。
- ToString(Result(4)) を呼出す。
- 基準オブジェクトが Result(5) でプロパティ名が Result(6) である Reference 型の値を返す。
の ToObject(Result(2)) がキモです。
JavaScript において
"foobar"
typeof "foobar" //=> "string"は、typeof すればわかるように Primitive な String 型であって、String オブジェクトのインスタンス (Object 型) ではありません。プロパティアクセス演算子が使われると、そのつど String オブジェクトへ変換されます。
これは以下のようにすればすぐわかります。
String.prototype.returnThis = function () { return this };
typeof "foobar".returnThis(); //=> "object"
"foobar".returnThis() === "foobar".returnThis(); //=> falseレシーバは "foobar" にみえますが、上の結果と違っています。これはプロパティアクセス演算子の作用で ToObject された結果が this として渡されているからです。(ToObject は処理系の内部関数なので JS から直接はよべません)
ここでなんとなく気付くと思いますが、this は Object 型以外の型には絶対になりません。this を明示して渡せる call や apply でさえ this に対しては ToObject で変換がかかります。
そうなると、Object に変換されるまえの、Primitive な値がほしいときに (そんなケースあんまりありませんが)、ちょっと困るので、そういうときに valueOf() をつかいます。valueOf() って説明だけ読みとなにがしたいのがさっぱりわかりませんが、こいつを使ってやることで、本来のレシーバ (のようにみえる値) をとることができます。
"foobar".valueOf() //=> "foobar"この valueOf() はどんなオブジェクトにも存在するので安心して本来のレシーバを取得することができます。(Primitive 値のラッパオブジェクトでは Primitive 値になるし、そうでなければ単に this をかえすだけです)
valueOf には Date オブジェクトみたいに this 以外をかえすのもあります。
JavaScript の型
前後しますが JavaScript には6個の型があります (処理系内部的/説明的には9個)。
- Undefined / undefined
- Null / null
- Boolean / true, false
- Number / 10, 0xff
- String / "foo", "fumino san love"
- Object / {foo: 123, bar: 456}
Object 型以外は Primitive であり、そう考えると Primitive vs Object の構造が想像できると思います。(リテラル undefined や null, 1, 2, "foo" とかは全部この型に対応しています) JavaScript における「オブジェクト」は Object 型の値のことで、Object 型以外は「プロパティ」や「メソッド」を持ったりはしていません。
プロパティアクセス演算子は Object 型へ必ず変換しますが、そのとき使われる ToObject は、undefined と null のときに TypeError をなげます。(この変換のおかげで Primitive 値の多くはオブジェクトのように扱うことができます)
割とよくみるであろう
TypeError: null has no properties TypeError: undefined has no properties
は、この ToObject への変換時におきているものです (殆どないし全部)。もし JavaScript でも Ruby と同じように「全てがオブジェクト」であるならば、上のようなエラーは絶対に起きないはず (オブジェクトであれば no properties はありえない) ですし、Object に定義されているメソッドが null や undefined に対しても使えるはずです。
null.toString();
undefined.valueOf();実行しなくてもわかるようにこのコードは TypeError がでます。JavaScript では「全てがオブジェクトというわけではない」ことは、この TypeError の背中が物語っています。
Tree Style Tab いい!
https://addons.mozilla.org/en-US/firefox/addon/5890 (SandBox にはいってる)
そろそろ Fx3 で縦おきタブデキナイカナーとおもってさまよってたら Tree Style Tab でできた……piroさん++
Mac のテーマだとタブの高さがちょっとたりなくてセレクトしたときに outline がはみだしてしまうので、Stylish で
@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
.tabbrowser-tab {
height: 2.2em !important;
}
.tabbrowser-tab label {
font-size: 90% !important;
}こんなん書いた。
なんか Opera と同じようなレイアウトにしたら (Opera は左にタブ縦置きにしてる) Fx がはやくなったように感じるプラセボ
それにしてもツリーが思ったより便利><
>
Windows 再インストール
たいして使ってないのに再インストール…… Windows Update でエラーでて (なんか証明書関係のエラーで、対策もひとおりしてみたんだけどだめだった。)
http://subtech.g.hatena.ne.jp/cho45/20070927/1190891651
- Chipset Driver Windows 2000 用のやつ (from SC440 付属CD)
- reboot
- イーサネットコントローラ (ドライバの更新で CD を検索させる)
- reboot
- nVidia GeForce 6 系のドライバをインストール (via Internet)
- reboot
- WPCRSET 自動起動 ( Bus=0 Device=28 Function=0 Register=05h Data=00h )
- Windows Update (再起動しまくり)
- Avast インストール
- US Keyboard http://subtech.g.hatena.ne.jp/cho45/20070928/1190965320
- Firefox 3b1
- Lhaplus
- mayu
- SKKIME http://subtech.g.hatena.ne.jp/cho45/20070929/1191020138
- ~/fonts/* を %fonts% へコピー
- foobar2000
- Columns UI
- ~/foobar.fcs からインポート
- Last.fm インストール
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters] "LayerDriver JPN"="KBD101.DLL" "OverrideKeyboardIdentifier"="PCAT_101KEY" "OverrideKeyboardType"=dword:00000007 "OverrideKeyboardSubtype"=dword:00000000 "LayerDriver KOR"="KBD101A.DLL"
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] "Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,1d,00,3a,00,00,00,00,00
JSDeferred
そういえば、あらかじめデータは取得しておきたいけど、表示自体は遅延したい、みたいな場合 (ホバーツールチップみたいなやつ) にもめっさつかえるなぁねむい。
var d = null;
anElement.addEventListener("mouseover", function (e) {
if (d) d.cancel();
// http.get はおこなわれるが、少なくとも 1 秒遅延してから表示する
d = parallel({
wait: wait(1),
value: http.get("foobar")
}).next(function (o) {
show(e.pageX, e.pageY, o.value); // show はどっかで定義
});
}, false);
anElement.addEventListener("mouseout", function (e) {
if (d) d.cancel();
}, false);これだとまだまずいけど (mouseover が発生しまくるから//http.get をキャッシュつきにラップすればスマートかも) wait(1) してからロードしにいくみたいにするより、これだと同時によみこむから待ち時間がへる (その変わりリクエストが必ずとんでサーバに負荷かかる)
Trac で特定のコミッタの timeline フィード
http://mk-colors.org/scrap/2007/12/075208 みたいにあるとおり標準でそのまんまなのはできないっぽい。
けど http://dev.ariel-networks.com/column/tech/tracreport-tips/ よんでて、あーそっかーとおもったので report つかってフィード生成してみた。
- http://coderepos.org/share/report/9
- 例: http://coderepos.org/share/report/9?format=rss&AUTHOR=dankogai
SELECT
"../changeset/" || rev AS ticket,
rev || ": " || message AS summary,
time AS _changetime,
time AS created,
author AS _reporter,
message AS _description
FROM revision WHERE author = '$AUTHOR' ORDER BY rev+0 DESC LIMIT 50;こんなん。ticket がフィードのリンクにつかわれるみたい。ticket/#{ticket} にリンクされるので相対パスつかって changeset にしてる。詳細は TracReports にいろいろ書いてあった。
✖
- よりよい Ruby 用のドキュメント記法
- doctest
- よりよい JavaScript 用のドキュメント記法
- ソースコードとの分離
- doctest
Deferred チェインのときの setTimeout
http://coderepos.org/share/browser/lang/javascript/jsdeferred/trunk/jsdeferred.js?rev=2761#L119
の setTimeout について、スタックを消費するからこうしている、と書いたのは、next の問題で無駄な Deferred を生成していたせい ( http://subtech.g.hatena.ne.jp/cho45/20071202/1196571302 ) で、Stack over flow がでたことがあったからなんだけど、next の問題は解決したので、あらためて必要かどうか考えたらいらない気がした。
でもって http://coderepos.org/share/changeset/2817 はずしてみた。Safari はスタックサイズがかなりちっちゃくて、600?くらいの再帰でオーバーフローするからテストでは loop(1000 を実行してちゃんと戻ってくるかをテストしてる (loop は内部で next と call よんでる)。
この修正で、チェイン間ではブラウザへ処理がもどらなくなる。もどしたいなら wait(0) を return すればもどせる。