Quelqu'un peut-il s'il vous plaît me dire quoi
send("#{Model.find...}")
est et fait?
send
envoie un message à une instance d'objet et à ses ancêtres dans la hiérarchie de classes jusqu'à ce qu'une méthode réagisse (car son nom correspond au premier argument).
En pratique, ces lignes sont équivalentes:
1.send '+', 2
1.+(2)
1 + 2
Notez que send
ignore les contrôles de visibilité, de sorte que vous pouvez également appeler des méthodes privées (utile pour les tests unitaires).
S'il n'y a vraiment pas de variable avant l'envoi, cela signifie que l'objet global est utilisé:
send :to_s # "main"
send :class # Object
send est une méthode Ruby (sans Rails) permettant d'appeler une autre méthode par son nom.
De la documentation
class Klass
def hello(*args)
"Hello " + args.join(' ')
end
end
k = Klass.new
k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
Une des fonctionnalités les plus utiles que je pense avec la méthode .send est qu’elle peut appeler dynamiquement une méthode. Cela peut vous faire économiser beaucoup de frappe. L’une des utilisations les plus courantes de la méthode .send consiste à attribuer des attributs de manière dynamique. Par exemple:
class Car
attr_accessor :make, :model, :year
end
Pour attribuer des attributs régulièrement, il faut
c = Car.new
c.make="Honda"
c.model="CRV"
c.year="2014"
Ou en utilisant la méthode .send:
c.send("make=", "Honda")
c.send("model=", "CRV")
c.send("year=","2014")
Mais tout cela peut être remplacé par ce qui suit:
En supposant que votre application Rails ait besoin d'attribuer des attributs à votre classe de voiture à partir d'une entrée utilisateur, vous pouvez
c = Car.new()
params.each do |key, value|
c.send("#{key}=", value)
end
Un autre exemple, similaire à Antonio Jha/ https://stackoverflow.com/a/26193804/1897857
est si vous avez besoin de lire les attributs sur un objet.
Par exemple, si vous avez un tableau de chaînes, si vous essayez de les parcourir et de les appeler sur votre objet, cela ne fonctionnera pas.
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.a
end
# => NoMethodError: undefined method `a'
Cependant, vous pouvez send
les chaînes dans l'objet:
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.send(a)
end
# => Vandalay Project
# => A very important project
Un autre cas d'utilisation pour les vues:
<%= link_to
send("first_part_of_path_{some_dynamic_parameters}_end_path",
attr1, attr2), ....
%>
Autoriser d’écrire une vue évolutive qui travaille avec tout type d’objets avec:
render 'your_view_path', object: "my_object"
send
est un autre moyen d'appeler une méthode. Ceci est mieux illustré par l'exemple:
o = Object.new
o.send(:to_s) # => "#<Object:0x00005614d7a24fa3>"
# is equivalent to:
o.to_s # => "#<Object:0x00005614d7a24fa3>"
L'avantage de cette approche est que vous pouvez transmettre la méthode que vous souhaitez appeler en tant que paramètre. Voici un exemple simple:
def dynamically_call_a_method(name)
o = Object.new
o.send name
end
dynamically_call_a_method(:to_s) # => "#<Object:0x00005614d7a24fa3>"
Vous pouvez transmettre la méthode que vous souhaitez appeler. Dans ce cas, nous avons passé :to_s
.