たのしいRuby 第21章 Mix-in
21章に入る前に、昨日の復習をしておきたいと思う。やはりyieldの理解度が足りない。
yieldの復習。
昨日、イマイチわからなかったのが、何処のブロック呼び出しなのか。
プログラミングRuby言語編の4章に答えはあった。
シンプルにyieldを呼び出してみる。
def hello yield yield yield end hello {puts "Hello, yield World!!"} #=> Hello, yield World!! #=> Hello, yield World!! #=> Hello, yield World!!
helloで指定したブロックを呼び出してます。シンプルだとわかりやすいっすね。
「yield 引数」だった場合は、
def hello_itelator (1..3).each do |i| yield "#{i}times" end end hello_itelator {|message| puts "Hello, #{message} yield World!!"} #=> Hello, 1times yield World!! #=> Hello, 2times yield World!! #=> Hello, 3times yield World!!
message | の中に「3times」という文字が入りました。yieldを呼ぶと、 |
def hello_itelator (1..3).each do |i| puts "Hello, #{i}times yield World!!" end end
こんな感じに展開されるようです。
yieldは呼び出し元のブロックを実行する機能を備えている事がわかりました。C言語の関数ポインタみたいですね。
ところで、yieldって何て読むの?
おぉ。JavaScriptにもyield
IT戦記 - JavaScript 1.7 の yield が凄すぎる件について
yield波はJavaScriptにも波及しているようです。
と、思ったけど、
avaScriptのyieldは値をreturnする。次回の呼び出しはyieldしたところからスタートする。関数を一時停止させる役目があるだけだった・・・。
"ブロックを呼び出す機能は無い。"
Rubyとは全然、全く関係ない!!!!!!!!!!!!!激しくツマンネ。ガックリ来た・・・orz
Mix-inって何だぁ?
継承関係を保ったまま"機能だけ"継承する仕組みらしい。
class Array < Object include Enumerable end
ArrayはObjectを継承し、機能としてEnumerable(eachとかsortとか)を提供する。
Javaだと、いちいち委譲しなければいけないところを、モジュールとして提供することによって、継承関係を崩さずに、新しい機能を追加出来る!!
つまり・・・プログラマは、機能を作ることに集中することが出来る!!
楽しみですねぇ〜。では、遅めの21章スタート。
モジュールを作ってみる。
HumanクラスとRabbitクラスを作って、動けぇ〜と命令してみます。
module Walk def move puts "歩きます。" end end module Jump def move puts "ジャンプします。" end end class Animal attr_accessor :name end class Human < Animal include Walk end class Rabbit < Animal include Jump end tanaka = Human.new puts tanaka.name = "たなか" tanaka.move #=> たなか #=> 歩きます。 pickaxe = Rabbit.new puts pickaxe.name = "ピッケル" pickaxe.move #=> ピッケル #=> ジャンプします。
moduleをincludeすることで、共通する機能をまとめることが出来ました。カンタンですね。
組込みモジュールをinclude
昨日作ったBookクラスを利用して、ComparableやEnumerableをインクルードしてみた。
長いのでソースは略。
- Comparableは<=>を定義する必要がある。
- Enumerableはeachを定義する必要がある。
色々ルールがありそうです。