Rubyrush: Методы и функции в языке Ruby

Ruby для новичков [Rubyrush]

В этом уроке мы проходим тему Методы и функции в Ruby. На уроке разберем понятия методов и функций, как правильно их использовать, ну и немного о том как и для чего нужно писать собственные методы.

Что такое метод?

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

  1. возьму свой телефон,
  2. разблокирую его,
  3. зайду в список контактов,
  4. найду номер друга,
  5. нажму кнопку вызова.

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

В программировании на Ruby все точно так же — все по полочкам разложено и описано в документации. С самого первого для изучения этого языка программирования я использую в программах методы:

  • puts
  • gets

Для описания объекта типа метод проще всего сказать, что Метод — это определенное действие объекта. Методы свойственны только объектно-ориентированному программированию. Метод это один из многих способов структурирования кода, служит чтобы действие объекта вынести отдельно и использовать несколько раз.

Лично я предпочитаю более запутанное описание. Метод — это абстрактный объект содержащий в себе набор инструкций для выполнения конкретной задачи. Если сказать еще проще — метод — это упорядоченная последовательность действий, фрагмент сценария или программы, объединённый = сохранённый в виде условного названия.

Методы создаются при помощи ключевого слова def. Всякий раз, когда ты пишешь слово def в программе, она понимает что сейчас ты будешь писать имя метода (определишь метод) и задашь ему последовательность инструкций (тело метода). А когда закончишь описывать тело метода то программа ждёт что ты поставишь слово end.

Rubyrush: Методы и функции в языке Ruby
Простой пример метода и его вывода в программе.

Аргументы метода

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

Если метод должен принимать параметры — то после имени метода добавляются круглые скобки, в которые ты передаёшь аргументы = параметры метода.

Rubyrush: Методы и функции в языке Ruby
Пример простого метода, который принимает два аргумента. Вызывая метод мы передаем значения этим аргументам и выводим на экран строку с текстом.

В чем фишка использования методов

Методы позволяют удобно использовать отдельно взятые и часто повторяющиеся фрагменты программы, для выполнения задач в программировании.

Ты же помнишь про принцип DRY — Don’t repeat yourself? Вот и молодец! Методы помогают не повторяться по 100 раз и с ними гораздо удобней программировать. Ровно так же как в обычной жизни общаться и делиться историями о том что ты планируешь сделать сегодня или в течении месяца и так далее.

Методы можно использовать совершенно по разному. Он может как вернуть значение, выполнить последовательность действий и ничего не вернуть. Использую этот инструмент с умом.

Три базовых правила создания методов в Ruby

  1. Присваивай методам осмысленные уникальные имена.
  2. Имя должно быть глаголом, так как метод чаще всего содержит в себе действия.
  3. В параметрах метода перечисляй минимально необходимые данные. Не должно быть ничего лишнего.
  4. Создавай методы только если это упрощает и облегчает работу с твоей программой.

Еще хочется добавить по поводу последнего пункта — не создавай лишних методов. Дели программу на логические блоки. Мне это все напоминает семантичную разметку на html. В ней мы делим страницу на смысловые блоки, по средствам тега section. А еще при стилизации блоков часто используется методология BEM, по условиям которой страница разделяется на блоки, элементы и модификаторы. Тут тоже похожая аналогия с методами. Тебе как бы нужно вынести часть программы в логический блок, который с высокой вероятностью будет использоваться более одного раза. тем самым ты сможешь избежать повторов в коде программы и сократить длину.

Пишем пример программы с использованием метода

Задача

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

Проще на примере:

  • У нас есть крокодилы.
  • У нас есть 10 крокодилов,
  • У нас есть 3 крокодила.

К числу подставляем словоформу (склонение), в зависимости от того какой число у нас принято при запуске программы.

В программе используем ARGV и создаём свой собственный метод. Погнали!

Для начала создадим сам метод, а в качестве аргументов будем передавать четыре значения. Первое значение — это число, которое нужно ввести при запуске программы в консоли. Остальные три аргумента — это просто слова, которые выводятся в тексте строки по итогу работы программы. Эти параметры можно переопределять в зависимости от желаемого смысла в тексте.

def sklonenie(number, крокодил, крокодила, крокодилов)

end

Так как на словоформу влияет не общее число, а последняя цифра с числе, то мы упростим задачу в теле метода будем работать с остатком от деления на 10. Ну и теперь пишем условия:

если остаток от деления единица — подставляем первую словоформу.

если остаток от деления больше или равен двум И меньше или равер четырём — подставляем вторую словоформу.

ну и если остаток меньше четырёх или равен нулю — подставляем третью словоформу.

def sklonenie(number, крокодил, крокодила, крокодилов)
  ostatok = number % 10

  if (ostatok == 1) 
    return крокодил
  end

  if (ostatok >= 2 && ostatok <= 4) 
    return крокодила
  end

  if (ostatok > 4 || ostatok == 0) 
    return крокодилов
  end
end

На этом программирование нашего метода завершено и мы можем написать произвольную программу.

В уроке Rubyrush предлагают игру по мотивам детектива Агаты Кристи «Десять негритят». Программа будет принимать входящее значение и выводить на экран составной текст.

Как видно в примере кода ниже, в переменную skolko мы сохраняем введённое пользователем значение и для надёжности явно приводим эти данные к типу «число».

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

skolko = ARGV[0].to_i

puts "#{skolko} " +
sklonenie(skolko, "негритёнок", "негритёнка", "негритят") +
" " +
sklonenie(skolko, "пошёл", "пошли", "пошли") +
" купаться в море!"
Rubyrush: Методы и функции в языке Ruby
Итоговая программа и результат её работы в консоли.

Важные нюансы, которые нужно понять

Область видимости переменных

Область видимости переменной, которая объявлена в методе видна только внутри самого метода. Основная программа, которую мы писали ниже, эту переменную не видит! Это важно понимать.

Rubyrush: Методы и функции в языке Ruby
Переменные, которые передаются в метод в качестве аргументов НЕ видны за пределами метода!

Важно проверять данные

В нашем методе мы совсем забыли про проверку полученных данных. Мы полностью им доверяем и поэтому рискуем. В случае ввода НЕ числа а строки мы этого можем и не заметить, так как данные автоматически при явном приведении к числу превратятся в число 0.

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

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

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

def sklonenie(number, крокодил, крокодила, крокодилов)
  if (number == nil || !number.is_a?(Numeric))
    number = 0
  end

  ostatok = number % 10

  if (ostatok == 1) 
    return крокодил
  end

  if (ostatok >= 2 && ostatok <= 4) 
    return крокодила
  end

  if (ostatok > 4 || ostatok == 0) 
    return крокодилов
  end
end

skolko = ARGV[0].to_i

puts "#{skolko} " +
sklonenie(skolko, "негритёнок", "негритёнка", "негритят") +
" " +
sklonenie(skolko, "пошёл", "пошли", "пошли") +
" купаться в море!"

Юрий Ронин