ほんとのこと知りたいだけなのに。

夏休みはもうおわり。

D3.js の基本がどうも理解できていないので整理してみる。

これまで D3.js を何度が利用することはあったがほとんどコピペだった。

それでも十分動くんだけど、個々の命令やその動作について理解できていない。

使いこなす必要が出てきそうなので整理してみる。

やること

まずやること。 内容はシンプル。 rect を追加するだけ。

下図の左の状態を右の状態にする。

実行前
<svg id="d3">
    // ここに
    // rect要素を三つ
    // 追加します。
</svg>
実行後
<svg id="d3">
    <rect></rect>  // __data__ = 1
    <rect></rect>  // __data__ = 2
    <rect></rect>  // __data__ = 3
</svg>

コード と説明

次はコード。こんだけ。

d3.select("div#d3")
  .selectAll('rect') // 追加対象の要素を指定する。
  .data([1, 2, 3])   // 追加対象のデータを指定する。
  .enter()           // データの個数分以下の処理をする。
  .append("rect")    // rect要素(<rect></rect>)をdiv#d3に追加する。

(1) select

要素を追加する先の要素を指定する。

See Also

(2) selectAll

追加対象の要素を選択する。 これを実行した段階ではまだ rect 要素は追加されていない。

この命令が一番わかりにくい。 どうやら 引数のselector で指定した要素を取得してどこかに保持するみたい。

(恐らく)ここで選択した要素と、次で指定するデータを突き合わせて追加/変更削除するんじゃなかろうか。

See Also

(3) data

追加する rect 要素のデータを指定する。

イメージとしてはここで指定された個数の rect 要素が追加される。

まだここでも rect 要素は追加されていない。

(恐らく)ここでデータと要素がバインドされるんかな。

See Also

(4) enter

data メソッドで指定されたデータの個数分これ以降のメソッドチェーンの処理を繰替えす。

まだここでも rect 要素は追加されていない。

Common Lisp で言うところの dolist みたいなものだろう。

Value

Returns the enter selection

See Also

(5) append

