Block
定义
some_array.each { |value| puts value + 3 }sum = 0other_array.each do |value| sum += value puts value / sumendA block is somewhat like the body of an anonymous method Block can take parameters Block 只有被 method 调用时才会起作用,如果 method 中有参数,block 出现在最后面
Block 中的变量
如果 block 的本地变量的名字和 block 之外但是在同样 scope 里面的 变量名字一样,那他们两个是一样的。block 内变量的值会改变 block 外变量的值。
sum = 0[1,2,3,4].each do |value| sum += value puts value / sumendputs sum # => 30
如果 block 中的变量只出现在 block 中,那么它只是 block 中本地变量,无法在 block 之外被引用。
sum = 0[1,2,3,4].each do |value| square = value * value sum += squareendputs sum # => 30puts square # undefined local variable or method 'square' for main:Object <NameError>Parameters to a block are always local to a block, even if they have the same name as locals in the surrounding scope.value = "some shape"[1,2].each { |value| puts value }puts value# 1# 2# some shapeYou can define a block-local variables by putting them after s semicolon in the block's parameter listsquare = "some shape"sum = 0[1,2,3,4].each do |value; square| square = value * value sum += squareendputs sum # 30puts square # some shapeBy making square block-local, values assigned inside the block will not affect the value of the variable with the same name in the outer scope. Blocks for Transactions You can use blocks to define a chunk of code that must be run under some kind of transnational control
class File def self.open_and_process(*args) f = File.open(*args) yield f f.close endendFile.open_and_process("testfile","r") do |file| while line = file.gets puts line endend
Blocks Can Be Objects
You can convert a block into an object, store it in variables, pass it around, and then invoke its code later.
如果 method 的最后一个参数前面有 & 符号 (&action), 那么当此 method 被调用时,Ruby 会找一个 code block, 这个 code block 被转换成 class Proc 的一个对象。
class ProcExample def pass_in_block(&action) @stored_proc = action end def use_proc(parameter) @store_proc.call(parameter) endendeg = ProcExample.neweg.pass_in_block { |param| puts "The parameter is #{param}" }eg.use_proc(99)# => The parameter is 99def create_block_object(&block) blockendbo = create_block_object { |param| puts "You called me with #{param}" }bo.call 99 # => You called me with 99bo.call "cat" # => You called me with catRuby have two built-in methods that convert a block to an object: lambda and Proc.newbo = lambda { |param| puts "You called me with #{param}" }bo.call 99 # => You called me with 99
新闻热点
疑难解答