Насколько я понимаю метод отправки, этот
some_object.some_method("im an argument")
совпадает с этим
some_object.send :some_method, "im an argument"
Итак, какова точка, использующая метод "Отправить"?
Насколько я понимаю метод отправки, этот
some_object.some_method("im an argument")
совпадает с этим
some_object.send :some_method, "im an argument"
Итак, какова точка, использующая метод "Отправить"?
Это может пригодиться, если вы не знаете заранее имя метода, например, когда вы выполняете метапрограммирование, вы можете иметь имя метода в переменной и передать его в send
метод.
Он также может использоваться для вызова частных методов, хотя это конкретное использование не считается хорошей практикой для большинства разработчиков Ruby.
class Test
private
def my_private_method
puts "Yay"
end
end
t = Test.new
t.my_private_method # Error
t.send :my_private_method #Ok
Вы можете использовать public_send
, но только для вызова общедоступных методов.
В дополнение к случаям использования Intrepidd это удобно, когда вы хотите направить разные методы на один и тот же приемник и/или аргументы. Если у вас есть some_object
и вы хотите делать с ним разные вещи в зависимости от того, что foo
, то без send
вам нужно написать как:
case foo
when blah_blah then some_object.do_this(*some_arguments)
when whatever then some_object.do_that(*some_arguments)
...
end
но если у вас есть send
, вы можете написать
next_method =
case foo
when blah_blah then :do_this
when whatever then :do_that
....
end
some_object.send(next_method, *some_arguments)
или
some_object.send(
case foo
when blah_blah then :do_this
when whatever then :do_that
....
end,
*some_arguments
)
или используя хеш, даже это:
NextMethod = {blah_blah: :do_this, whatever: :do_that, ...}
some_object.send(NextMethod[:foo], *some_arguments)
В дополнение ко всем остальным ответам, хороший пример использования будет для итерации с помощью методов, содержащих инкрементирующую цифру.
class Something
def attribute_0
"foo"
end
def attribute_1
"bar"
end
def attribute_2
"baz"
end
end
thing = Something.new
3.times do |x|
puts thing.send("attribute_#{x}")
end
#=> foo
# bar
# baz
Это может показаться тривиальным, но иногда помогло мне сохранить код Rails и шаблоны DRY. Это очень конкретный случай, но я считаю его действительным.
Суммируя кратко то, что уже было сказано коллегами: send
метод - синтаксический сахар для метапрограммирования. Пример ниже демонстрирует случай, когда естественные вызовы методов, вероятно, невозможны:
class Validator
def name
'Mozart'
end
def location
'Salzburg'
end
end
v = Validator.new
'%name% was born in %location%'.gsub (/%(?<mthd>\w+)%/) do
# v.send :"#{Regexp.last_match[:mthd]}"
v.send Regexp.last_match[:mthd].to_sym
end
=> "Mozart was born in Salzburg"
Мне нравится эта конструкция
Object.get_const("Foo").send(:bar)