web-dev-qa-db-fra.com

Que fait send () en Ruby?

Quelqu'un peut-il s'il vous plaît me dire quoi

send("#{Model.find...}")

est et fait?

73
Christian Bankester

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
82
giraff

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"

http://corelib.rubyonrails.org/classes/Object.html#M001077

84
Nikita Rybak

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
45
Antonio Jha

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
8
Mike Vallano

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"
0

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.

0
BKSpurgeon