深入理解Ruby中的代码块block特性
Ruby中的block是包裹的代码片段,可赋值给变量并通过call调用,类似未绑定对象的方法。通常由lambda或do...end创建,通过yield挂载并传参,也可用&转为Proc类对象。方法也能通过to_proc转化为block。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
WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,
Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。
REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。
Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理工具,可在 Windows 上完成照片修饰、选区抠图、图层合成、文字排版、绘画及生成式编辑。软件采用订阅授权,由 Creative Cloud 管理安装、更新与许
Adobe InDesign 是面向印刷与数字出版的专业页面排版工具,可制作书籍、杂志、宣传册、海报、交互式 PDF 和电子书。它提供精细的文字样式、多页面管理、印前检查及多格式输出能力,并能与 Photoshop、Illustrator
Adobe Illustrator 是用于绘制矢量图形、插画、图标、徽标和版式的专业设计工具。它以路径和锚点为核心,作品放大后仍能保持清晰,并提供画板、文字、渐变、图像描摹及精确变换等功能,适合品牌视觉、印刷物料、数字界面和商业插画创作。













