Quelqu'un peut-il me dire quoi
send("#{Model.find...}")
est et fait?
Quelqu'un peut-il me dire quoi
send("#{Model.find...}")
est et fait?
Réponses:
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
contourne 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'invoquer 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"
L'une des fonctionnalités les plus utiles que je pense de la méthode .send est qu'elle peut appeler dynamiquement une méthode. Cela peut vous épargner beaucoup de saisie. 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 faudrait
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 peut être remplacé par ce qui suit:
En supposant que votre application Rails doit attribuer des attributs à votre classe de voiture à partir de l'entrée utilisateur, vous pouvez faire
c = Car.new()
params.each do |key, value|
c.send("#{key}=", value)
end
Un autre exemple, similaire à https://stackoverflow.com/a/26193804/1897857 d' Antonio Jha
est si vous avez besoin de lire des 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 de l'objet:
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
est une autre façon 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>"
Envoyez des vies dans la classe Object .
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 sommes passés :to_s
. Cela peut être très pratique lors de la métaprogrammation ruby, car cela nous permet d'appeler différentes méthodes en fonction de nos différentes exigences.
Un autre cas d'utilisation des vues:
<%= link_to
send("first_part_of_path_#{some_dynamic_parameters}_end_path",
attr1, attr2), ....
%>
Autoriser . vous d'écrire des vues évolutives qui fonctionnent avec tous les types d'objets avec:
render 'your_view_path', object: "my_object"