Blocks:代码段,使用起来就像参数(parameters)一样 先来说说Blocks的表现形式: 1.{puts "hi"} #用{}表示Blocks,请在只有一行的时候使用{} 2. do puts "hi" end #用do...end表示Blocks,多行的时候使用do...end...
说明:实际上,{}和do...end是一样的,可以使用在多行,但是ruby的标准,规定,{}用于只有一行的情况,而do...end使用在有多行的情况
使用Blocks: Blocks使用起来和parameters一样,可以这样用: 1.greet { puts "Hi" } #没有parameters的情况 2.verbose_greet("Dave", "loyal customer") { puts "Hi" } #有参数的情况 那Blocks是怎么样被方法所调用的?方法通过一个statement---yield来调用,例如: def call_block puts "Start of method" yield #yield部分被block代替 yield #1个method可以有多个yield puts "End of method" end call_block { puts "In the block" }
produces: Start of method In the block In the block End of method
yield: yield是一个statement,而不是method yield可以带parameters(此说法来源于《programming ruby》),比如:yield("hi",123),一个更加具体的例子:
#本代码模拟times def mytimes p mytimes(3){|i| p i} #p 是一个类似于print,puts的打印的method
结果: 0 上面的代码说明:yield的parameter,传递给了block里面对应的variable,block在利用variable进行有关操作。也许这一切有点难以理解,你可以想象block就是一个方法,它可以接受parameters,而|i|就是对参数的声明,yield会把自己的parameters传递到block里面。 *假如我们在方法里面放入了yield,但是在调用的时候没有使用block会是什么样的?允许吗? 例如: def mytimes p mytimes(3) #不使用block 结果: 4:in `mytimes‘: no block given (LocalJumpError)
所以,在使用了yields的情况下面,必须使用blocks 另外一个问题出来了,假如是yield带有参数,block却没有对应的参数,会怎么样? 例如: def mytimes p mytimes(3){} #无参数 结果:
#一个空白行,可以运行
再看: def mytimes p mytimes(3){|a,b| p a} #带有2个参数
结果: 0 继续看: def mytimes p mytimes(3){|a,b| p b} #这次打印 b
结果: nil
我想读者应该知道了吧,总结一下:出现yield就必须使用block,但是block和yield的parameters不一定要匹配,blocks中variable的初值是nil
iterators:(迭代器) iterators是一种method,object of collections 可以使用它,collections在Arrays and Hashes里面已经提到,最常见的就是Arrays and Hashes了,我们可以形象的认为他们的关系是:collection.literator,举例: animals = %w( ant bee cat dog elk ) # create an array animals.each {|animal| puts animal } # iterate over the contents each就是一个iterator,它是class Array 的一个方法
下面举例来说说各种iterators: [ ‘cat‘, ‘dog‘, ‘horse‘ ].each {|name| print name, " " } #这里有点要注意的就是,print后面可以接多个parameters,同样的p,puts都可以
5.times { print "*" } 5.times {|i| p i} # Fixnum 类的 iterators:times
3.upto(6) {|i| print i } # Fixnum 类的 iteratros:upto
(‘a‘..‘e‘).each {|char| print char } # Range 类的 iterators:each,Range也是一个collections,each在所有collections里都有定义
Range 类:表现形式,(1..9),(‘a‘..‘k‘)
|
|