【发布时间】:2010-12-29 23:34:21
【问题描述】:
在 Ruby 中,我知道如果我这样做:
some_objects.each(&:foo)
和这个一样
some_objects.each { |obj| obj.foo }
也就是说,&:foo 创建块 { |obj| obj.foo },将其转换为 Proc,并将其传递给每个块。为什么这行得通?它只是 Ruby 的一个特例,还是有什么理由可以这样工作?
【问题讨论】:
标签: ruby
在 Ruby 中,我知道如果我这样做:
some_objects.each(&:foo)
和这个一样
some_objects.each { |obj| obj.foo }
也就是说,&:foo 创建块 { |obj| obj.foo },将其转换为 Proc,并将其传递给每个块。为什么这行得通?它只是 Ruby 的一个特例,还是有什么理由可以这样工作?
【问题讨论】:
标签: ruby
可以这么说,你的问题是错误的。这里发生的不是“& 和冒号”,而是“& 和对象”。在这种情况下,冒号用于符号。所以,有& 和:foo。
& 在对象上调用to_proc,并将其作为块传递给方法。在Ruby中,to_proc是在Symbol上实现的,所以这两个调用是等价的:
something {|i| i.foo }
something(&:foo)
所以,总结一下:& 在对象上调用to_proc 并将其作为块传递给方法,Ruby 在Symbol 上实现to_proc。
【讨论】:
Proc 对象,以便它像文字块一样被传递。只有当对象已经不是Proc对象时,它才会调用to_proc。
& 符号和符号的组合并没有什么特别之处。这是(ab)使用正则表达式的示例:
class Regexp
def to_proc
->(str) { self =~ str ; $1 }
end
end
%w(station nation information).map &/(.*)ion/
=> ["stat", "nat", "informat"]
或整数。
class Integer
def to_proc
->(arr) { arr[self] }
end
end
arr = [[*3..7],[*14..27],[*?a..?z]]
arr.map &4
=> [7, 18, "e"]
你有arr.map &4,谁还需要arr.map(&:fifth)?
【讨论】:
[*3..7] 语法。我没想到你会那样摔跤!