読者です 読者をやめる 読者になる 読者になる

Programming log - Shindo200

イベント参加記録とプログラミング系の雑記

Rubyライブラリのソースコードリーディング(Sinatra編)

東京Ruby会議10で「ライブラリのソースコード読むと勉強になる」とのお話がありました。読んでみたいけど、初めて読むのに良いライブラリは何なのかわかりません。1000行くらいのライブラリなら読めそうだと思ったので、コードの行数でライブラリを調べてみたところ、Sinatra の base.rb が約1700行だと知りました。初めてでも読めそうな量なので、今回は Sinatra(1.3.4) の base.rb を読んでみることにしました。

コードリーディング環境

tmux でコンソール画面を分割し、片方の画面でソースコードを開き、もう片方の画面で pry を起動しました。こうしておくと、ソースコードを読んでいて気になった構文があれば、pry ですぐに確認できて便利です。また、git でコードリーディング用のブランチを作っておいて、気になったことはコードに直接コメントを書き入れていきました。
f:id:Shindo_Masaya:20130219234825j:plain:w400

Sinatra コードリーディングの感想

難易度が高かったです。最初の700行くらいはリクエストとレスポンスの処理が書いてあります。これらは Rack のクラスを継承しているので、Rack のコードも読まないとわからないところがあります。わからないところはあまり深く考えず、「このメソッドはこんな入力を与えて、こんな出力を返すのだろう」ぐらいの予想で進めてみました。わからないところでも、普段はあまり使わないメソッドを知ることができたり、コーディングの勉強になったりしました。

コーディングについて学んだこと

・begin でコードをまとめる書き方がある。

str = "text/html,text/xml,*/*;q=0.8"
env = begin
  entries = str.split(',')
  entries.map {|e| accept_entry(e) }.sort_by(&:last).map(&:first)
end

例外捕捉のためではなく、コードをまとめるために begin を使っています。ローカル変数 entries は begin の外でも有効です。


・String === で、インスタンスが String クラスかどうか判断できる。

value = "foo"
"OK." if String === value

value は Stringクラスなので true になります。また、インスタンスが指定したクラスのサブクラスでも true になります。

value = "foo"
"OK." if Object === value

インスタンスが指定したモジュールをインクルードしたクラスのサブクラスでも true になります。

value = "foo"
"OK." if Kernel === value

is_a? と同じと考えて良さそうです。

まとめ

・コード行数でコードリーディングするライブラリを選ぶのは、あまり良くない。
Ruby に精通していない人が、いきなり Sinatra のコードを読むのは少し難しい。
・先に Rack のソースコードを読んだほうが良いかもしれない。
・動作がわからなくても、コーディングの勉強になる。
・一人でコーディングしているときはあまり使わないメソッドが出てくるので、Rubyのメソッドの勉強になる。

次回の予定

Rake が易しめという情報をいただいたので、他に良さそうなライブラリがなければ Rake を読みます。