Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Kanasansoft/5264301 to your computer and use it in GitHub Desktop.
Save Kanasansoft/5264301 to your computer and use it in GitHub Desktop.
達人出版経由で購入したPDFのメタデータのタイトルが「Nodejs_カバー入稿2」
P89
図7-4内のイベントが「foo」になっているが、その直前のサンプルコードでは「bar」になっている。
P90
SyncDBの例では、node.jsの機能を一切使わなくてもエラーが発生するので例として不適切な気がする。
このサンプルコードでは、
1行目 var events = require('events');
2行目 var util = require('util');
6行目 util.inherits(SyncDB, events.EventEmitter);
がなくてもfoo.setbaz未定義でエラーとなる。
P132
『this.t_queue = {}; // 未実行のタイマーオブジェクトを格納する配列』
コードはオブジェクトだが、コメントは配列になっている。
P133
リスト9-4は動く?
t_queueの扱いが怪しい。
writeDataDelayed内、client.counterは、実行時に評価されるので、client.writeDataには最大値が渡される。
client.writeData内のidは同じ値になるので、whileで何回ループしても
delete t_queue[id];
は同じタイマーオブジェクトを削除しにいくだけに見える。
P143
本文では「tls.EncryptedtextStream」となっているが、図9-13内では「tls.EncryptedStream」となっている。
P177
「● リクエストイベントリスナ内で http.ServerRequest オブジェクトのデータイベントを受け取り、終了時
に標準出力する」とあるが、リスト10-1の出力先はresponseオブジェクト。
P192
「リスナでは、サーバからのレスポンスを受けるhttp.ClientResponse クラスのオブジェクトreqが引数として渡ります。」
「リスナでは、サーバからのレスポンスを受けるhttp.ClientResponse クラスのオブジェクトresが引数として渡ります。」
P210
---
URL エンコードされたクエリ文字列をパースする場合(自動的に URL デコードされます)
> querystring.parse(’key1=val%22’);
{ key1: [ ’val1’, ’val"’ ] }
---
とあるが、実際は
{ key1: 'val"' }
になる。
P253
---
ここでは b の変数定義の直後に挿入します。
---
とあるが、実際はcの変数定義直後を含めて3カ所に挿入している。
P269
ステップ実行の説明で、
スクリーンキャプチャでは6つのアイコンを囲っているが、
説明文では5つしか解説されていない。
P328
link_toメソッドにXSSあり。
直後にescapeを使用しているので同時に説明できるはず。
P352
動的ビューへルパに登録しているuser_or_loginにXSSあり。
P353
動的ビューへルパに登録しているmessageにXSSあり。
P366
ログフォーマットについての記述にtypoらしきもの。
https://github.com/nomiddlename/log4js-node/blob/master/lib/connect-logger.js
より引用された記述部分で
スペースと「`」が削除されてしまっている。
P375
package.jsを編集している箇所で、
削除行と追加行のインデントが一致していない。
P396
コード内
res.local('variables'
において
username,channel等に
「'」が入るとvariable.ejsがバグる。
P397
本文中に「$('#fileUploaderDropZone) 」とあるが、閉じる「'」が抜けている。
P415
$ ls uploads | ws -l
でファイル数を確認しているが、
ここの実行結果は「0」ではなく「1」のはず。
P420
P396と同じ問題。
P423
socket.json.emit()の説明をしているはずなのに、
socket.emit()の話に変わっている。
P483
図にはToがあるが本文中にはない。
Javaの世代別GCを知っていれば理解できるが、
初見ではほぼ不可能に近い。
P501
リスト20-7
(ちょっと自信がない...。)
ブロックされないことの例としてリスト20-7が挙げられているが、
第1引数の関数の配列でsetTimeoutを使っているため
ブロックされないことの例としては不適切ではないか。
setTimeoutを使用しないとブロックされる?されない?
前者であれば説明がおかしいし、後者であればsetTimeout内でcallbackしても正常に動作する例になる。
P518
ツリー表示のインデントがずれている。
P520
「この変更内容は npm install -g を実行するまで、利用側のディレクトリ(/path/to/somewher)には反映されません。」の
「somewhere」のtypo。
P530
リスト23-1内
「//0.5秒後ワーカにシグナルSIGKILLを送信」とあるが3秒後。
P531
リスト23-2内
「//5秒ごとにメッセージを標準出力に出力」とあるが0.5秒ごと。
P539
リスト23-13内
「process.send('worker %d to master');」とあるが「%d」は意図した出力になっていないはず。
P540
「マスタはワーカ fork() により起動しましたが、」
「マスタはワーカを fork() により起動しましたが、」?
or
「マスタはワーカを fork() により起動しますが、」?
or
other?
P541
リスト23-14内
「console.log('maste を %d で 起 動 し ま し た 。 ', process.pid);」
「console.log('master を %d で 起 動 し ま し た 。 ', process.pid);」
P543
「まず Node HTTP Proxy を npm でインストールします。」とあるが
「$ npm install http-proxy@0.8.0 express@2.5.4」となっており
本文にはないexpressもインストールされている。
P560
アクション一覧の表内
引数にscriptもしくはindexを指定できる各アクションで、
「<script|index>」のあるものとないものが混在している。
P568
「Pull Requestの送りましょう。」
「Pull Requestを送りましょう。」
読了。
@shigeki
Copy link

shigeki commented Apr 2, 2013

@Kanasansoft 非常に細かくチェックしていただき感謝いたします。ご指摘の点につきまして、私が執筆した部分について下記の通り訂正させていただきます。ありがとうございました。訂正ページの反映までもうしばらくお待ちください。

P89

図7-4内のイベントが「foo」になっているが、その直前のサンプルコードでは「bar」になっている。

申し訳ありません。ご指摘の通り記載するイベント名は bar が正しいです。訂正させていただきます。

P90

SyncDBの例では、node.jsの機能を一切使わなくてもエラーが発生するので例として不適切な気がする。
このサンプルコードでは、
1行目 var events = require('events');
2行目 var util = require('util');
6行目 util.inherits(SyncDB, events.EventEmitter);
がなくてもfoo.setbaz未定義でエラーとなる。

上記3行について SyncCB/AsyncCB の2つの例に限り本質的に不要なものであります。
通常これらの非同期コールバックを利用するオブジェクトは、EventEmitter を継承した使われる場合が多く、7.2の例とそろえた記載の方が読者が読みやすいのではないかと思い、本来不要な3行文を残しております。ご理解のほどお願いします。

P132

『this.t_queue = {}; // 未実行のタイマーオブジェクトを格納する配列』
コードはオブジェクトだが、コメントは配列になっている。

申し訳ありません。コメント記述の間違いです。 配列 ではなく オブジェクト が正しいです。訂正させていただきます。

P133

リスト9-4は動く?
t_queueの扱いが怪しい。
writeDataDelayed内、client.counterは、実行時に評価されるので、client.writeDataには最大値が渡される。
client.writeData内のidは同じ値になるので、whileで何回ループしても
delete t_queue[id];
は同じタイマーオブジェクトを削除しにいくだけに見える。

申し訳ありません、うっかりしておりました。ご指摘の通り Timer 実行時のスコープの client.counter を参照しているのでその値を参照して delete するのは不適切です。chunk データ毎に id を振って、socket.write 毎に別スコープにするように下記のように修正します。

diff --git a/dist/ch09/tcp_echo_server3.js b/dist/ch09/tcp_echo_server3.js
index 7c021fd..4fb34d5 100644
--- a/dist/ch09/tcp_echo_server3.js
+++ b/dist/ch09/tcp_echo_server3.js
@@ -6,36 +6,40 @@ var server = net.createServer();
 server.maxConnections = 3;

 // データコンストラクタ
-function Data(d) {
+function Data(d, id) {
   this.data = d;
   // タイムアウト済フラグ
   this.responded = false;
+  this.id = id; // 何番目に受け取ったデータなのか識別するID
 }

 // クライアントコンストラクタ
 function Client(socket) {
   this.counter = 0;
   this.socket = socket;
-  this.t_queue = {}; // 未実行のタイマーオブジェクトを格納する配列
+  this.t_queue = {}; // 未実行のタイマーオブジェクトを格納するオブジェクト
   this.w_queue = []; // 未送信データを格納する配列
 }

-Client.prototype.writeData = function(d, id) {
+
+Client.prototype.writeData = function(d) {
   var socket = this.socket;
   var w_queue = this.w_queue;
   var t_queue = this.t_queue;
+
+  function writeSocket(d_obj) {
+    var key = socket.remoteAddress + ':' + socket.remotePort;
+    process.stdout.write('[' + key + '] - ' + d_obj.data);
+    socket.write('[R] ' + d_obj.data, function() {
+      delete t_queue[d_obj.id];
+    });
+  }
+
   // 送信データが一番最初の未送信データである場合に継続する
   if (w_queue[0].data !== d) return;
   // 頭から順番にタイムアウトが過ぎているデータを送信する
   while (w_queue[0] && w_queue[0].responded) {
-    var w_data = w_queue.shift().data;
-    if (socket.writable) {
-      var key = socket.remoteAddress + ':' + socket.remotePort;
-      process.stdout.write('[' + key + '] - ' + w_data);
-      socket.write('[R] ' + w_data, function() {
-        delete t_queue[id];
-      });
-    }
+    if (socket.writable) writeSocket(w_queue.shift());
   }
 };

@@ -58,14 +62,14 @@ server.on('connection', function(socket) {
   socket.on('data', function(chunk) {
     function writeDataDelayed(key, d) {
       var client = clients[key];
-      var d_obj = new Data(d);
+      var d_obj = new Data(d, clients[key].counter++);
       client.w_queue.push(d_obj);
       var tmout = setTimeout(function() {
         // タイムアウト済フラグを変更する
         d_obj.responded = true;
-        client.writeData(d_obj.data, client.counter);
+        client.writeData(d_obj.data);
       }, Math.random() * 10 * 1000);
-      client.t_queue[client.counter++] = tmout;
+      client.t_queue[d_obj.id] = tmout;
     }
     // 改行コードが送られて来るまで溜めておく (Windowsのtelnetクライアント対応)
     data += chunk.toString();

尚 node-v0.10.x では、このように終了時に残ったタイマーをわざわざ管理して clear せず、 tmout.unref() を使うことでタイマ参照が有効にならないようにできますので、この辺の処理が非常にすっきりさせることができます

P143

本文では「tls.EncryptedtextStream」となっているが、図9-13内では「tls.EncryptedStream」となっている。

申し訳ありません。本文の tls.EncryptedtextStream が間違いです。 tls.EncryptedStream が正しいです。訂正させていただきます。

P177

「● リクエストイベントリスナ内で http.ServerRequest オブジェクトのデータイベントを受け取り、終了時
に標準出力する」とあるが、リスト10-1の出力先はresponseオブジェクト。

申し訳ありません。標準出力する が間違いです。 responseオブジェクトに書き込む が正しいです。訂正させていただきます。

P192

「リスナでは、サーバからのレスポンスを受けるhttp.ClientResponse クラスのオブジェクトreqが引数として渡ります。」

「リスナでは、サーバからのレスポンスを受けるhttp.ClientResponse クラスのオブジェクトresが引数として渡ります。」

申し訳ありません。ご指摘の通りです。訂正させていただきます。

P210


URL エンコードされたクエリ文字列をパースする場合(自動的に URL デコードされます)

querystring.parse(’key1=val%22’);
{ key1: [ ’val1’, ’val"’ ] }

とあるが、実際は
{ key1: 'val"' }
になる。

申し訳ありません。ご指摘の通りです。訂正させていただきます。

@Kanasansoft
Copy link
Author

@shigeki

たった今コメントに気付きました。
反映内容まで含めて教えて頂いたのは初めてです。

先程追記しましたのでご参照ください。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment