SSブログ

Rubyのyieldの使い方ってどうなってんだ。 [プログラミング]

Rails3でyieldが使われているので、今のうちに使い方を覚えておこうと思った。ググったらみんな分かりづらいらしくて、説明にしてもあんまり明白な使い方を示したものがない。どちらかと言えば、挙動はこうなっているって物が多い。

yieldはそもそもメソッドとかじゃなくて、Ruby組み込みのキーワードだったりする。見た目メソッドなんだけど、汎用性から考えたらキーワードというのも分かる。

 

一言で言うなら、ブロック部分のコールバック、という事になりそうだけど、何となく分かりづらい。とかやってると、やっぱり挙動を見せて納得する事になっちゃう。やっぱり仕方ないのか。

ファイルを開ける時にopenメソッドにwhile文を渡したりしていますが、ブロック付きのメソッドを作る時に使うものらしい。あぁだからイテレータを自分で定義する時に使うって話が出てくるんですね。

もともとブロックを受け取る場所がyieldで受け取った処理を、その場所にはめるようになっているみたいですね。実際のopen文がどう定義されているかソースを見たい気がしてきました。ええと、どこにあるんだろう。コンパイルされてないだろうから、実行環境がソースがそのままありそうなもんだけど。open-uri.rbあたりにありそうなんだが、正直ディレクトリが深過ぎたりして、本質を掴みにくかったりする。

yieldを含むメソッドでは、yield以外はいっつも使う処理で、yieldで詳細を決めるって寸法らしい。だから、yieldで引数を渡されない場合でも全然問題なくて、その場合は状況によるデータを使わないで処理するだけって話で、別に引数をもらってないからって、処理分けに意味がないわけじゃない事になる。むしろ、処理する場合の場合分けに、データの条件で拘泥されなくなるのかな? そこいらは動的な言語ってことになるのかな。いまいちケースが思いつけないところに、プログラマとしての資質のなさに苛まれるわけで。

Rubyは何でもオブジェクトなオブジェクト指向言語だから、ブロックとしてオブジェクトを渡しやすいってのもあるんだろうけども、後から処理を入れ込むってのも性に合ってるかもって、ちょっと思って来た。ダックタイピングとかを適当さの言い訳に使ったりするヤツなので、いろいろ後先を考えてインプリしているわけじゃない。


むかーしの本をひっくり返して引用。
def twice
  puts yield
  sleep 1
  puts yield
end

twice do
  Time.now
end

一秒ごとに何するかは後で決めて実装するって訳ね。んで、引数もらう時はdoの後に|hoge|として、hogeオブジェクトをもらう、と。今回はもらってないけど、これで物があるべき場所に落ち着いた感じ。

こんなものRubyの初歩に学ぶものなんだろうけど、結局、始めは決められた文法で、その言語を使う事が主になっちゃうから、わりと核心になるところは後回しになっちゃうんだよなぁ。そんで、大抵の事が出来るようになっちゃうと、核心のところはたくさん出てきちゃって顕在化して面倒で放置ってのがいつものパターン。使えれば中身なんてそんなに興味ないっすよね、普通。いや、初歩だから知ってなきゃダメなところなんだろうけど、ある程度鵜呑みにしちゃったところって、後で論理的に詰めていくのが面倒になってしまうところは、なきにしもあらず、な訳で。Rubyのコア部分に手を出す小学生とかすごいなぁと思っちゃうけど、それで触発されるところなんて全然なし。いい加減だなぁ。



そういや、Railsのyieldが結局何やってるかなんだけど、

app/views/layouts/application.html.erb



app/views/hoges/index.html.erb

が、埋め込まれるらしい。

埋め込まれるものは、rake routes で見る事ができて、状況によって割り振りされるんだと思う。大体やる事は同じだから、scaffoldで作るとみんなお膳立てしてくれる、みたい。
$ rake routes
    employees GET    /employees(.:format)          {:action=>"index", :controller=>"employees"}
              POST   /employees(.:format)          {:action=>"create", :controller=>"employees"}
 new_employee GET    /employees/new(.:format)      {:action=>"new", :controller=>"employees"}
edit_employee GET    /employees/:id/edit(.:format) {:action=>"edit", :controller=>"employees"}
     employee GET    /employees/:id(.:format)      {:action=>"show", :controller=>"employees"}
              PUT    /employees/:id(.:format)      {:action=>"update", :controller=>"employees"}
              DELETE /employees/:id(.:format)      {:action=>"destroy", :controller=>"employees"}

タグ:Ruby Rails3
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。