select メソツドで指定した要素(svg#g3)に rect 要素を追加する。

ここで初めて rect 要素が作成され追加される。

See Also

おわり

ざっと眺めてみたんだけど、やはりしっくりこない。

以下の二種類についての構成/仕組みが理解できていないからかな。というように感じた。

  • データをバインドする。
  • 各命令の戻り値。

次回はそのあたりを整理したいな。

SBCL のマニュアル 14 Networking を俯瞰してみる。

upanishad の master - slave の部分のテストが透らず困っている。

仕方なく socket を勉強することに。

とりあえず SBCLのマニュアルを眺めて見ることにした。
英語は Google先生を元に文章が短かくなるように適当に編集した。

それでは開始。

14 Networking

sb-bsd-sockets モジュールは、SBCLのためのBSDソケットAPIを提供します。

CのBSDソケットAPIとPerlのGraham BarrのIO::Socketクラスを参考にしています。

ソケットはCLOSEオブジェクトとして表現されています。

APIの命名規則はBSD名とLispスタイルのバランスを取っています。

14.1 Sockets Overview

ほとんどの関数はBSDソケットAPIでモデル化されています。

BSDソケットは、さまざまなシステムで移植可能(少なくともUNIX標準では "移植可能")で広くサポートされており、文書化されています。

Common Lispのより有用な機能のいくつかを簡単に利用したアプローチにはいくつかの違いがあります:

  • 通常、C APIが-1を返してerrnoを設定する場合、sb-bsd-socketsはエラーを通知します。 すべてのエラーはsb-bsd-sockets:socket-conditionのサブクラスであり、一般的にはerrno値の可能性のあるエラーに対応します。
  • C APIが参照渡しの値を使用する多くの場所で、複数の戻り値を使用します。
  • 引数の長さをすでに知っているので、関数に明示的な長さ引数を渡すことをしばしば避けることができます。
  • IPアドレスとポートは、「network-endian integers」よりも少し優しい方法で表現されます。

14.2 General Sockets

type symbol args
Class socket [sb-bsd-sockets]
Generic Function socket-bind [sb-bsd-sockets] socket &rest address
Generic Function socket-accept [sb-bsd-sockets] socket
Generic Function socket-connect [sb-bsd-sockets] socket &rest address
Generic Function socket-peername [sb-bsd-sockets] socket
Generic Function socket-name [sb-bsd-sockets] socket
Generic Function socket-receive [sb-bsd-sockets] socket buffer length &key oob peek waitall dontwait element-type
Generic Function socket-send [sb-bsd-sockets] socket buffer length &key address external-format oob eor dontroute dontwait nosignal confirm more
Generic Function socket-listen [sb-bsd-sockets] socket backlog
Generic Function socket-open-p [sb-bsd-sockets] socket
Generic Function socket-close [sb-bsd-sockets] socket &key abort
Generic Function socket-shutdown [sb-bsd-sockets] socket &key direction
Generic Function socket-make-stream [sb-bsd-sockets] socket &key input output element-type external-format buffering timeout auto-close serve-events
Method socket-make-stream [sb-bsd-sockets] (socket socket) &key input output (element-type (quote character)) (buffering full) (external-format default) timeout auto-close serve-events
Function socket-error [sb-bsd-sockets] where &optional errno
Generic Function non-blocking-mode [sb-bsd-sockets] socket

14.3 Socket Options

ソケットオプションのサブセットは、一般的なフレームワークを使用してサポートされています。
これにより、必要に応じて簡単に追加することができます。
詳細については、SYS:CONTRIB;SB-BSD-SOCKETS:SOCKOPT.LISPを参照してください。

Cからの名前マッピングはかなり簡単です。
SO_RCVLOWATsockopt-receive-low-water(setf sockopt-receive-low-water) になります。

type symbol args
Function sockopt-reuse-address [sb-bsd-sockets] socket
Function sockopt-keep-alive [sb-bsd-sockets] socket
Function sockopt-oob-inline [sb-bsd-sockets] socket
Function sockopt-bsd-compatible [sb-bsd-sockets] socket
Function sockopt-pass-credentials [sb-bsd-sockets] socket
Function sockopt-debug [sb-bsd-sockets] socket
Function sockopt-dont-route [sb-bsd-sockets] socket
Function sockopt-broadcast [sb-bsd-sockets] socket
Function sockopt-tcp-nodelay [sb-bsd-sockets] socket

14.4 INET Domain Sockets

あなたが知っている、愛しているTCPソケットとUDPソケット。 いくつかの表現の問題:

  • IPv4インターネットアドレスは(符号なしバイト8)のベクトルで表されます。 #(127 0 0 1)
    ポートは6010(整数)だけです。
    このパッケージのユーザーからは、ネットワーク注文データとホスト注文データの間の変換は必要ありません。
  • IPv6インターネットアドレスは、16(符号なしバイト8)のベクトルで表されます。 #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)
    ポートは単なる整数です。
    IPv4アドレスに関しては、このパッケージのユーザからネットワーク注文データとホスト注文データの間の変換は必要ありません。
  • ソケットアドレスはaddressとportの2つの値で表されます。
    例えば、(socket-connect socket#(192 168 1 1)80)for IPv4と (socket-connect socket#(0 0 0 0 0 0 0 0) 0 0 0 0 0 0 0 1)80)IPv6のために。
type symbol args
Class inet-socket [sb-bsd-sockets]
Class inet6-socket [sb-bsd-sockets]
Function make-inet-address [sb-bsd-sockets] dotted-quads
Function make-inet6-address [sb-bsd-sockets] colon-separated-integers
Function get-protocol-by-name [sb-bsd-sockets] name

14.5 Local (Unix) Domain Sockets

ローカルドメイン(AF_LOCAL)ソケットはUnixドメインソケットとも呼ばれますが、おそらく他のシステムでも利用可能であるという基準でPOSIXによって名前が変更されました。

ローカルソケットアドレスは文字列であり、ローカルファイルシステムにノードを作成するために使用されます。
これはもちろん、ネットワーク上で使用することはできません。

type symbol args
Class local-socket [sb-bsd-sockets]

14.6 Name Service

現在、ネームサービスは getaddrinfo(3)gethostinfo(3)、またはgethostbyname(3)gethostbyaddr(3)を呼び出すことで実装されています。
名前解決プロセス(DNSやhostsファイルが参照に使用されているかどうかなど)の正確な詳細は、プラットフォームによって異なります。

type symbol args
Class host-ent [sb-bsd-sockets]
Function get-host-by-name [sb-bsd-sockets] node
Function get-host-by-address [sb-bsd-sockets] address
Generic Function host-ent-address [sb-bsd-sockets] host-ent

おわり

なんかなんとなく全体は見えたような気がする。

C のソケットの使い方を理解すれば良さそう.

パッケージは sb-bsd-sockets みたいなので次回はそれを俯瞰してみるか。

babel2 の コンディション

babel2(babel) の condition を眺めてみます。

GitHub - yanqirenshi/babel2: babel をイジって遊ぶためのプロジェクトです。

github.com

コンディションの構成

コンディションの構成(階層)はこんな感じ。

大きくわけて encoding と decoding の二種類あるみたいですね。

                                             +-------+
                                             | error |
                                             +-------+
                                                 |
                                      +------------------------+
                                      | character-coding-error |
                                      +------------------------+
                                                 |
                               +-----------------o------------+
                               |                              |
                    +--------------------------+   +--------------------------+
                    | character-decoding-error |   | character-encoding-error |
                    +--------------------------+   +--------------------------+
                               |
               +---------------o-------------+
               |               |             |
 +---------------------------+ | +------------------------+
 | end-of-input-in-character | | | character-out-of-range |
 +---------------------------+ | +------------------------+
                               |
           +-------------------o----------------------+
           |                                          |             encodings.lisp
 - - - - - | - - - - - - - - - - - - - - - - - - --:--|- - - - - - - - - - - - - - -
           |                  enc-unicode.lisp     :  |               enc-gbk.lisp
           |   +---------------------------+       :  |   +------------------+
           +---| invalid-utf8-starter-byte |       :  +---| invalid-gbk-byte |
           |   +---------------------------+       :  |   +------------------+
           |   +--------------------------------+  :  |   +-----------------------+
           +---| invalid-utf8-continuation-byte |  :  `---| invalid-gbk-character |
           |   +--------------------------------+  :      +-----------------------+
           |   +------------------------+          :
           `---| overlong-utf8-sequence |          :
               +------------------------+          :
symbol parent file
invalid-gbk-byte character-decoding-error enc-gbk.lisp
invalid-gbk-character character-encoding-error enc-gbk.lisp
invalid-utf8-starter-byte character-decoding-error enc-unicode.lisp
invalid-utf8-continuation-byte character-decoding-error enc-unicode.lisp
overlong-utf8-sequence character-decoding-error enc-unicode.lisp
character-coding-error error encodings.lisp
character-encoding-error character-coding-error encodings.lisp
character-decoding-error character-coding-error encodings.lisp
end-of-input-in-character character-decoding-error encodings.lisp
character-out-of-range character-decoding-error encodings.lisp

上の構成図には含めていませんが streams.lisp にもコンディションがあります。
ただ、このコンディションは streams.lisp で閉じられているので上の構成図には入れていません。
(export もされていません)

symbol parent file
in-memory-stream-error stream-error streams.lisp
in-memory-stream-closed-error in-memory-stream-error streams.lisp
wrong-element-type-stream-error stream-error streams.lisp

コンディションを発火させるオペレータ

コンディションを発火させるオペレータハ以下の二つです。

  • encoding-error
  • decoding-error

おわり

朧げですが全体像が掴めました。

これの結果で babel2.conditions を新設してそこにコンディションを分離しました。

また少しコードの見通しが良くなりました。