您可能熟悉以下Ruby速记(a是一个数组):

a.map(&:method)

例如,在irb中try 以下操作:

>> a=[:a, 'a', 1, 1.0]
=> [:a, "a", 1, 1.0]
>> a.map(&:class)
=> [Symbol, String, Fixnum, Float]

语法a.map(&:class)a.map {|x| x.class}的简写.

在"What does map(&:name) mean in Ruby?"中阅读更多关于这种语法的内容.

通过语法&:class,可以对每个数组元素进行方法调用class.

我的问题是:你能为方法调用提供参数吗?如果是,怎么做?

例如,如何转换以下语法

a = [1,3,5,7,9]
a.map {|x| x + 2}

&:语法?

我并不是说&:语法更好.

我假设你知道+是整数类上的一个方法.你可以在irb中try 以下方法:

>> a=1
=> 1
>> a+(1)
=> 2
>> a.send(:+, 1)
=> 2

推荐答案

您可以在Symbol上创建一个简单的补丁,如下所示:

class Symbol
  def with(*args, &block)
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
  end
end

这不仅能让你做到:

a = [1,3,5,7,9]
a.map(&:+.with(2))
# => [3, 5, 7, 9, 11] 

还有很多其他很酷的东西,比如传递多个参数:

arr = ["abc", "babc", "great", "fruit"]
arr.map(&:center.with(20, '*'))
# => ["********abc*********", "********babc********", "*******great********", "*******fruit********"]
arr.map(&:[].with(1, 3))
# => ["bc", "abc", "rea", "rui"]
arr.map(&:[].with(/a(.*)/))
# => ["abc", "abc", "at", nil] 
arr.map(&:[].with(/a(.*)/, 1))
# => ["bc", "bc", "t", nil] 

甚至可以使用inject,它将两个参数传递给块:

%w(abecd ab cd).inject(&:gsub.with('cde'))
# => "cdeeecde" 

或者一些超级酷的东西,比如通过[速记]模块to速记模块:

[['0', '1'], ['2', '3']].map(&:map.with(&:to_i))
# => [[0, 1], [2, 3]]
[%w(a b), %w(c d)].map(&:inject.with(&:+))
# => ["ab", "cd"] 
[(1..5), (6..10)].map(&:map.with(&:*.with(2)))
# => [[2, 4, 6, 8, 10], [12, 14, 16, 18, 20]] 

Here is a conversation I had with @ArupRakshit explaining it further:
Can you supply arguments to the map(&:method) syntax in Ruby?


正如@amcaplan在comment below中所建议的,如果将with方法重命名为call,可以创建一个更短的语法.在本例中,ruby为这个特殊方法提供了一个内置的快捷方式.

所以你可以这样使用上面的内容:

class Symbol
  def call(*args, &block)
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
  end
end

a = [1,3,5,7,9]
a.map(&:+.(2))
# => [3, 5, 7, 9, 11] 

[(1..5), (6..10)].map(&:map.(&:*.(2)))
# => [[2, 4, 6, 8, 10], [12, 14, 16, 18, 20]] 

Ruby相关问答推荐

如何通过语法将Ruby Sorbet签名突出显示为不强调的 comments ?

当我在 Ruby 中围绕最后一个字符拆分时,如何拆分字符串?

RSpec 是否有 python 类似功能来做 TDD?

在 Ruby 中,rescue语句可以嵌套在哪些 struct 中

数组到哈希:字数

当没有传入块时,是否有更好的方法来防止屈服?

如何增加 ruby​​ 应用程序的堆栈大小.递归应用程序获取:堆栈级别太深(SystemStackError)

如何在不将换行符粘贴到字符串中的情况下使用puts添加额外的换行符?

需要Ruby

如何使用 yardoc 列出未记录的模块/类/常量/方法?

group_by 在 rails by 2 或更多属性

array.include?多个值

RSpec allow/expec vs expect/and_return

使用哈希参数进行 DRY Ruby 初始化

HAML 中 Javascript 中的 Ruby 方法

if语句末尾带有then有什么区别?

`File` 对象访问模式的区别(即 w+, r+)

如何使用器重新安装 gem

如何在遍历数组时使用 Array#delete?

何时在 Ruby 中使用 Struct 而不是 Hash?