Ruby 过程语法

发布于 2024-10-08 23:44:25 字数 345 浏览 2 评论 0原文

我昨天在这里提出的问题的答案是以下 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 表示法是什么?把我从语法地狱中救出来!

谢谢!

An answer to a question I posed yesterday on here was the following piece of Ruby code:

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

I get each_cons, but what's the strange &:begin notation? Save me from syntax hell!

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

宫墨修音 2024-10-15 23:44:25

当您在调用的最后一个参数前加上 & 前缀时,您就明确表示您正在发送一个块,而不是一个正常参数。好的,在 method(&:something) 中,:something 是一个符号,而不是 proc,因此 Ruby 会自动调用该方法 to_proc 获取真正的块。 Rails 人员(现在还有普通 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]

When you prefix the last argument of a call with & you are making clear that you are sending a block and not a normal argument. Ok, in method(&:something), :something is a symbol, not a proc, so Ruby automatically calls the method to_proc to get a real block. And Rails guys (and now also vanilla Ruby) cleverly defined it as:

class Symbol
  def to_proc
    proc { |obj, *args| obj.send(self, *args) }
  end
end

That's why you can do:

>> [1, 2, 3].map(&:to_s) # instead of [1, 2, 3].map { |n| n.to_s }
=> ["1", "2", "3"]

[edit] Note: when you realize that this construction is no syntatic sugar but generic infrastructure that Ruby provides, nothing stops you from implementing your own to_proc for other classes. Never felt limited because &:method allowed no arguments?

class Array
  def to_proc
    proc { |obj, *args| obj.send(*(self + args)) }
  end
end

>> ["1", "F", "FF"].map(&[:to_i, 16])
=> [1, 15, 255]
暮光沉寂 2024-10-15 23:44:25

my_method(&some_value) 表示调用 my_method,在特殊参数槽(proc-slot)中传递 some_value,通常保留用于传递 do - 符号块。

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 传递给 proc-slot 中的 each (通常会传递一个块,如果你使用了 do 符号来创建一个块)。 :hello.to_proc.call(my_array[0]) 最终成为 my_array[0].send :hello,对于 my_array 的所有后续索引也是如此

my_method(&some_value) means to invoke my_method, passing some_value in the special argument slot, the proc-slot, usually reserved for passing do-notation blocks.

my_block = lambda { puts "hello" }
(1..3).each(&my_block)

Any object which is a Proc or which responds to to_proc is permitted to be passed in the proc-slot. If you pass in an object which is not a Proc but which responds to to_proc, then Ruby will call to_proc on the object for you and pass the result into the method.

The implementation of Symbol#to_proc is to return a proc which, when passed an argument, sends that argument the message that is the symbol itself. For example, :hello.to_proc.call(my_obj) will end up doing my_obj.send :hello.

So my_array.each(&:hello) passes :hello to each in the proc-slot (where a block would normally passed, if you used the do-notation to make a block). :hello.to_proc.call(my_array[0]) ends up being my_array[0].send :hello, and the same for all subsequent indexes of my_array.

锦上情书 2024-10-15 23:44:25

它等于:

ranges.sort_by{|r| r.begin}

it equals:

ranges.sort_by{|r| r.begin}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文