Когда я сегодня сидел в классе, изучая .send (), я все больше расстраивался. Я вижу ценность абстракции. Довольно круто, насколько чистыми могут выглядеть ваши методы в каждом классе.

Отправить, однако, похоже, что это на другом уровне. Говоря банально, «это похоже на начало». Мне кажется, что он функционирует как абстракция уже абстрагированной вещи. Вот пример с веб-сайта Flatiron School:

Нижний - это абстракция - здесь нет конкретных имен переменных. Все универсально. И это действительно проясняет, что происходит в этой строке кода. Так почему же верхний лучше?

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

class Dog
  attr_accessor :name, :owner, :breed
end

Всякий раз, когда создается новый объект Dog, при инициализации необходимо выполнить следующие действия:

snoopy = Dog.new
snoopy.name = "Snoopy"
snoopy.owner = "Charlie Brown"
snoopy.breed = "beagle"

вместо этого: имя,: владелец и: порода, до бесконечности - может быть гораздо больше атрибутов, таких как,: возраст,: место рождения,: лучший_френд,: любимая_ еда и: любимая_активность.
Эти атрибуты и их значения (например,
name: «toto»,
owner: «dorothy»,
Birth_place: «kansas»)
могут быть определены как ключевые пары -значение (присвоенные переменной «атрибуты»), то есть, когда создается новый экземпляр Dog, нам нужны только две строки кода, чтобы назначить каждый из этих атрибутов нашей новой собаке:

toto = Dog.new()
attributes.each do |key, value|
  toto.send("#{key}=", value)
end

Это круто. Выглядит красиво. Но меня не продают. Атрибуты еще нужно где-то определить, поэтому эти строки кода с числом x (скажем, 5–8) все равно нужно где-то записать. Так почему бы не в методе инициализации?

Ok. Прорвать. Это то, что позволяет нам изменять количество параметров / атрибутов, которые мы можем назначить каждой новой собаке, без изменения метода инициализации. Если бы мы хотели добавить новый атрибут, например: date_adopted или: birthday, это была бы просто еще одна пара ключ-значение в каждом цикле.

Причина, по которой send здесь полезна, заключается в том, что каждый атрибут будет иметь свой собственный метод установки, такой как name =, поэтому, заменив «ключ» на «имя», мы можем передавать множество различных атрибутов, не называя их по отдельности.

И самое полезное объяснение, которое я видел, благодаря Google и Джеффу Парсонсу: «Метод send позволяет вам отправить сообщение (вызвать метод), когда вы не узнаете имя этого метода до тех пор, пока время выполнения ".

ЭТО ОТВЕТ, КОТОРЫЙ Я ИЩЁН.

Итак, я думаю, что преимущество этого, помимо того, что оно выглядит как хорошая идея с философской точки зрения, состоит в том, что он позволяет вам изменить свое мнение без необходимости возвращаться и изменять свой код.

Вы можете написать .send в своем коде, и когда вы запустите программу, вы можете передать любые методы, которые хотите .send, без необходимости изменять структуру вашего существующего написанного кода, но при этом получать из него разные части информации в зависимости от какие методы вы говорите. send использовать.

Не знаю, как скоро я буду использовать метод .send, но приятно понимать, почему кто-то может захотеть его использовать. И понять, что он говорит мне в чужом коде - что они с самого начала ожидают, что информация, которую они захотят, со временем изменится.

Изучая способы изменения кода во время выполнения, я также обнаружил, что в Ruby есть такая вещь, как методы псевдонима. Это позволяет вам сделать небольшое дополнение к существующему методу, который вы определили, не переопределяя свой метод (минимизируя риск поломки) или не создавая новый метод с новым именем (вам придется вернуться и изменить любой вызовы этого метода в вашем коде).

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

def display_board(level)   
     system("clear")  
     show_hangman(level)  #displays the hangman
     puts self.board.chars.join(" ")  #displays the letters & spaces
end

Если бы я хотел повторно использовать этот код, чтобы сделать более сложную версию игры, где пользователь получает еще меньше догадок (не то чтобы игра была недостаточно сложной, потому что из-за некоторого отсутствия подсказок пользователя наша игра была слишком сложной) , Я мог бы повышать уровень каждый раз, когда я его показываю, чтобы, например, одновременно отображались 2 руки вместо одной.

def display_board_difficulty_2(level)   
     system("clear") 
     level = level + 1 
     show_hangman(level)  #displays the hangman
     puts self.board.chars.join(" ")  #displays the letters & spaces
end

Чтобы использовать то же имя метода, «display board», я мог бы написать alias_method, который будет принимать 2 символа: метод, который я хочу реализовать, и имя, которое я хочу, чтобы он вызывал.

alias_method :display_board_difficulty_2, :display_board

Люди в Интернете много говорили об использовании этого для имени - так что если вы получаете полное имя, когда вызываете имя, и вам нужно только имя, вы все равно можете позвонить по имени и получить конкретные данные, которые вы хотите, без необходимости работать с ним на другом этапе процесса.

Также приятно, что Ruby предоставляет такую ​​гибкость для внесения изменений в ваш код после того, как вы что-то написали или объявили. Почему вы бы сделали это вместо того, чтобы просто изменить код в исходном методе, заключается в том, что это также может быть легко полезно при работе с другим разработчиком, чтобы внесенные вами изменения были понятны и был простой способ вернуться к исходному функционалу.

Выводы:

Ruby позволяет разными способами вносить дополнения или изменения в работу вашей программы в последнюю минуту.

#send: позволяет изменять параметры во время выполнения.

alias_method: позволяет вносить изменения в метод, сохраняя при этом исходный метод.