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
新聞熱點
疑難解答