首页 > 编程 > Ruby > 正文

Ruby中Block代码快的使用深度解析

2020-02-24 15:40:41
字体:
来源:转载
供稿:网友

  今天小编给大家分享一篇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代码快的使用深度解析,想必都了解了吧,更多相关内容请继续关注武林技术频道。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选