ruby 学习笔记(六) Blocks

A method can then invoke an associated block one or more time using the Ruby yield statement. Thus any method that wants to take a block as a parameter can use the yield keyword to execute the block at any time.

Program p022codeblock.rb illustrates what we have just discussed.

  1. =begin 
  2.   Ruby Code blocks are chunks of code between braces or 
  3.   between do- end that you can associate with method invocations 
  4. =end 
  5. def call_block 
  6.   puts 'Start of method' 
  7.   # you can call the block using the yield keyword 
  8.   yield 
  9.   yield 
  10.   puts 'End of method' 
  11. end 
  12. # Code blocks may appear only in the source adjacent to a method call 
  13. call_block {puts 'In the block'

The output is:

  1. >ruby p022codeblock.rb 
  2. Start of method 
  3. In the block 
  4. In the block 
  5. End of method 
  6. >Exit code: 0 

If you provide a code block when you call a method, then inside the method, you can yield control to that code block - suspend execution of the method; execute the code in the block; and return control to the method body, right after the call to yield. If no code block is passed, Ruby raises an exception:

  1. no block given (LocalJumpError) 

You can provide parameters to the call to yield: these will be passed to the block. Within the block, you list the names of the arguments to receive the parameters between vertical bars (|).

The program p023codeblock2.rb illustrates the same.

  1. # You can provide parameters to the call to yield: 
  2. # these will be passed to the block 
  3. def call_block 
  4.   yield('hello', 99) 
  5. end 
  6. call_block {|str, num| puts str + ' ' + num.to_s} 

The output is:

  1. >ruby p023codeblock2.rb 
  2. hello 99 
  3. >Exit code: 0 

Note that the code in the block is not executed at the time it is encountered by the Ruby interpreter. Instead, Ruby remembers the context in which the block appears and then enters the method.

A code block's return value (like that of a method) is the value of the last expression evaluated in the code block. This return value is made available inside the method; it comes through as the return value of yield.

block_given? returns true if yield would execute a block in the current context. Refer to the following example:

  1. def try 
  2.   if block_given? 
  3.     yield 
  4.   else 
  5.     puts "no block" 
  6.   end 
  7. end 
  8. try # => "no block" 
  9. try { puts "hello" } # => "hello" 
  10. try do puts "hello" end # => "hello" 

Block Variables

Let us see what happens in the following example when a variable outside a block is x and a block parameter is also named x.

  1. x = 10 
  2. 5.times do |x
  3.   puts "x inside the block: #{x}" 
  4. end 
  5.  
  6. puts "x outside the block: #{x}" 

The output is:

  1. x inside the block: 0 
  2. x inside the block: 1 
  3. x inside the block: 2 
  4. x inside the block: 3 
  5. x inside the block: 4 
  6. x outside the block: 10 

You will observe that after the block has executed, x outside the block is the original x. Hence the block parameter x was local to the block.

Next observe what happens to x in the following example:

  1. x = 10 
  2. 5.times do |y
  3.   x = y 
  4.   puts "x inside the block: #{x}" 
  5. end 
  6.  
  7. puts "x outside the block: #{x}" 

The output is:

  1. x inside the block: 0 
  2. x inside the block: 1 
  3. x inside the block: 2 
  4. x inside the block: 3 
  5. x inside the block: 4 
  6. x outside the block: 4 

Since x is not a block parameter here, the variable x is the same inside and outside the block.

In Ruby 1.9, blocks introduce their own scope for the block parameters only. This is illustrated by the following example:

  1. x = 10 
  2. 5.times do |y; x| 
  3.   x = y 
  4.   puts "x inside the block: #{x}" 
  5. end 
  6. puts "x outside the block: #{x}" 

The output is:

  1. x inside the block: 0 
  2. x inside the block: 1 
  3. x inside the block: 2 
  4. x inside the block: 3 
  5. x inside the block: 4 
  6. x outside the block: 10 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值