写ref="/tag/2028/" style="color:#C468A7;font-weight:bold;">Ruby代码时,你有没有遇到过这样的场景:需要遍历一个数组,对每个元素做点操作,比如打印、计算或者筛选。最开始可能用while或for循环,写起来啰嗦还容易出错。其实Ruby早就给你准备了更顺手的工具——脚本块和迭代器。
块(Block)是Ruby的灵魂之一
块不是方法,也不是对象,但它能被方法调用。它用do...end或花括号{}包围,紧跟在方法后面。最常见的就是each遍历:
[1, 2, 3].each do |n|
puts "数字是 #{n}"
end
这段代码比传统的for循环更清晰,也更符合Ruby的表达习惯。块里的|n|是参数,代表当前元素。
迭代器让重复操作变简单
Ruby中很多方法都设计成支持块的“迭代器”。比如map用来转换数据:
names = ['alice', 'bob', 'charlie']
scores = names.map { |name| name.upcase }
# => ['ALICE', 'BOB', 'CHARLIE']
再比如select用来过滤:
ages = [20, 25, 18, 30]
adults = ages.select { |age| age >= 21 }
# => [25, 30]
这些方法本身不干具体活,它们把控制权交给块,由你来定义“我想做什么”,这种灵活性正是Ruby的魅力所在。
自定义方法也能接收块
你写的函数也可以支持块。用yield就能在方法里执行传入的块:
def twice
yield
yield
end
twice { puts "Hello" }
# 输出两次 Hello
如果想更灵活地处理块,可以用&block把它变成一个Proc对象:
def run_if_true(condition, &block)
block.call if condition
end
run_if_true(true) { puts "条件成立!" }
这样你可以判断是否为空、传递给其他方法,控制力更强。
实际应用场景
假设你在处理一批用户上传的文件,需要逐一检查格式、重命名、保存。用迭代器可以写得非常流畅:
files = ['photo.jpg', 'doc.pdf', 'image.png']
files.each_with_index do |filename, index|
ext = filename.split('.').last
if ['jpg', 'png'].include?(ext)
puts "第#{index+1}个是图片:#{filename}"
end
end
代码读起来像自然语言,逻辑清晰,维护起来也省心。
Ruby的块和迭代器不只是语法糖,它们改变了你组织代码的方式。学会用好它们,你会发现原本冗长的循环变成了几行优雅的表达,工作效率自然就上去了。