Использование функций в программах на языке Crystal
Не смотря на то, что язык программирования Crystal является строго объектно-ориентированным, процедурное программирование на алгоритмическом языке Crystal возможно и даже иногда необходимо. В данной статье показано как это делать на алгоритмическом языке программирования Crystal.
В соответствие с методикой итерационного и инкрементного подхода изучения языков программирования на первом цикле обучения методам процедурного программирования начинать надо после изучения простых типов данных языка Crystal и освоения его операторов и управляющих конструкций переходить к освоению создания и использования функций и процедур.
Процедурное программирование на алгоритмическом языке, в том числе и Crystal, базируется на таких понятиях как процедура и функция. В алгоритмическом языке программирования Crystal используются собственные методы(функции) и процедуры, а также библиотечные методы(функции).В любом случае это обособленные фрагменты кода, позволяющие группировать код так, чтобы иметь возможность вызывать их(фрагментов) многократно по присвоенным ранее им именам в любой части программы.
Для освоения работы с методами и процедурами необходимо знать способы:
- объявления методов и процедур;
- объявления формальных и передачи фактических аргументов;
- возврата значений.
В соответствие с методологией процедурного(структурного) программирования на алгоритмическом языке любую программу можно создать как совокупность взаимодействующих процедур и функций. Поэтому процедурное программирование на алгоритмическом языке Crystal возможно, не смотря на его прочный объектно-ориентированных фундамент, и даже иногда необходимо.
Методы и функции
Собственные методы объявляются в программе, используя синтаксис ключевых слов «def» и «end». Формальные аргументы указываются в скобках после имени, тип возвращаемого значения указывается после круглых скобок.
При вызове метода надо записать его имя и предоставить один или несколько фактических аргументов, которые служат для передачи и последующей обработки методом информации.
Например, метод вычисления факториала имеет вид.
- def fact(n : Int) : Int
- if n < 0
- puts «n должен быть положительным»
- exit
- end
- n == 0 ? 1 : n * fact(n — 1)
- end
Метод имеет имя, в данном случае fact, один или несколько формальных аргументов, которые перечисляются в скобках после имени метода с указанием типа, а также тип возвращаемого значения, показывается после скобок.
Формальные аргументы воспринимаются как переменные, существующие в области действия метода.
Метод возвращает значение своего последнего выражения, которое присваивается его имени. Однако код может иметь оператор явной передачи «returns n», но это не обязательно. Если необходимо вернуть несколько значений, их можно упаковать в кортеж или массив.
Хорошо спроектированные методы должны содержать не только задаваемые вычисления, но и проверку возможных исключительных ситуаций. Например, в данном методе кроме вычисления факториала по рекуррентной формуле(функции) предусмотрены проверки на положительность аргумента и блокировка передачи строкового аргумента уже на стадии компиляции с четким сообщением о несовпадении типов аргумента и параметра.
Примечание. Метод в языке Crystal может вызвать сам себя, как в методе вычисления факториала целого числа «fact». Такие методы называются рекурсивными.
Другим примером метода или функции в языке Crystal рассмотрим метод вычисления чисел Фибоначчи, представленный на рисунке.
# Способы создания и применения функций
- def fib(n)
- return n if n <= 1
- fib(n — 1) + fib(n — 2)
- end
- sum = 0
- i=0
- while i<3
- sum += fib(i)
- i+=1
- end
- puts «Суммирование чисел Фибоначчи», sum
Внимание. В следующем фрагменте только аргумент «y» объявляется, как принадлежащий типу Int, но не «x»:
def add(x, y : Int)
x + y
end
Вызов функции
add 3, 4 # 7
add 2.14, 7 # 9.14
Во втором вызове метода add параметр «x» не соответствует типу Int. Если «x» и «y» оба должны соответствовать типу Int, то надо определить метод так: add (x: Int, y: Int).
Таким образом, процедурное программирование на алгоритмическом языке Crystal базируется на его собственных методах(функциях), взаимодействие которых будет рассмотрено далее. Это позволяет полагать, что процедурное программирование на алгоритмическом языке Crystal возможно, не смотря на его прочный объектно-ориентированных фундамент.
Процедуры языка Crystal
Процедуры алгоритмического языка программирования Crystal позволяют поместить логику, включая методы, внутрь схожих с переменными структур, которые можно пропускать сквозь программу и вызывать напрямую или через ключевое слово «yield» (выдача).
Подобно методам(def), процедуры (Procs) могут принимать аргументы и возвращать значения.
В алгоритмическом языке программирования Crystal применяются следующие виды процедур. Захваченный блок кода (&block) с помощью фигурных скобок { } фактически является объектом, называемым процедурой («Proc»), или лямбда-функцией, или анонимной функцией.
Процедуры можно создавать с помощью нескольких различных подходов:
1)Двухсимвольная запись «->» позволяет создать литерал процедуры. Например, процедура сложения двух чисел add имеет вид:
fn = ->(n : Int32, m : Int32)
{ n + m }
Имя процедуры находится слева от знака «=». Затем оператор «->» указывает список параметров с обязательным указанием типов. Дальше следует фрагмент кода между фигурных скобок {}. Во второй строке компилятор делает вывод относительно числового типа, возвращаемого процедурой.
Обращение к процедуре «Proc» осуществляется как к функциональному объекту с методом «call».
fn.call(42, 108) # => 150
2) Можно создать процедуру из существующего метода «add», используя аналогичную запись:
Например, имеем метод.
def add(n, m)
n + m
end
На его основе создаем процедуру.
fn = ->add(Int32, Int32)
Обращение к процедуре в программе.
fn.call(42, 108) # => 150
3) Тот факт, что Proc является классом в стандартной библиотеке Кристалла, позволяет вам также использовать метод new:
fn = Proc(Int32, Int32, Int32).new { |n, m| n + m }
fn.call(42, 108) # => 150
Процедурное программирование на алгоритмическом языке Crystal можно реализовать с помощью процедур. Однако здесь без объектно-ориентированных приемов не обойтись.
Библиотечные методы
Как и любой язык программирования Crystal имеет несколько библиотек, в которых определены множество методов. Среди которых: ввод со стандартного ввода(клавиатуры) gets, чтение строки стандартного ввода read_line, вывод на стандартный вывод(экран) puts, печать любого объекта ‘p’ и т.д.
Некоторые примеры прменения библиотечных функций. Ввод с клавиатуры целых чисел с печатью введенного массива..
- while n = gets
- arr << n.to_i8
- p arr # => для примера: [2, 3, 3, 5]
- end
Методы «pp» и «inspect» полезны для отладки программ;
Методы printf и sprintf принимает строку в формате, свойственном языку программирования C; последний вариант (sprintf) возвращает тип String.
Видимость переменных в методах
В алгоритмическом языке программирования Crystal применяются следующие правила видимости переменных в программах. Переменные, определяемые локально в методе, не будут видны вне метода, а переменные, которые определены вне метода, не будут видимы внутри этого метода тоже.
Процедурное программирование на языке Crystal
Для примера использования методологии процедурного программирования на алгоритмическом языке Crystal рассмотрим решение следующей задачи.
Необходимо разработать программу Stat статистического анализа случайного набора чисел. Для решения такой задачи необходимо создать ряд методов, которые генерируют массив случайных чисел, суммируют элементы массива и возвращают математическое ожидание и дисперсию(среднеквадратическое отклонение) элементов массива, содержащего случайные числа с плавающей десятичной запятой. Размер массива передается в качестве аргумента в выборку.
Известно, что решение любой задачи на ЭВМ предполагает разработку алгоритма ее решения. В данном случае алгоритм простой, поэтому на его разработке останавливаться не будем. Вычисления оценок математического ожидания и дисперсии осуществляется по известным формулам математической статистики.
Метод генерации массива случайных чисел.
В методе предусмотрено применение пустого массива mas=[] вещественного типа of Float64 в качестве формального параметра. Для создания случайного числа, соответствующего типу float, используется библиотечная функция rand. Формирование массива осуществляется путем дополнения элементов операцией “<<”.
- def gen(n,mas=[] of Float64)
- i=0
- while i<n
- mas<< rand
- i+=1
- end end
Метод суммирования элементов массива случайных чисел.
В этом методе также предусмотрено применение пустого массива mas=[] вещественного типа of Float64 в качестве формального параметра. Далее применяется известный прием суммирования элементов массива в операторе цикла. В методе предусмотрено явная передача вычисленного значения оператором return sum.
- def sum_el_mas(n,mas=[] of Float64)
- i=0
- sum = 0
- while i<n
- sum += mas[i]
- i+=1
- end
- return sum
- end
Метод вычисления математического ожидания элементов массива
И в этом методе также предусмотрено применение пустого массива mas=[] вещественного типа of Float64 в качестве формального параметра. Далее определяется сумма элементов массива путем вызова ранее созданного метода sum_el_mas(n,mas) с передачей ему фактических параметров(аргументов) – n — размер массива, mas – ранее сгенерированный массив.
- def mat_ogid(n,mas=[] of Float64)
- i=0
- sum = sum_el_mas(n,mas)
- mat_og = sum/n
- return mat_og
- end
Для отладки метода вычисления математического ожидания создается специальная отладочная программа, в которой предусмотрены контрольные выводы значений промежуточных вычислений. Код программы и результаты ее выполнения показаны на следующем рисунке.

