今天小編給大家分享一篇Ruby中Block代碼快的使用深度解析,感興趣的朋友跟小編一起來了解一下吧!
Block 定義
some_array.each { |value| puts value + 3 }
sum = 0
other_array.each do |value|
sum += value
puts value / sum
end
A 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 / sum
end
puts sum # => 30
如果 block 中的變量只出現在 block 中,那么它只是 block 中本地變量,無法在 block 之外被引用。
sum = 0
[1,2,3,4].each do |value|
square = value * value
sum += square
end
puts sum # => 30
puts square # undefined local variable or method 'square' for main:Object
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 shape
You can define a block-local variables by putting them after s semicolon in the block's parameter list
square = "some shape"
sum = 0
[1,2,3,4].each do |value; square|
square = value * value
sum += square
end
puts sum # 30
puts square # some shape
By 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
end
end
File.open_and_process("testfile","r") do |file|
while line = file.gets
puts line
end
end
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)
end
end
eg = ProcExample.new
eg.pass_in_block { |param| puts "The parameter is #{param}" }
eg.use_proc(99)
# => The parameter is 99
def create_block_object(&block)
block
end
bo = create_block_object { |param| puts "You called me with #{param}" }
bo.call 99 # => You called me with 99
bo.call "cat" # => You called me with cat
Ruby have two built-in methods that convert a block to an object: lambda and Proc.new
bo = lambda { |param| puts "You called me with #{param}" }
bo.call 99 # => You called me with 99
Blocks Can Be Closures
Closure: Variables in the surrounding scope that are referenced in a block remain accessible accessible for the life of that block and the life on any Proc object created from that block.
def n_times(thing)
lambda {|n| thing * n}
end
p1 = n_times(23)
p1.call(3) #=> 69
p2.call(4) #=> 92
def power_proc_generator
value = 1
lambda { value += value }
end
power_proc = power_proc_generator
puts power_proc.call # 2
puts power_proc.call # 4
lambda 表達式的另一種簡寫方式
lambda { |params| ... }
# 與下面的寫法等價
-> params { ... }
# parmas 是可選的
proc1 = -> arg1, arg2 {puts "#{arg1} #{arg2}"}
proc1.call "hello", "world"
# => hello world
proc2 = -> { "Hello World" }
proc2.call # => Hello World
Block Parameter List
Blocks can take default values, splat args, keyword args and a block parameter
proc = -> a, *b, &block do
puts "a = #{a.inspect}"
puts "b = #{b.inspect}"
block.call
end
proc.call(1,2,3,4) {puts "in block"}
# a = 1
# b = [2,3,4]
# in block
以上就是Ruby中Block代碼快的使用深度解析,想必都了解了吧,更多相關內容請繼續關注武林技術頻道。
新聞熱點
疑難解答
圖片精選