パーフェクトRubyから泣く泣く削った標準添付ライブラリ パーフェクトRuby Advent Calendar 2013(12日目)
なんとなく12日が空いていたので書いてみます*1。
このエントリは パーフェクトRuby Advent Calendar の12日目のエントリです。 前の日のエントリはイオリさん http://iori-o.github.io/blog/2013/12/11/perfect-ruby-2013-12-11/ でした。
- 作者: Rubyサポーターズ,すがわらまさのり,寺田玄太郎,三村益隆,近藤宇智朗,橋立友宏,関口亮一
- 出版社/メーカー: 技術評論社
- 発売日: 2013/08/10
- メディア: 大型本
- この商品を含むブログ (10件) を見る
パーフェクトRubyから泣く泣く削った標準添付ライブラリ
ページ数の都合で泣く泣く削ることになってしまった部分というのが多少なりともあります。その他にこれも載せたほうが良いんだけどページ数が(ryというのもあります。
そこで削ってしまったけど、本当はあると良かったなというのを紹介します。
IO#select
これはいわゆるselect(2)を提供してくれます。select(2)って何スカっていうとman select 2
すれば良いじゃないって感じなんですけど、たぶんIOオブジェクト(もっと言うとファイルディスクリプタかな)を待ち受けて、読み取り準備ができたオブジェクトを返すって感じですかね。
で?っていう
例えば、TCPServerのサンプルとかで使われてるので、こういう事例を見ると良いと思う。
ここのサンプルソースでTCPServerを使ったエコーサーバがある。
require "socket" gs = TCPServer.open(0) socks = [gs] addr = gs.addr addr.shift printf("server is on %s\n", addr.join(":")) while true nsock = select(socks) next if nsock == nil for s in nsock[0] if s == gs socks.push(s.accept) print(s, " is accepted\n") else if s.eof? print(s, " is gone\n") s.close socks.delete(s) else str = s.gets s.write(str) end end end end
これの nsock = select(socks)
ってところで使われている。実はKernel#selectはIO#selectと同じなので、単にselectとも書けるのだった。
ここでやってるのはTCPServerをopenして開いたsocketをIO#selectで待って、入力があったらその文字列をそのまま返却する(s.write(str)
のところ)というのをやってるわけですね。
ちなみに、上記のスクリプトを実行するとこんな感じで出力がある。
% ruby sample.rb server is on 51450:0.0.0.0:0.0.0.0
そうしたら、別のターミナルからおもむろに telnet localhost 51450*2 して、何か文字列を打ってみると動作を確認できます。
このIO#selectというのは配列の配列で返ってくるのでなかなかデータ構造を把握するのが大変なのですが、こういう低レイヤーっぽいものの動作を調べるのもなかなか楽しいですよね。
次のアドベンターは id:akiinyo さんです。本書のレビューでも助けて頂きました……!!