商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 深入理解Ruby中的代码块block特性

深入理解Ruby中的代码块block特性

  发布于2026-06-29 阅读(0)

扫一扫,手机访问

block是什么?

深入理解Ruby中的代码块block特性

在Ruby里,“block”这个词你应该经常遇到。官方给出的定义是“一段被包裹着的代码”——坦白讲,看完这个定义,大多数人还是云里雾里。不如换个更直白的说法:block就像一段代码片段,可以被塞进一个变量里,随时随地拿出来跑。

光讲理论有点干,咱们直接看代码,从最基础的加法开始,一步步把它改造成block的形式,感受会更直观。

比如,对两个数做加法?

puts 5 + 6
# => 11

这样写当然没问题,但它只满足了block定义的前半部分——它是一段代码。可它没有被“包裹”起来,也没有存进变量。所以咱们继续改造,先让它更通用一点。

a = 5
b = 6
puts a + b
# => 11

好,用变量代替了数字,代码具备了通用性,但依然没有存进变量。现在咱们来实现真正的block。

addition = lambda { |a, b| return a+b }
puts addition.call(5, 6)
# => 11

看看,现在它被好好地包裹了起来,这就是一个block!lambda是Ruby里创建block最常用的方式,还有别的方法,不过先不展开。

这时候你可能会想:“等等,这不就是一个方法(method)吗,只是少了类和对象。” 没错,你可以把block理解为一个不绑定任何对象的方法。

继续深入,仔细看看block

一个block包含一块代码,你可以给它起个名字(通过变量),也可以直接传递。block的代码一律包裹在花括号{}或者do...end里。

[1, 2, 3].each do |i|
 puts i
end

#=> 1
  2
  3

上面这个例子,each方法后面跟着do...end,那就是一个block。

Ruby里任何一个方法都可以接受一个block。

  def test;end
  test{ puts i}

def test
  yield
 end
 test{puts "hello test!"}

 def test(x)
  yield(x)
 end
 test('world!'){|x| puts "hello #{x}"}

yield关键字不仅能挂载block,还能给block传参数。

def test(&block)
  block.call("world")
 end

 test{|msg| puts "hello #{msg}"}

这个block传进方法后,被&转成了一个Proc对象。

 def test(&block)
  inner_test(&block)
 end

 def inner_test
  yield("haha!")
 end

 test{|msg| puts "hello #{msg}"}

test方法把block转为Proc,内部的inner_test又用&把这个Proc转回block——灵活得很。

block是对象吗?

当然,和Ruby里其他东西一样,block也是对象。

empty_block = lambda { }
puts empty_block.object_id
# => 28765760
puts empty_block.class
# => Proc
puts empty_block.class.superclass
# => Object

你看,这个block有object_id,属于Proc类(Ruby对block的称呼),而Proc的父类就是Object

我们甚至可以反过来:从一个方法(method)生成block。说到底,方法就是绑定了某个对象的block,可以访问那个对象的状态。下面演示用方法创建block——请原谅糟糕的对象建模。

class Calculator
 def add(a, b)
  return a+b
 end
end

puts Calculator.new.add(5, 6)
# => 11

这段当然能正常工作。现在稍作修改:

class Calculator
 def add(a, b)
  return a+b
 end
end

addition_method = Calculator.new.method("add")
addition = addition_method.to_proc

puts addition.call(5, 6)
# => 11

瞧,一个传统的方法就这样被转换成了block!

block化你的代码!

咱们来构造4个block,分别做加、减、乘、除。每个block接收两个参数,执行运算并返回结果。

Addition = lambda { |a, b| return a+b }

Subtraction = lambda { |a, b| return a-b }

Multiplication = lambda { |a, b| return a*b }

Division = lambda { |a, b| return a/b }

# 使用的时候通过call来使用
Addition.call(5, 6)
# => 11

本文转载于:https://www.jb51.net/article/85251.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

产品推荐

热门关注