Frage

Eine Antwort auf eine Frage, die ich gestern hier gestellt war das folgende Stück 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

ich each_cons, aber was ist die seltsame &:begin Schreibweise? Rette mich vor Syntax Hölle!

Danke!

War es hilfreich?

Lösung

Wenn Sie das Präfix das letzte Argument eines Anrufs mit & Sie machen deutlich, dass Sie einen Block senden und nicht ein normalen Argument. Ok, in method(&:something), :something ist ein Symbol, keine proc , so Rubin automatisch ruft die Methode to_proc einen echten Block zu erhalten. Und Rails Jungs (und jetzt auch Vanille Rubin) geschickt definiert als:

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

Das ist, warum Sie tun können:

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

[Bearbeiten] Hinweis: Wenn Sie feststellen, dass diese Konstruktion ist kein Syntatic Zucker, aber allgemeine Infrastruktur, dass Ruby bietet, nichts hält von Ihnen, Ihre eigenen to_proc für andere Klassen implementieren. Nie fühlte begrenzt, weil &:method keine Argumente erlaubt?

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

>> ["1", "F", "FF"].map(&[:to_i, 16])
=> [1, 15, 255]

Andere Tipps

my_method(&some_value) Mittel my_method aufzurufen, some_value in dem speziellen Argument Schlitz vorbei, das proc-Slot, in der Regel reserviert für das Bestehen do-Notation Blöcke.

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

Jedes Objekt, das ein Proc ist oder die auf to_proc reagiert erlaubt ist in dem proc-Slot übergeben werden. Wenn Sie in einem Objekt übergeben, das kein Proc ist, aber reagiert auf to_proc, dann to_proc auf dem Objekt aufrufen für Sie Ruby und das Ergebnis in die Methode übergeben.

Die Implementierung von Symbol#to_proc ist ein proc zurückzukehren, die, wenn ein Argument übergeben, das Argument sendet die Nachricht, dass das Symbol selbst ist. Zum Beispiel :hello.to_proc.call(my_obj) werden bis zu tun my_obj.send :hello beenden.

So my_array.each(&:hello) geht :hello zu each im proc-Slot (wobei ein Block normalerweise übergeben würde, wenn Sie das tun-Notation verwendet, um einen Block zu machen). :hello.to_proc.call(my_array[0]) endet als my_array[0].send :hello, und das gleiche für alle nachfolgenden Indizes von my_array.

es gleich:

ranges.sort_by{|r| r.begin}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top