~/journal/2024/11/passing-block-arguments-in-ruby

在 Ruby 中传递块参数

快速了解 Ruby 中 `&` 运算符的用法,从 `Symbol#to_proc` 到将方法对象转换为块。

发布
阅读时间
1 分钟
标签
RubyTips

本页由 AI 从原文翻译。

在 Ruby 中,我们可以通过在参数前加上 & 来向函数传递块参数。让我们通过示例来看一下。

Symbol

一个常见的实现 to_proc 的对象示例是 Symbol。

ruby
["a", "b", "c"].map { |s| s.upcase } # => ["A", "B", "C"]
["a", "b", "c"].map(&:upcase)        # => ["A", "B", "C"]

这两行代码的行为完全相同。

之所以能这样工作,是因为 Symbol 实现了 to_proc 方法。它所做的就是*接收这个 proc 的参数,并调用与该符号名称匹配的方法。*

我们经常会看到这种语法作为接受简单块(如 map 或 sort_by)的方法的快捷方式。

让它更简单

我们可以向函数传递普通的 do 块,但有时我们可以让它更简单。让我们看一个示例。

ruby
numbers = 1..5

operator = gets

number = Integer(gets)

if operator.start_with?("t")
  puts numbers.collect { |n| n * number }.join(", ")
else
  puts numbers.collect { |n| n + number }.join(", ")
end

这段代码能工作,但很丑陋。我们可以像下面这样重构它。

ruby
numbers = 1..5

operator = gets

number = Integer(gets)

if operator.start_with?("t")
  calc = ->(n) { n * number }
else
  calc = ->(n) { n + number }
end

puts numbers.map(&calc).join(", ")

在这个版本中,我们将正确的块赋值给名为 calc 的变量,然后将 calc 传递给方法 map,并在前面加上 &。

但还有更短的写法。Ruby 对象有一个名为 `method` 的方法,它接受一个符号并返回该对象中同名的方法。

ruby
operators = get

number = Integer(gets)

method = number.method(operator.start_with?("t") ? :* : :+)

puts (1..5).map(&method).join(", ")

在这种情况下,我们使用 method 根据输入获取名为 :+ 或 :* 的方法,并利用 & 的 to_proc 能力创建一个调用该方法的 proc。

Epona
作者Epona

There's nothing wrong with having a little fun

x.com/simura_epona

相关文章

正在加载评论…