SSブログ
JavaScript ブログトップ

関数のマーシャリング [JavaScript]

「分散関数呼び出し」 [1] という記事を読んで、JavaScript でも特に環境までマーシャリングされるということは無いのではないかと思った。

js>  f = function (x) { return function (y) { return x + y } }
function (x) {
    return (function (y) {return x + y;});
}
js> g = f(3)
function (y) {
    return x + y;
}
js> eval('h=' + g.toSource())
function (y) {
    return x + y;
}
js> g(2)
5
js> h(2)
typein:3: ReferenceError: x is not defined

単に関数定義(含仮引数)の(環境はともかく)文字列表現を得ることができて、eval が存在すればよいという条件だと JavaScript が特に珍しいということはなくて Tcl でもできる(info args コマンドと info body コマンド)し、たしか Lisp でも同様のことはできた気がします。動的言語なら特に出来ておかしいということはなさそう。どう書く?org のリフレクション系お題にできるかな?

[1] http://d.hatena.ne.jp/Gemma/20070818


textarea の内容を pre 要素の下に挿入するときの注意 [JavaScript]

CodeRedingWiki で久しぶりに Web っぽいというかブラウザが関与するプログラムをしたのだけどやっぱりブラウザの互換性問題でうんざりした。

CodeReadingWiki では、ソースの行をダブルクリック→textarea表示→もう1回ダブルクリック→textareaの入力内容を該当行の下に DOM で挿入、ということをやっている。
GLOBAL の HTML ではソースは pre タグで囲まれていて、ここで嵌った。何か IE と FirexFox では改行の扱いが違うようで、一方で改行されたものが一方では空白1文字扱いになったりして上手く行かない。

検索してみたら [1] のようなことだった(リンク先のまとめに感謝)のだが、なんだかなあという感じ。これで OS やロケールでまた動作が違うとかだったらもう投げ出したい。ブラウザ間の非互換性の問題って Web プログラミングの世界ではいつまでも引きずって歩かなければいけないのかな。

[1] http://d.hatena.ne.jp/brazil/20060917/1158465641


global object と call object [JavaScript]

JavaScript のグローバル変数はすべて global object と呼ばれるオブジェクトのプロパティである。global object への参照は this を使って得られる。これは Lua のグローバル変数が _G というテーブルの要素であるというのに似ている。ただし Lua では _G 自体がグローバル変数であり、従って _G 自身の要素であるのに対して JavaScript では this は this のプロパティではない。

> -- Lua
> i = "global i"
> print(i)
global i
> print(_G.i)
global i
> print(_G._G.i)
global i
> print(_G._G._G.i)
global i
js> // JavaScript
js> i = "global i"
global i
js> print(i)
global i
js> print(this.i)
global i
js> print(this.this.i)
4: SyntaxError: missing name after . operator:
4: print(this.this.i)
4: ...........^
js>

JavaScript 本ではグローバル変数が global object のプロパティであるのと同様にローカル変数も call object と呼ばれるオブジェクトのプロパティなのですよと説明している。Lua には同様の概念はない。この説明には特にコード例のようなものがなかったのだが、疑問に思ったのはその call object への参照はどのようにして得られるのかということだ。global object とのアナロジーで考えれば関数の中での this が call object を指していると期待できるのだが、実際試してみるとそうではない。(以下のコードはさっきの続きで打ち込む)

js> function f() {
        var i = "local i";
        print(i);
        print(this.i);
}
js> f()
local i
global i

この例から分かることは関数の中であっても this は global object を指し示すということだ。しかし call object への参照を得る方法がないとしたら、そもそも「ローカル変数は call object のプロパティである」という言明はどういう意味をもつのだろうか。

(1) 実装上ローカル変数を格納するオブジェクトを作っている場合が殆どですよという意味
(2) call object というものがあると考えると学習上分かりやすいですよという意味
(3) call object というものがあると考えると global object とパラレルになって概念的に美しいですよという意味

勿論まだ JavaScript は始めたばかりなので、ひょっとしたら call object の実体を通常のプログラミングレベルで観察できる方法があるのかもしれない。

ちなみに Lua では debug.getlocal という関数でローカル変数の情報を得ることができる。

> function f(x, y)
>>   local z
>>   local i = 1
>>   while true do
>>     local n, v = debug.getlocal(1, i)
>>     if not n then break end
>>     print(n, v)
>>     i = i + 1
>>   end
>> end
> f(777, 999)
x       777
y       999
z       nil
i       4

こちらではテーブル(オブジェクト)との類似性はまったくない。


SpiderMonkey をコンパイルする [JavaScript]

O'Reilly の JavaScript 本をぼちぼち読み始めている(同時期に注文して同時期に来るはずだった Practical OCaml はまだこない)のだけど、変数の値の表示にブラウザで(ブラウザで!) document.write() とかやるのはきついので OCaml や Tcl や Lua みたいなインタラクティブシェルが欲しいと思っていたところ、 Mozilla プロジェクトの SpiderMonkey という実装にまさにそれがあることが分かったので早速導入。

最初 MinGW でコンパイルしようと思って [1] を見て DLL を作るところまで行ったのだが目当てのシェルが出来上がっていないのでそこで挫折し、実は MSVC で簡単にできるということが [2] を見て分かったので素直にそうした。

1. 適宜環境変数を設定
2. js.mak中の"/MD"をすべて"/MT"に置換する
3. nmake -f js.mak CFG="jsshell - Win32 Release"

使ったのは MSVC 2005 Express だが「js.mak中の"/MD"をすべて"/MT"に置換する」を実行しないと新しいほうの MSVC ランタイム (MSVCR80.DLL) に依存してしまうので注意。

あと最初 odbc.lib がリンクできないといってリンカに怒られた。探してみたら私の環境では MASM のライブラリフォルダにあったので環境変数 LIB に追加した。これはよくわからない。

メイクすると使っている関数が古いとか知らないオプションを使っているとか警告が出るが最後まで通る。出来上がった jsshell.exe と js32.dll を適当なフォルダに移すと(移さなくてもいいが)ダブルクリックで起動できる。

[1] http://sourceforge.net/docman/display_doc.php?docid=13826&group_id=50913
[2] http://d.hatena.ne.jp/bellbind/20051101/1130871157


JavaScript: The Definitive Guide, Fifth Edition [JavaScript]

JavaScript の本で「実用サンプル集」の類じゃないものといったらオライリーの "JavaScript" [1] しかない――と Amazon のレビューに書いてあります。
で、ちょっと言語としての JavaScript を詳しく知ってみたい欲が沸いていたのだけど、しかしこれは2000年に出版されたもので内容が古いようだから購入を躊躇っていた。現在の日本語訳は第3版をもとにしているのだが英語版は2001年の第4版が最新らしい。
じゃあ英語でもいいから第4版を手に入れちゃおうか、と思って検索しているとサイトによっては "Fifth Edition" なんて表示をしているのがある。誤記?と思ってたらそうではなく、今度出るのだ。2006年版が。店頭で衝動買いしなくてよかった!

第3版がJavaScript1.2を対象としていたのに対して第5版はJavaScript 1.5を対象にするらしい。でも調べてみると2006年時点での最新はJavaScript1.7らしい([3]参照)。詳しく知らないけど実装が追いついてるのは1.5ってことなのだろうか。とりあえず予約。

[1] http://www.oreilly.co.jp/books/4873110270/
[2] http://www.oreilly.com/catalog/jscript5/
[3] http://en.wikipedia.org/wiki/JavaScript


JavaScript ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。