Rubyの勉強 01

クローラー作りたいぜとか言って、初歩の初歩のWebページの読み込みで既に失敗しているというのもまずいのだが…。
まず、私がサンプルプログラムを読めてない

require 'open-uri'
open("http://www.ruby-lang.org/") {|f|
  f.each_line {|line| p line}
}

高々3行のサンプルであるし、意味も簡単と推測できる。
しかし、今迄の知識でこんな書き方にお目に掛かったことがない。
浦島太郎も良いところだ。

1行目は分かる。
"open-uri"と言うライブラリを読み込んでいる。
# しかし、リファレンスを見てrequireがモジュール関数であることには仰天した。
# 構文やディレクティブじゃないんだ。

open-uriのお陰でopenメソッドはWebページをURLで指定することで
ファイルストリームと同じように読み込める。
再定義してるのかラップしてるのか仕組みは分からんが後回しでいいだろう。
問題はその後。{}で囲まれている(ーー;)
関数の後にブロックを作ってる?それに|f|ってなんだ。
そしてf.each_lineで普通に読み込んだストリームを利用している。
each*は経験上何となく分かる。
その後にまたブロックが出てきて戸惑うが、|line|と書いて、
p lineと利用している。
つまり、lineと言う変数(?)を作りfの最初から終わりまで
1行ずつ取り出して突っ込んでるということか。
pは何なんだ?と思ったがこれはすぐに分かる。
表示してるのね、lineを。printの略かなんかなんだろう。
ということは|f|と言う書き方も分かる。
読み込んだストリームをfに突っ込んでるんだ。

と予想を立てたところでopen-uriのリファレンスを見てみる。

Kernel.#openを再定義します。

と要約に書いてあった。こんな分かりやすいところに書いてあるものを忘れるのか。
このページ、使用例しか書いてないな。
Kernel.#openを見て定義を考えるしかないのかな。
Kernel.#openを見る。普通のファイルの開き方が書いてあるが、最後の方まで見てみると
open-uriでの定義がちゃんと書いてあった。

open(name, mode = 'r', perm = nil, options = {}) -> StringIO | File[permalink][rdoc] [redefined by open-uri]
open(name, mode = 'r', perm = nil, options = {}) {|ouri| ...} -> nil [redefined by open-uri]

nameにはURIを渡す。URIと書いてあるが今はURLと読み替えて差し支えないだろう。
第2、第3、第4引数はサンプルでは書かなかった。
デフォルト値が入っている引数は省略できるということか。

ブロックを与えた場合は上の場合と同様、name が http:// や ftp:// で 始まっている文字列なら URI のリソースを取得した上で StringIO オブジェクトを 引数としてブロックを評価します。後は同様です。 StringIO オブジェクトは OpenURI::Meta モジュールで extend されています。

と書いてある。
「StringIO オブジェクトを 引数としてブロックを評価します。」って何だよと思ったのだが、
単純にブロックに引数を渡せるということか…。
つまり定義の|ouri|はStringIOオブジェクトのブロック引数と。
ブロック引数ってなんだよ。自分で言ってて気持ち悪いよorz
何か名前があるのかな。

ここまで来れば後はStringIOを見てみればその後の意味も分かりそうだ。
each_lineメソッドを見ると、他のメソッド群とまとめられて、

自身から 1 行ずつ読み込み、それを引数として与えられたブロックを実行します。

と説明されている。つまり、サンプルでは1行ずつ読み込んで、p lineを実行したわけだ。
最後にp。これは予想通りだったが、ちゃんと引用すると、

引数を人間に読みやすい形に整形して改行と順番に標準出力 $stdout に出力します。主にデバッグに使用します。

とのこと。標準出力に出力するよ、と。あと主にデバッグ用途だよと。


長かった(ーー;)
これはちゃんと勉強しないと苦戦するどころか、プログラムが書けないな。
ということで本を買いました(・ω・ )

1日…じゃ厳しい気がしてきた。3日位で読めないかな。