题
我昨天在这里提出的问题的答案是以下Ruby代码:
def overlap?(r1,r2)
r1.include?(r2.begin) || r2.include?(r1.begin)
end
def any_overlap?(ranges)
ranges.sort_by(&:begin).each_cons(2).any? do |r1,r2|
overlap?(r1, r2)
end
end
我明白了 each_cons
, ,但是有什么奇怪的 &:begin
符号?救我免于语法地狱!
谢谢!
解决方案
当您将呼叫的最后一个参数前缀 &
您明确表示您正在发送一个块而不是 普通的 争论。好,在 method(&:something)
, :something
是一个符号,而不是 Proc, ,因此Ruby会自动调用该方法 to_proc
要获得真正的块。和Rails的家伙(现在也是Vanilla Ruby)巧妙地将其定义为:
class Symbol
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
end
这就是为什么您可以这样做:
>> [1, 2, 3].map(&:to_s) # instead of [1, 2, 3].map { |n| n.to_s }
=> ["1", "2", "3"]
编辑]注意:当您意识到这种结构不是语法糖,而是Ruby提供的通用基础设施时,没有什么可以阻止您实施自己的 to_proc
对于其他课程。从来没有受到限制,因为 &:method
不允许争论?
class Array
def to_proc
proc { |obj, *args| obj.send(*(self + args)) }
end
end
>> ["1", "F", "FF"].map(&[:to_i, 16])
=> [1, 15, 255]
其他提示
my_method(&some_value)
意味着调用 my_method
, ,通过 some_value
在特殊参数插槽中,通常保留用于传递do-notation块的Proc-Slot。
my_block = lambda { puts "hello" }
(1..3).each(&my_block)
任何对象 Proc
或回应 to_proc
被允许在Proc-Slot中通过。如果您通过一个不是一个的对象 Proc
但是什么回应 to_proc
, ,然后Ruby会打电话 to_proc
在对象上,并将结果传递到方法中。
实施 Symbol#to_proc
是返回一个proc,该proc在通过一个参数时将该参数发送为符号本身的消息。例如, :hello.to_proc.call(my_obj)
最终会做 my_obj.send :hello
.
所以 my_array.each(&:hello)
通过 :hello
至 each
在Proc-Slot中(如果您使用do-notation制作块,则通常会通过一个块)。 :hello.to_proc.call(my_array[0])
最终成为 my_array[0].send :hello
, ,以及随后的所有索引 my_array
.
它等于:
ranges.sort_by{|r| r.begin}