仮引数とクロージャ2007年05月04日 02時58分41秒

(元記事:あるSEのつぶやき: prototype.jsでプライベートメソッドを持つクラスを作る方法

ローカル変数の代わりに

個人的には最近まったく使わなくなっていた「JavaScriptによるプライベートフィールドの隠蔽」だが、あるSEのつぶやきさんが取り上げていたので一言(でもないか)。

リンク先記事で、Animal#defineメソッド内の実装で、プライベートフィールドをわざわざ定義しているが、これって、defineメソッドの仮引数「_sex」を_getSexで囲っちゃっても同じなんだよね。

15:	define : function(_sex) {
16:		//プライベートフィールド
17://		var sex = _sex; // ←コメントアウト
18:
19:		//プライベートメソッド
20:		var _getSex = function() {
21:			return _sex;// ←変更。仮引数にアクセスできるし。
22:		}
23:
24:		//Privileged(特権)メソッド
25:		this.getSex = function (){
26:			return Animal.SEXTYPE[_getSex()];
27:		}
28:	}
仮引数も、関数内でvar宣言されたローカル変数も、このメソッド内の実行コンテキストにバインドされた変数オブジェクトのプロパティであることには変わりがないので、宣言するだけ冗長かと。

同じIdentifierの仮引数とローカル変数の関係を見るために以下のコードを検証してみた。

function test1() {
	var a;
	return "test1: " + a;
}

function test2(a) {
	return "test2: " + a;
}

function test3(a) {
	var a;
	return "test3: " + a;
}

alert( test1("hoge") ); // 'test1: undefined'
alert( test2("hoge") ); // 'test2: hoge'
alert( test3("hoge") ); // 'test3: hoge'
Firefox1.5でしか試していないが、たぶんどの処理系でも同じだと思う。ポイントはtest2とtest3の結果が同じになること。 ついでだが、test3内でローカル変数宣言に代入式を与えると、当然仮引数「a」はオーバーライドされるので、違う結果になる。

おまけ

この手の解説で、以前は「Effective JavaScript」というよいコンテンツがあったのだが、現在は公開されていない。非常に残念だ。

現在はアクセスしても404になるのでリンクはせず、当時のURLを掲載しておく。www.archive.orgなんかを利用するとまだ確認できるかも。

http://www.interq.or.jp/student/exeal/dss/ejs/index.html

EXEを作ってみた2007年05月04日 03時11分17秒

これはちょっと便利かも

ゆるゆるとJSDBを試しているが、本家のチュートリアル眺めてたら、「Standalone JSDB programs」という項があって、

c:\temp>pkzip program.zip main.js

c:\temp>copy /b jsdb.exe+file.zip program.exe
c:\temp>program.exe
とか書いてあるじゃないですか。

さらに-helpオプションつけて起動してみたら、.zipのアーカイブをパラメータに渡せるとあった。

D:\jsdb>jsdb -help
JSDB 1.52Compiled Apr 27 2007.  http://www.jsdb.org/
Copyright 2003-2006 by Shanti Rao and others.

JSDB [-strict] [-werror] [-load file.js] [-debug server] [lib.zip] [program.js]

  -strict             Strict syntax mode
  -werror             Treat warnings as errors
  -load file.js       Load and run file.js before program.js
  -debug server:port  Connect to a debugger server
lib.zip Set lib.zip as the default location for library files Executes main.js if found in the zip file
program.js Runs a JavaScript program. If omitted, enter console mode D:\jsdb>
ということは、「main.js」にメインコードを記述し、それをzipで固めて、チュートリアルにあるように結合コピーするとオリジナルのコンソールアプリケーションが作れるってことじゃない!こいつぁ便利かも。

早速試してみた

まず、以下のコードを「main.js」で保存。コードの中身はかなり適当。

write("what your name ? > ");
writeln( "hello, ", readln()," !!" );
sleep( 1000 );

そんで、main.jsをmain.zipとして固める。

そしてチュートリアルにある要領で、コピー。hello.exeとした。

D:\jsdb>copy /b jsdb.exe+main.zip hello.exe
jsdb.exe
main.zip
        1 個のファイルをコピーしました。

D:\jsdb>
さて、hello.exeを実行。
D:\jsdb>hello
what your name ? > hoge
hello, hoge !!

D:\jsdb>
おお、ちゃんとできてるよ。

使い道

とりあえず思いつくのは、ライブラリ読み込み処理をmain.jsに記述してカスタマイズした実行環境にするってとこかな。

と思ったが、アーカイブ内のmain.jsを実行するとそのまま終了しちゃうので、この方法だとドラッグドロップ専用になっちゃうな(たぶんコマンドライン引数は受け取れるだろうから)。 もっとも、ライブラリロードを起動時になんとかするんだったら、-loadをくっつけたバッチファイルにしちゃえばよいんだし。ちぇ。

ピアノ猫2007年05月05日 11時30分49秒

すこし前から結構話題になってるみたいだが、夢中でピアノを弾く猫が人気の模様。ものすごく夢中で弾いている様子が愛らしい。

YouTubeにいくつもUPされているのでごらんになってみては。

成分分析してみる2007年05月05日 12時10分22秒

dara-jは猫としてどうか。

しばらく前にPHPSPOTさんで見つけたにゃんにゃん分析を試してみた。

ふむ、なかなか可愛らしい猫になりました。

必殺技は、どうよ?

もはやカテゴリに適用している「猫」とは関係ない方向にゆくが、このブログの必殺技を判定してもらった

dara-jの必殺技

レベル:67
必殺技1:コフィンブレス - 攻撃力→232
必殺技2:葉大槌霊突き - 攻撃力→60
必殺技3:黄金断 - 攻撃力→47
...レベル67は高いレベルなのか?「葉大槌霊突き」ってどう読むの??

リンク

その他「わんわん分析」や「恋愛賞味期限」などの各種成分分析はこちらから。

JSDBのhttp取得の件2007年05月05日 22時36分14秒

Streamのhttp取得できます

以前のエントリで、JSDBのStreamを使用したhttp読み込みがハングするといったことを記述しましたが、これ間違いでした。もし信じてしまった方がいましたら、ごめんなさい。おわびします。

なぜ取得できなかった?

前のエントリでのテストはローカルホスト(Win2K Pro + IIS5.0)に対するリクエストだったが、どうもこれがハングの原因だった模様。ローカルに設置したコンテンツは末尾の改行の有無にかかわらず、read()した以降制御を戻してこない。

最初はローカルホストに対する制約かとも思ったが、考えてみたら

while( ! stream.eof ) writeln( readln() );
のコードは最終行前までは出力できていたので、多分、IISが原因。

(2007/05/06 00:30 追記)
いくつかIISなホストを探して試してみたところ、IIS6は問題ないが、IIS5.0はconnectionが切断されない。IIS5.1(XP)はどうだろうか。
(2007/05/07 13:40 追記)
さらに調査したところ、IISうんぬんでないと判明。詳しくはこちら

さらにちょっと恥ずかしいことに

malさんよりいただいたコメントに、「prototypeの本家サイトから1.5.1を読み込ませてもハング」と書いたのだが、これまた恥ずかしいことにしばらく待ってたら受信完了したよ。

これ、「多分ハングするよ」という思い込みと、dara-jの家庭のネットワーク環境が、いまどきなろーばんどなため、状態を確認せずにハングしたと思い込んでいたためのようだった。

というわけで

JSDBでStreamを使用したhttp接続は普通に使えます。エンコード変換はわからんけど。

もう少ししっかり検討して投稿しないとあかんなぁ。コメントくださったmalさんに感謝です。

おまけ

しかしコンソール出力に文字数制限があるみたい。prototype.1.5.1を読み込んでそのままwriteln()すると出力されない。

substr()するとどっかを境に出力される・されないが分かれるみたいだが、これも不定っぽい。

もすこし調査したら別に掲載する予定。