Kann mir bitte jemand was sagen
send("#{Model.find...}")
ist und tut?
Kann mir bitte jemand was sagen
send("#{Model.find...}")
ist und tut?
Antworten:
send
sendet eine Nachricht an eine Objektinstanz und ihre Vorfahren in Klassenhierarchie, bis eine Methode reagiert (da ihr Name mit dem ersten Argument übereinstimmt).
In der Praxis sind diese Zeilen gleichwertig:
1.send '+', 2
1.+(2)
1 + 2
Beachten Sie, dass send
Sichtbarkeitsprüfungen umgangen werden, sodass Sie auch private Methoden aufrufen können (nützlich für Komponententests).
Wenn vor dem Senden wirklich keine Variable vorhanden ist, bedeutet dies, dass das globale Objekt verwendet wird:
send :to_s # "main"
send :class # Object
send ist eine Ruby-Methode (ohne Rails), mit der eine andere Methode mit Namen aufgerufen werden kann.
Aus der Dokumentation
class Klass
def hello(*args)
"Hello " + args.join(' ')
end
end
k = Klass.new
k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
Eine der nützlichsten Funktionen, die ich mit der .send-Methode denke, ist, dass sie die Methode dynamisch aufrufen kann. Dies kann Ihnen viel Tipparbeit ersparen. Eine der beliebtesten Anwendungen der .send-Methode ist die dynamische Zuweisung von Attributen. Beispielsweise:
class Car
attr_accessor :make, :model, :year
end
Um Attribute regelmäßig zuzuweisen, müsste man
c = Car.new
c.make="Honda"
c.model="CRV"
c.year="2014"
Oder mit der .send-Methode:
c.send("make=", "Honda")
c.send("model=", "CRV")
c.send("year=","2014")
Es kann jedoch alles durch Folgendes ersetzt werden:
Angenommen, Ihre Rails-App muss Ihrer Fahrzeugklasse Attribute aus Benutzereingaben zuweisen, können Sie dies tun
c = Car.new()
params.each do |key, value|
c.send("#{key}=", value)
end
Ein weiteres Beispiel, ähnlich dem von Antonio Jha unter https://stackoverflow.com/a/26193804/1897857
ist, wenn Sie Attribute für ein Objekt lesen müssen.
Wenn Sie beispielsweise über ein Array von Zeichenfolgen verfügen und versuchen, diese zu durchlaufen und sie für Ihr Objekt aufzurufen, funktioniert dies nicht.
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.a
end
# => NoMethodError: undefined method `a'
Sie können jedoch send
die Zeichenfolgen für das Objekt festlegen:
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.send(a)
end
# => Vandalay Project
# => A very important project
define_method
: apidock.com/ruby/Module/define_method .
send
ist eine andere Möglichkeit, eine Methode aufzurufen.
Dies lässt sich am besten anhand eines Beispiels veranschaulichen:
o = Object.new
o.send(:to_s) # => "#<Object:0x00005614d7a24fa3>"
# is equivalent to:
o.to_s # => "#<Object:0x00005614d7a24fa3>"
Senden Sie Leben in der Object-Klasse .
Der Vorteil dieses Ansatzes besteht darin, dass Sie die Methode, die Sie aufrufen möchten, als Parameter übergeben können. Hier ist ein einfaches Beispiel:
def dynamically_call_a_method(name)
o = Object.new
o.send name
end
dynamically_call_a_method(:to_s) # => "#<Object:0x00005614d7a24fa3>"
Sie können die Methode übergeben, die Sie aufrufen möchten. In diesem Fall sind wir vorbeigekommen :to_s
. Dies kann sehr praktisch sein, wenn Sie eine Ruby-Metaprogrammierung durchführen, da wir so verschiedene Methoden entsprechend unseren unterschiedlichen Anforderungen aufrufen können.
Ein weiterer Anwendungsfall für Ansichten:
<%= link_to
send("first_part_of_path_#{some_dynamic_parameters}_end_path",
attr1, attr2), ....
%>
Ermöglichen . Sie schreiben eine skalierbare Ansicht, die mit allen Arten von Objekten arbeitet mit:
render 'your_view_path', object: "my_object"