目次
- 本書に寄せて
- 本書について
- 本書の構成
- 目次
第1章 I/O
1.01 RubyのIOクラスとC言語のstdioライブラリ ——プログラマが知っている名前を利用する
- FILE構造体とIOクラスの対応
- IOクラス以外のC言語とRubyの対応
- まとめ
1.02 feof関数とIO#eof?メソッド ——過去にEOFに出会ったのか,それとも今現在EOFなのか
- C言語とPascalにおけるファイルの終端
- ユーザにとってわかりやすいファイルの終端
- まとめ
1.03 IOバッファが空でなければsysreadは例外 ——明らかに危険で役に立たない動作は禁止する
- sysreadメソッドの由来
- sysreadメソッドの危険性
- Rubyでは混用禁止
- まとめ
1.04 EOFフラグの除去 ——モードで挙動が変化するのは良くない
- stdioのEOFフラグ
- RubyにおけるEOFフラグ
- EOFフラグの再実装の試み
- まとめ
1.05 0バイト読んだときに何を返す? ——用例を探して良い挙動を判断する
- readメソッド
- read(0)の挙動
- CGIでPOSTされたデータを読み込む
- CGI以外の用法
- 固定長レコード
- 可変長レコード
- 用法を探す
- Rubyの実際の挙動
- まとめ
1.06 selectとstdioのバッファ ——無理をしても使いやすくする
- I/Oの多重化
- selectとstdioのバッファリング
- RubyのIO.select
- まとめ
1.07 readpartial ——I/Oを多重化したときに適切なメソッド
- I/Oの多重化と読み込み/書き込み
- 適切な読み込み/書き込みサイズはわからない
- バッファを考慮したreadシステムコールが欲しい
- readpartialの動作
- まとめ
1.08 ノンブロッキングI/O ——モードで挙動が変化するのは良くない
- ノンブロッキングI/Oはfdのフラグ
- ノンブロッキングI/Oと1行入力
- ノンブロッキングモードと競合状態
- まとめ
1.09 ノンブロッキングI/Oメソッドの導入 ——read_nonblockやwrite_nonblock
- ノンブロッキングI/Oの用途
- 書き込みの多重化
- 読み込みの多重化
- 1. ノンブロッキングI/Oの設定
- 2. 複数スレッドからの読み込み
- 3. 圧縮されたストリームや,SSLなストリームからの読み込み
- ノンブロッキングI/Oメソッドを用いたI/Oの多重化
- 読み込むために書き込み可能になるのを待つこともある
- 4. Linux固有の問題
- ノンブロッキングI/Oの他プロセスへの影響
- まとめ
Column ノンブロッキングI/OとRubyの歴史
- UnixにおけるノンブロッキングI/Oの歴史
- RubyにおけるノンブロッキングI/Oの歴史
1.10 PTY.open ——ptyを利用するためのプリミティブ
- 擬似でない端末
- tty
- 制御端末
- 擬似端末
- PTY.spawnメソッド
- 擬似端末が必要になる状況
- 擬似端末の利用の仕方
- PTY.openメソッド
- まとめ
1.11 IOによるエンコーディング変換 ——正しく処理すべきだが,速度も重要
- IOクラスによるエンコーディング変換
- 改行の変換
- IOでの変換と文字列の変換の違い
- ファイルの現在位置の扱い
- 現在位置を扱える変換手法
- まとめ
第2章 ソケット
2.01 Addrinfoクラスの導入 ——関連して扱う情報をまとめてオブジェクトにする
- Addrinfo.getaddrinfoメソッドとSocket.getaddrinfoメソッド
- Addrinfoクラス
- 逆引きの有無
- プロトコル非依存
- アドレスの種類を判定するプレディケートメソッド
- ソケットアドレス構造体を返すメソッドと互換性
- まとめ
2.02 Socketクラスの勧め ——使いやすく,かつ,低レベルな操作も可能
- ソケットのクラス階層
- 細分化されたクラスの問題
- Socketクラスの強化
- クラスメソッド
- インスタンスメソッド
- initialize
- 特定の種類のソケットのためのメソッド
- ソケットアドレスを返すメソッド
- まとめ
2.03 Socket.ip_address_list ——自ホストのIPアドレスを正しく簡単に得る
- 自ホストのIPアドレスの必要性
- 自ホストのIPアドレスを得る方法
- Socket.ip_address_listメソッド
- Socket.ip_address_listの実装
- まとめ
2.04 ソケットオプション ——関連して扱う情報をまとめてオブジェクトにする
- ソケットオプションの使い方の例
- ソケットオプションの内容の表示
- ソケットオプションの型の詳細を隠蔽
- Socket::Optionの内容
- Socket::Option導入に伴う非互換性
- クラスを細分化しない
- まとめ
2.05 send_ioとrecv_ioによるfd passing ——ポータブルで引数の少ないAPI
- fd passing
- recvmsgとsendmsgシステムコール
- recv_ioとsend_ioメソッド
- まとめ
2.06 recvmsgとsendmsg ——多機能なシステムコールを工夫して提供
- recvmsgとsendmsgシステムコール
- recvmsgとsendmsgメソッド
- 「不連続なバッファを扱える」機能は提供しない
- 「MSG_OOBなどのフラグを指定できる」機能
- 「recvmsgではMSG_TRUNCなどのフラグが返ってくる」機能
- 「recvmsgで送信元を得られ,sendmsgで送信先を指定できる」機能
- 「バイト列を読み書きできる」機能
- 「補助データを扱える」機能
- まとめ
2.07 getpeereid ——簡単確実なユーザ認証
- ユーザ認証
- マシン内のユーザ認証システムコール
- getpeereidメソッド
- まとめ
第3章 プロセス
3.01 プロセス起動プリミティブspawnメソッド ——ポータブルで高機能で簡単なプロセス起動
- forkとexecはポータブルでない
- プロセス起動の悩ましい選択
- spawnメソッド
- まとめ
Column async-signal-safe関数
- async-signal-safeでない関数
- forkで生成された子プロセス
- 経緯と現状
3.02 close-on-execフラグ ——意図しないfdの継承を防止する
- 子プロセスへのさまざまな継承
- fdを継承する用途
- 意図せざるfdの継承
- デフォルトでclose-on-execにする
- Rubyにおけるclose-on-exec
- POSIXとRubyのデザインの違い
- すべてのfdをcloseする実装
- まとめ
3.03 Open3.popen3の修正 ——互換性を保って問題を解決する
- Ruby 1.8のopen3ライブラリ
- open3ライブラリの改善
- double forkの除去
- まとめ
3.04 open3における標準エラー出力の扱いと
- デッドロック ——用途に応じたメソッドの追加
- メソッドの追加
- popen3,popen2,popen2eメソッド
- デッドロック
- capture3,capture2,capture2e
- まとめ
3.05 open3のパイプラインサポート ——パイプで接続したプロセス起動
- パイプで接続されたプロセスの起動
- パイプの使われ方
- まとめ
Column PerlとPythonでパイプラインを作る
- 使う例について
- Rubyのopen3
- PerlのIPC::Open2
- Pythonのsubprocess
- fdがオープンされたまま残る
- クローズして問題を解決する
3.06 双方向popenのソケットによる実現 ——ソケットペアによる実装の失敗
- コマンドとの単方向通信
- コマンドとの双方向通信
- 1つのIOオブジェクトで2つのfdを扱う問題
- ソケットペアによる双方向popenの実現
- 2つのfdの問題への対応
- まとめ
3.07 forkは他のスレッドを子プロセスに残さない ——用途に適した挙動が重要
- マルチスレッドとfork
- 子プロセスですべてのスレッドが実行されることの問題
- まとめ
第4章 時刻
4.01 POSIXの時刻機能とRubyのTimeクラス ——プログラマが知っているPOSIXの機能を提供する
- POSIXの時刻機能で用いる型
- POSIXの時刻機能とRubyの対応
- まとめ
4.02 Time.utcと閏秒 ——POSIXが提供していなくても必要なら提供する
- Time.utcメソッド
- timegm関数と閏秒
- Rubyによるtimegm関数のエミュレーション
- まとめ
4.03 Time#monとTime#ydayの範囲 ——実際の用法を検討してAPIをデザインする
- 「月」を整数でどう表すか
- 「年初からの日数」を整数でどう表すか
- まとめ
4.04 時刻に関するOSの制限 ——本質的でない制限を取り除く
- C言語における時刻表現の制限
- time_tの制限
- struct tmの制限
- 関数の制限
- RubyのTimeクラス
- まとめ
4.05 localtimeの逆関数 ——mktimeに依存しない
- 地方時とタイムゾーンデータベース
- mktimeの不安定性
- mktimeをlocaltimeと2分探索で実現する
- まとめ
4.06 localtimeの外挿 ——2038年問題への対応
- 2038年問題への対応
- 未来の地方時の推定
- いくつかの地方時の規則
- localtime関数の外挿
- 過去の地方時の推定
- その他の制約の除去
- まとめ
Column さまざまなタイムゾーン
- キューバと夏時間
- ブラジルと夏時間
- イスラエルと夏時間
- モロッコと夏時間
- イランと夏時間
- イギリスと夏時間
- 夏時間の時差の例外
- 夏時間と歴史的観点
- 日付変更線付近の夏時間
- 夏時間と極地
- 日付をまたぐ例
- 時刻を取り巻くさまざまな理由
4.07 UTCからの時差と夏時間 ——対象を確実に表現するデータ構造
- C言語とRubyにおける時刻表現の違い
- C言語における時刻の扱いの問題
- Rubyにおける時刻の扱いの問題
- Time#utc_offsetメソッドの追加
- Time#strftimeメソッドの強化
- まとめ
4.08 UTCからの時差を指定 ——メンテナンスを増やさない範囲で表現を広げる
- UTCと地方時の扱い
- さまざまな地方時とタイムゾーンデータベース
- 時差が一定のタイムゾーン
- まとめ
4.09 秒未満の表現 ——有理数による表現
- 外部から時刻が伝達される状況
- Timeオブジェクトの内部表現
- Marshalフォーマットの問題
- まとめ
4.10 タイムゾーンの略称 ——問題が多過ぎるので避ける
- 略称はタイムゾーンに1つでない
- タイムゾーンの略称は複数のタイムゾーンで共有される
- タイムゾーンの略称の生成はOSによっては期待されない結果になる
- UTCからの時差を直接使う
- まとめ
Column 一方,PHPはタイムゾーンデータベースを同梱した
- PHPのタイムゾーンデータベースの同梱
- タイムゾーンデータベースの更新
- OSのタイムゾーンの検出
- まとめ
Column Pythonの時刻 ——naiveとaware
- datetimeの2種類の時刻
- naiveなdatetimeとawareなdatetime
- PythonとRuby
4.11 time.rbが提供するメソッドの意図 ——正しい方が簡単になるようにしておく
- time.rbが追加するメソッド
- 特定用途のためのメソッド
- Time#strftimeメソッド
- strftimeのlocale依存性の問題
- strftimeの%zの問題
- RFC 2822の時刻を生成する正しい方法
- プログラマを正しい方法に誘導する
- まとめ
4.12 Time.localとTime.utcの引数順 ——あからさまに奇妙だが互換性のために残っている
- Time.localとTime.utcの奇妙な引数順
- 引数順の理由と歴史
- 問題を修正するかどうか
- まとめ
第5章 数,文字列
5.01 Math.gammaのメソッド名 ——慣習は無視することもある
- ガンマ関数と対数ガンマ関数
- Rubyのメソッド名とC言語の関数名
- まとめ
5.02 Integer#nonzero?の返り値 ——意外な動作だけど役に立つ
- Integer#nonzero?の返り値
- Enumerable#sort
- Enumerable#sortでInteger#nonzero?を使う
- まとめ
5.03 有理数のビット演算 ——一貫性を拡張するのは無理かもしれない
- Rubyにおける数の演算
- 有理数のビット演算は交換法則が成り立たない
- 有理数のビット演算で交換法則を実現できるか
- まとめ
5.04 Integer#bit_lengthメソッド ——用途と前例を調べる
- メソッドの用途
- 仕様決定の難しさ
- 用途を検討する
- 前例を検討する
- 既存のメソッドの問題
- まとめ
5.05 文字列中の式展開構文の一貫性 ——一貫性を優先
- バージョンによる式展開の違い
- 式展開の変更の影響
- まとめ
5.06 URI.encode_www_formとURI.decode_www_form ——間違いにくいAPI
- URI.decode_www_formとURI.encode_www_formメソッド
- 間違いに気がつきやすいAPI
- まとめ
- おわりに