Ruby/Избранное с RubyNews: различия между версиями

Содержимое удалено Содержимое добавлено
Строка 203:
== Подпрограммы: функции, методы и другие... ==
 
Многие из студентов уже встречались с такими словами и даже пытались самостоятельно понять, что они значат. Но вопрос все равно возникает, и хотелось бы его разобрать по кускам, чтобы он больше не возникал. Начнем с того, что подпрограммы, функции и методы - это все одно и тоже. Отличия лишь в незначительных деталях. Все это кусок программы, которые программист решил объявить всего лишь один раз, а потом вызывать столько сколько душе угодно. Например, программисту заказали программу подсчета суммы факториалов (помните <code>1*2*:*N</code>) двух чисел. Вот как он написал бы программу, если бы у него не было возможности составлять подпрограммы:
<codesource lang=ruby>n1, n2 = 4, 5
p1, p2 = 1, 1
n1.times{ |i| p1 *= i + 1 }
n2.times{ |i| p2 *= i + 1 }
puts "#{n1}! + #{n2}! = #{p1 + p2}"</codesource>
Он тут же смекнул, что писать кусок программы подсчета факториала числа он написал дважды (чисел, то две штуки) и решил написать подпрограмму, которая этот факториал числа вычислит. Вот как будет выглядеть более продвинутая программа:
<codesource lang=ruby>def fact( int )
pr = 1
int.times{ |i| pr *= i + 1 }
pr
end
n1, n2 = 4, 5
puts "#{n1}! + #{n2}! = #{fact(n1) + fact(n2)}"</codesource>
А если нужно было бы складывать три числа? Выигрыш в простоте очевиден. А теперь давайте разберемся, что же такое мы написал смекалистый программист. Разберем сначала верхний кусок. Он называется ОПРЕДЕЛЕНИЕМ ПОДПРОГРАММЫ или ОПРЕДЕЛЕНИЕМ МЕТОДА (от англ. define methods). Верхняя строчка состоит из ключевого слова <code>def</code>, названия метода (в нашем случае <code>fact</code>) и списка аргументов, то есть входных данных (в нашем случае <code>int</code>). Если в списке аргументов указано всего одно имя переменной, то и передавать в метод (при вызове) надо тоже один аргумент (обратите внимание на вызов метода <code>fact</code>, <code>fact(n1)</code>. Его не обязательно вызывать с переменной в качестве аргумента. Достаточно указать какое либо число, например <code>fact(4)</code> ). Помимо того, взгляните на <code>end</code> в конце тела метода. ЛЮБОЙ МЕТОД должен заканчиваться <code>end</code>. Типичный шаблон для создания метода выглядит примерно так:
<codesource lang=ruby>def имя_метода( имя_первого_аргумента, имя_второго_аргумента, и т.д.)
кусок_программы_который_мы_хотим_поместить_в_подпрограмму
end</codesource>
Вызывать наш метод надо примерно так:
<codesource lang=ruby>имя_метода( значение_первого_аргумента, значение_второго_аргумента, и т.д.)</codesource>
Теперь обратите внимание на то, что переменная pr в теле метода (на которую мы заменили переменные p1 и p2) расположена в последней строчке подпрограммы (т.е. непосредственно перед end). Вроде как она там прохлаждается и совсем не нужна, но это не так. Таким образом, мы говорим, что переменная pr является РЕЗУЛЬТАТОМ РАБОТЫ ПОДПРОГРАММЫ. И как раз результат перемножения хранится в этой переменной, т.е. данная переменная содержит факториал числа int (т.е. числа, которое передано в качестве первого аргумента). Отсюда и получается, что наша подпрограмма ВОЗВРАЩАЕТ факториал числа. Теперь ПРАВИЛО: программный КОД, который ПОВТОРЯЕТСЯ больше двух раз, ДОЛЖЕН быть ВЫНЕСЕН В ПОДПРОГРАММУ. А сейчас немного о различиях между подпрограммой, функцией и методом. Дело в том, что ПОДПРОГРАММА - это ОБЩЕЕ НАЗВАНИЕ методов, функций и процедур, т.е. объединяющее понятие. Если программист говорит подпрограмма, то он может иметь в виду как метод, так и процедуру. Теперь про различия между методами, функциями и процедурами. Процедуры - это устаревшая конструкция, от которой многие языки программирования отказались. На данный момент она используется только в языке Pascal. СЕЙЧАС в основном ОСТАЛИСЬ только МЕТОДЫ, и ФУНКЦИИ. От процедур их отличает то, что ОНИ ВОЗВРАЩАЮТ РЕЗУЛЬТАТ. Иными словами, ПРОЦЕДУРА - это метод или функция, которые НЕ ВОЗВРАЩАЮТ РЕЗУЛЬТАТА. Теперь пор различия между методами и функциями. МЕТОДЫ есть только в ОБЪЕКТНО-ОРИЕНТИРОВАННЫХ ЯЗЫКАХ. ФУНКЦИИ во всех ОСТАЛЬНЫХ. Отсюда можно заключить, что мы написали с вами подпрограмму, которая является методом, т.к. Ruby - ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ ЯЗЫК. PS. Большие буквы -- это влияние самоучителя Драгункина... :-)
 
== Тенденции в ООП ==