Аналогично проводится отладка и других методов.
Метод вычисления дисперсии элементов массива
Аналогично для передачи элементов массива в метод предусмотрено применение пустого массива mas=[] вещественного типа of Float64 в качестве формального параметра. В методе вычисляется математическое ожидание по ранее созданному методу, которое используется для выччисления центрированных значений случайных величин. Вычисление дисперсии по известной формуле.
- def sko_el_mas(n,mas=[] of Float64)
- i=0
- sum = 0
- mo = mat_ogid(n,mas) # Матожидание элементов массива
- while i<n
- sum += (mas[i]-mo)*(mas[i]-mo) # Сумма центрированных значений
- i+=1
- end
- disp = sum/(n-1) # Дисперсия элементов массива
- return disp
- end
После того как подготовлены все необходимые методы можно приступать к их объединению в единую программу решения поставленной задачи.
Программа вычисления статистических характеристик элементов массива
В данной программе реализованы те шаги решения поставленной задачи, которые излагались при ее постановке. Повторяться не будем.
В преведенном ниже коде:
- -задана размерность массива и объявлен пустой массив типа Float64;
- -выполнена генерация массива вещественных чисел;
- -вычислены математическое ожидание и дисперсия элементов массива.
Результаты промежуточных вычислений выводятся на экран для котроля работы программы.
- n=5
- mas=[] of Float64 # создаем массив Array(Float64)
- gen(n,mas) # генерируем массив Array(Float64) из n элементов
- puts «Масив случайных вещественных чисел»
- puts mas
- y= sum_el_mas(n,mas) # суммируем элементы массива Array(Float64)
- puts «Сумма элементов масива»,y
- mo = mat_ogid(n,mas)
- puts «Матожидание элементов массива», mo
- disp = sko_el_mas(n,mas)
- puts «Дисперсия элементов массива», disp #,sko
Полный текст программы вычисления статистических характеристик представлен на следующем рисунке.

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

Поступая аналогичным образом, можно составить и использовать любую программу на языке Crystal.
Таким образом, эта статья заканчивает первый цикл изучения языка программирования Crystal согласно итерационному и инкрементному подходу. Следующий цикл также начинается с изучения типов данных, но уже более сложных, так называемых, структурированных типов данных.
Заключение
Процедурное программирование на алгоритмическом языке Crystal возможно, не смотря на его прочный объектно-ориентированных фундамент, и даже иногда необходимо.
С этой целью лучше использовать собственные методы(def).
Статьи по теме
- Что такое программирование?
- Как выбирать язык программирования высокого уровня для изучения
- Что выбирать язык или платформу программирования?
- Как быстро изучить язык программирования
- Как изучать простые типы данных языка программирования?
- Как стать специалистом по большим данным?