Ruby Baseのコードブロック、反復子、プロシージャオブジェクト
2968 ワード
ルビーではすべて対象.コードブロックもオブジェクトです!Rubyでは,コードオブジェクトをコードブロックと呼ぶ.コードブロックを小さなプログラムユニットに想像することができます.Rubyコードが含まれており、実行時にメソッドに移行できます.Python,C,Javaで同様の概念は,関数ポインタ,匿名関数,内部クラス,コールバック関数である.
Rubyコードブロックの構文は,Rubyコードを括弧の間に置くかdo/endコマンドの間に置く.次のようになります.
簡単な例では、{puts"hello world"}は有効なコードブロックです.では、これらのコードブロックをどのように使用して、コードのセットとしてメソッドに渡すべきですか?このためには、まず次のような簡単な方法を定義します.
コマンドyieldは制御をコードブロックに渡します(この方法に渡されます).次のコードは、コードブロックがどのように上の方法に渡されたかを示します.
yieldが呼び出されるたびに、メソッドに渡されるコードブロックが実行されます.次は、コードブロックを使用してより多くの作業を行う別のより複雑な方法の例です.
コードブロックはRuby全体に適用される.最も重要なことは,Array,Hash,さらにStringのようないくつかのクラスのiterator法に,Ruby内部でコードブロックが適用されることである.コードブロックはどのタスクを実行するかを定義します(典型的には、要素のタスクです).コードブロックとiteratorの使用をさらに説明するために、小さな例を提供します.いくつかのフィールド動物類を定義したと仮定します.(図3に示すように)、これらの動物の配列もあり、この配列にコードブロックと反復子を使用することで、各動物を発声させることができます.
図3.簡単な庭動物類
barnYardで呼び出される各メソッドは、配列上のiteratorメソッドの1つです.なお、|記号は、受信する参照を定義するために使用されます.この例の場合、コードブロックはパラメータを受信する.すなわちbarnYardの各動物を反復子としてこの動物集合を遍歴する.
反復子とコードブロックは、かなり簡単できれいなことをすることができます.
はい、Integerクラスでも反復子(timesメソッド)が提供されています.コードブロックを使用してループ操作を迅速に実行します.
コードブロックと反復子に関する議論を離れる前に、コードブロックが変数に割り当てられることも知っておくべきです.実際,このようなコードブロックは実際にはProcクラスの例である.newメソッドを使用してProcインスタンスを定義するか、これらのProcインスタンスを使用します.これらのインスタンスは後でcallメソッドを使用して呼び出すことができます.
これにより、再利用可能なコードブロックを任意の場所で実行可能なオブジェクトとしてパッケージして渡すことができます.次に、Rubyで再利用可能なコードの例を示します.
Rubyコードブロックの構文は,Rubyコードを括弧の間に置くかdo/endコマンドの間に置く.次のようになります.
{
# ...
}
do
#...
end
簡単な例では、{puts"hello world"}は有効なコードブロックです.では、これらのコードブロックをどのように使用して、コードのセットとしてメソッドに渡すべきですか?このためには、まず次のような簡単な方法を定義します.
def someMethod
yield
end
コマンドyieldは制御をコードブロックに渡します(この方法に渡されます).次のコードは、コードブロックがどのように上の方法に渡されたかを示します.
irb(main):001:0> someMethod {puts "hello world"}
hello world
yieldが呼び出されるたびに、メソッドに渡されるコードブロックが実行されます.次は、コードブロックを使用してより多くの作業を行う別のより複雑な方法の例です.
irb(main):001:0>
def fibonacci (stop)
while stop < 20
stop=yield
end
end
=> nil
irb(main):006:0>
i=0; j=1; fibonacci(j) {puts i; temp = i; i = j;j = temp + j}
0
1
1
2
3
5
8
コードブロックはRuby全体に適用される.最も重要なことは,Array,Hash,さらにStringのようないくつかのクラスのiterator法に,Ruby内部でコードブロックが適用されることである.コードブロックはどのタスクを実行するかを定義します(典型的には、要素のタスクです).コードブロックとiteratorの使用をさらに説明するために、小さな例を提供します.いくつかのフィールド動物類を定義したと仮定します.(図3に示すように)、これらの動物の配列もあり、この配列にコードブロックと反復子を使用することで、各動物を発声させることができます.
図3.簡単な庭動物類
irb(main):031:0>
barnYard = [Cow.new, Duck.new, Chicken.new, Horse.new, Dog.new]
=> [#<Cow:0x58d2f48>, #<Duck:0x58d2f30>, #<Chicken:0x58d2f00>, #<Horse:0x58d2ee8>, #<Dog:0x58d2ed0>]
irb(main):032:0>
barnYard.each {|animal| animal.talk}
Mooooo
Quack
Cluck-cluck
Naaaay
Bark bark
barnYardで呼び出される各メソッドは、配列上のiteratorメソッドの1つです.なお、|記号は、受信する参照を定義するために使用されます.この例の場合、コードブロックはパラメータを受信する.すなわちbarnYardの各動物を反復子としてこの動物集合を遍歴する.
反復子とコードブロックは、かなり簡単できれいなことをすることができます.
irb(main):001:0>
3.times {puts "Ruby is cool!"}
Ruby is cool!
Ruby is cool!
Ruby is cool!
はい、Integerクラスでも反復子(timesメソッド)が提供されています.コードブロックを使用してループ操作を迅速に実行します.
コードブロックと反復子に関する議論を離れる前に、コードブロックが変数に割り当てられることも知っておくべきです.実際,このようなコードブロックは実際にはProcクラスの例である.newメソッドを使用してProcインスタンスを定義するか、これらのProcインスタンスを使用します.これらのインスタンスは後でcallメソッドを使用して呼び出すことができます.
irb(main):003:0> simpleProc.call
hello
=> nil
irb(main):004:0> anotherProc.call("hello yourself")
hello yourself
=> nil
これにより、再利用可能なコードブロックを任意の場所で実行可能なオブジェクトとしてパッケージして渡すことができます.次に、Rubyで再利用可能なコードの例を示します.
irb(main):001:0>
def simpleMethod(aProc)
puts "Is Ruby cool or what?"
aProc.call("Way cool dude!")
end
=> nil
irb(main):005:0>
simpleMethod(anotherProc)