1

ここで昨日提起した質問に対する答えは、次の 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表記は何ですか?構文地獄から救ってください!

ありがとう!

4

3 に答える 3

7

呼び出しの最後の引数にプレフィックスを付けると、通常の&引数ではなくブロックを送信していることを明確にしています。inはprocではなくシンボルであるため、Ruby はこのメソッドを自動的に呼び出して実際のブロックを取得します。そして、Rails の連中 (そして今ではバニラ Ruby も) は、巧妙に次のように定義しました。method(&:something):somethingto_proc

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]
于 2010-12-22T19:08:06.713 に答える
2

my_method(&some_value)を呼び出すことを意味し、特別な引数スロットである proc-slot を渡します。これは通常、do 記法ブロックを渡すために予約されていますmy_methodsome_value

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 を返すことです。たとえば、:hello.to_proc.call(my_obj)を実行することになりmy_obj.send :helloます。

そのため、proc-slot にmy_array.each(&:hello)渡されます (do 表記を使用してブロックを作成した場合、ブロックが通常渡される場所)。となり、 の後続のすべてのインデックスについても同じです。:helloeach:hello.to_proc.call(my_array[0])my_array[0].send :hellomy_array

于 2010-12-22T19:11:09.513 に答える
1

それは等しい:

ranges.sort_by{|r| r.begin}
于 2010-12-22T18:55:37.450 に答える