In &method(:to_s)
wird .to_s
aus dem aktuellen Kontext genommen (oberstes Objekt main
). Diese Version ist bereits an den Empfänger gebunden und akzeptiert keine weiteren Argumente. Aber ein Argument wird von .map
(jedes Element des Arrays) übergeben, das ist, was es tut.
Werfen Sie einen Blick auf diesen Schritt-für-Schritt-Rekonstruktion dessen, was
to_s # => "main"
method(:to_s) # => #<Method: main.to_s>
method(:to_s).to_proC# => #<Proc:0x007ff73a27e1e0 (lambda)>
method(:to_s).to_proc.call(12) # =>
# ~> -:6:in `to_s': wrong number of arguments (given 1, expected 0) (ArgumentError)
# ~> from -:6:in `<main>'
Vergleichen Sie nun passiert, was passieren würde, wenn es .map(&:to_s)
:to_s.to_proc.call(12) # => "12"
war, kam ich auf die &method
in eine Codebasis
Es kann sein nützlich in Situationen wie diesem: Wenden Sie ein Stück Logik auf jedes Element an, aber diese Logik kommt aus dem aktuellen Kontext, komplett außerhalb der Elemente. Werfen Sie einen Blick auf diese erfundene Beispiel:
class Tweet
attr_accessor :text
def initialize(text)
@text = text
end
def shortened_links
find_links.map(&method(:shorten_link))
# same as
# find_links.map {|link| shorten_link(link) }
end
private
def find_links
# detect links in text
end
def shorten_link(url)
# use bit.ly or whatever
end
end
Hier links
eine Sammlung von Strings ist. Sie können sich sicherlich nicht verkürzen.
Ich folge nicht ganz, warum 'method (: to_s) .to_proc.call (12)' einen Fehler auslöst, aber ': to_s.to_proc.call (12)' läuft ohne Fehler. – Jwan622
@ Jwan622: weil es so funktioniert. '[12, 13] .map (&: to_s)' ist äquivalent zu '[12, 13] .map {| elem | elem.to_s} '. Dagegen ist '[12, 13] .map (& method (: to_s))' äquivalent zu '[12, 13] .map {| elem | to_s (elem)} '. Beachten Sie den Unterschied? –
Und das ist nur die Regel der Sprache? Ist '12. & method (: to_s)' wirklich nur ein Wrapper über 'method (: to_s) .to_proc.call (12)'? Was löst "& Methode" auf jeden Fall? – Jwan622