Что делает send () в Ruby? - PullRequest
80 голосов
/ 26 июля 2010

Может кто-нибудь, пожалуйста, скажите мне, что

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

есть и есть?

Ответы [ 6 ]

89 голосов
/ 26 июля 2010

send отправляет сообщение экземпляру объекта и его предкам в иерархии классов, пока какой-либо метод не отреагирует (поскольку его имя соответствует первому аргументу).

На практике эти строки эквивалентны:

1.send '+', 2
1.+(2)
1 + 2

Обратите внимание, что send обходит проверки видимости, так что вы также можете вызывать закрытые методы (полезно для модульного тестирования).


Если перед отправкой действительно нет переменной, тоозначает, что используется глобальный объект:

send :to_s    # "main"
send :class   # Object
89 голосов
/ 26 июля 2010

send - метод ruby ​​(без рельсов), позволяющий вызывать другой метод по имени.

Из документации

   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

49 голосов
/ 04 октября 2014

Одна из наиболее полезных функций, которые я считаю в методе .send, заключается в том, что он может динамически вызывать метод.Это может сэкономить вам много печатать.Одним из наиболее популярных способов использования метода .send является динамическое назначение атрибутов.Например:

class Car
  attr_accessor :make, :model, :year
end  

Чтобы регулярно присваивать атрибуты, потребуется

c = Car.new
c.make="Honda"
c.model="CRV"
c.year="2014"

Или использовать метод .send:

c.send("make=", "Honda")
c.send("model=", "CRV")
c.send("year=","2014")

Но все это можно заменитьс помощью следующего:

Предполагая, что вашему приложению Rails необходимо назначить атрибуты вашему классу автомобилей из пользовательского ввода, вы можете сделать

c = Car.new()
params.each do |key, value|
  c.send("#{key}=", value)
end
8 голосов
/ 04 февраля 2017

Другой пример, похожий на https://stackoverflow.com/a/26193804/1897857

Антонио Джа, - это если вам нужно прочитать атрибуты объекта.

Например, если у вас есть массив строк, если вы попытаетесьитерировать их и вызывать их на вашем объекте, это не сработает.

atts = ['name', 'description']
@project = Project.first
atts.each do |a|
  puts @project.a
end
# => NoMethodError: undefined method `a'

Однако вы можете send строки для объекта:

atts = ['name', 'description']
@project = Project.first
atts.each do |a|
  puts @project.send(a)
end
# => Vandalay Project
# => A very important project
1 голос
/ 30 марта 2019

send - это еще один способ вызова метода.Это лучше всего иллюстрируется примером:

o = Object.new
o.send(:to_s) # => "#<Object:0x00005614d7a24fa3>"
# is equivalent to:
o.to_s # => "#<Object:0x00005614d7a24fa3>"

Преимущество этого подхода заключается в том, что вы можете передать метод, который вы хотите вызвать, в качестве параметра.Вот простой пример:

def dynamically_call_a_method(name)
    o = Object.new
    o.send name 
end
dynamically_call_a_method(:to_s) # => "#<Object:0x00005614d7a24fa3>"

Вы можете передать метод, который хотите вызвать.В этом случае мы перешли в :to_s.

0 голосов
/ 18 декабря 2017

Другой вариант использования для просмотров:

    <%= link_to 
    send("first_part_of_path_{some_dynamic_parameters}_end_path", 
    attr1, attr2), ....
    %>

Разрешить.Вы пишете масштабируемое представление, которое работает со всеми видами объектов:

    render 'your_view_path', object: "my_object"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...