我昨天在这里提出的问题的答案是以下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) 通过 :helloeach 在Proc-Slot中(如果您使用do-notation制作块,则通常会通过一个块)。 :hello.to_proc.call(my_array[0]) 最终成为 my_array[0].send :hello, ,以及随后的所有索引 my_array.

它等于:

ranges.sort_by{|r| r.begin}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top