Методы, доступные данному типу, всегда известны компилятору. Таким образом, попытка вызвать несуществующий метод приведет к ошибке времени компиляции, а не к исключению времени выполнения.
К счастью, у Crystal есть инструмент, который помогает нам визуализировать типы по мере их вывода. Следующий раздел проведет вас через это.
Экспериментируем с командой Crystal Play
Команда crystal play
запускает Crystal Playground для воспроизведения языка с помощью вашего браузера. Он покажет результат каждой строки вместе с выведенным типом:
1. Откройте терминал и введите "crystal play”; он покажет следующее сообщение:
Listening on http://127.0.0.1:8080
2. Оставьте терминал открытым, а затем запустите этот URL-адрес в своем любимом веб-браузере. Это даст вам удобный интерфейс для начала программирования в Crystal:
Рисунок 2.1 - The Crystal playground
1. С левой стороны у вас есть текстовый редактор с некоторым кодом Crystal. Вы можете попробовать изменить код на какой-нибудь код из этой книги, чтобы получить интерактивный способ обучения.
2. С правой стороны есть поле с некоторыми аннотациями к вашему коду. Например, он покажет вам результат каждой строки рядом с типом значения, видимым компилятором.
Если вы сомневаетесь в каких-то примерах или нестандартных решениях, попробуйте их с помощью Crystal playground.
Переходя к более практичному представлению о том, как используются типы, нам нужно узнать о хранении данных в коллекциях и манипулировании ими. Они всегда печатаются на машинке для обеспечения безопасности.
Организация вашего кода по методам
При написании приложений код необходимо структурировать таким образом, чтобы его можно было повторно использовать, документировать и тестировать. Основой этой структуры является создание методов. В следующей главе мы перейдем к объектно-ориентированному программированию с классами и модулями. Метод имеет имя, может получать параметры и всегда возвращает значение (nil
также является значением). Посмотрите это, например:
def leap_year?(year) divides_by_4 = (year % 4 == 0)
divides_by_100 = (year % 100 == 0)
divides_by_400 = (year % 400 == 0)
divides_by_4 && !(divides_by_100 && !divides_by_400)
end
puts leap_year? 1900 # => false
puts leap_year? 2000 # => true
puts leap_year? 2020 # => true
Определения методов начинаются с ключевого слова def
, за которым следует имя метода. В данном случае имя метода — jump_year?
, включая символ вопроса. Затем, если у метода есть параметры, они будут заключены в круглые скобки. Метод всегда возвращает результат своей последней строки, в данном примере — условный результат. Типы не нужно указывать явно, они будут определяться в зависимости от использования.
При вызове метода круглые скобки вокруг аргументов не являются обязательными и часто опускаются для удобства чтения. В этом примере puts
— это метод, аналогичный jump_year?
и его аргумент является результатом последнего. ставит leap_year? 1900
— это то же самое, что и puts(leap_year?(1900))
.
Имена методов подобны переменным и соответствуют соглашению об использовании только строчных букв, цифр и подчеркиваний. Кроме того, имена методов могут заканчиваться символами вопроса или восклицательного знака. Они не имеют специального значения в языке, но обычно применяются в соответствии со следующим соглашением:
• Метод, заканчивающийся на ?
может указывать на то, что метод проверяет какое-то условие и возвращает значение Bool
. Он также часто используется для методов, которые возвращают объединение некоторого типа и Nil
для обозначения состояния сбоя.
• Метод, заканчивающийся на !
указывает на то, что выполняемая им операция в некотором роде «опасна», и программисту следует быть осторожным при ее использовании. Иногда может существовать «более безопасный» вариант метода с тем же именем, но без !
символ.
Методы могут основываться на других методах. Посмотрите это, например:
def day_count(year)
leap_year?(year) ? 366 : 365
end
Методы могут быть перегружены по количеству аргументов. Посмотрите это, например:
def day_count(year, month)
case month
when 1, 3, 5, 7, 8, 10, 12
31
when 2
leap_year?(year) ? 29 : 28
else
30
end
end
В этом случае метод будет выбран в зависимости от того, как вы расставите аргументы для его вызова:
puts day_count(2020) # => 366
puts day_count(2021) # => 365
puts day_count(2020, 2) # => 29