Crystal (язык программирования)
Последнее изменение этой страницы: 23:14, 8 июня 2016.
Содержание
Введение
Crystal – (произносится [ ˈkrɪs.təl ] )это язык программирования, который похож на Ruby, но компилируется в машинный код и является более эффективным за счет запрета динамической типизации, которая является одним из аспектов Ruby.
Статус
- Проект находится в альфа версии.
- Компилятор написан на Crystal.
Особенности
- Имеет схожий или почти похожий на Ruby синтаксис
- Статические типы проверяются, но без необходимости указывать тип переменных или аргументов метода.
- Возможно вызвать C код, написав обвязку к нему на Crystal
- Есть оценка времени компиляции и генерации кода, дабы избежать шаблонность кода.
- Эффективная компиляция в машинный код.
Обзор
в примерах кода, комментарий #=>
используется, чтобы показать значение выражения. Например:
a = 1 + 2 a #=> 3
Комментарий ::
используется для отображения типа переменной.
s = "hello" # s :: String
Давайте начнем с двух примеров, чтобы ознакомиться с языком.
Hello World!
Классическая "hello world" программа выглядит так на Crystal:
puts "Hello world!"
Как вы можете видеть, главная программа – это просто программа сама по себе. Не нужно определять "main" функцию или что-то подобное.
HTTP-сервер
Чуть более интересным примером является HTTP-сервер:
require "http/server" server = HTTP::Server.new(8080) do |request| HTTP::Response.ok "text/plain", "Hello world! The time is #{Time.now}" end puts "Listening on http://0.0.0.0:8080" server.listen
Подключаем код из других файлов:
require "http/server"
Определяем локальные переменные без необходимости определять их тип:
server = HTTP::Server.new ...
Вызываем методы (или отправляем сообщения) на объекты.
HTTP::Server.new(8000) ... ... Time.now ... puts "Listening on http://0.0.0.0:8080" ... server.listen
Вы можете использовать блоки кода или просто блоки, которые являются очень удобным способом повторного использования кода, и получить некоторые преимущества "функционального" мира:
HTTP::Server.new(8080) do |request| ... end
Вы можете легко создавать строки с включенным контентом (это называется интерполяция строк). Язык также имеет другой синтаксис для создания массивов, хэшей, рядов, кортежей и многого другого:
"Hello world! The time is #{Time.now}"
Установка
После того как вы установили компилятор, используя методы ниже, убедитесь, что вы прочитали статью про использование компилятора, дабы эффективно использовать его.
- На Debian и Ubuntu
- На RedHat и CentOS
- На Arch Linux
- На Mac OSX, используя Homebrew
- Из tar.gz
- Из исходников
Из tar.gz
Если по какой-либо причине вы не можете или не хотите использовать один из предыдущих методов установки, вы можете загрузить Crystal в виде автономного .tar.gz файла со всем необходимым для начала работы.
Последние релизы можно найти на GitHub: https://github.com/manastech/crystal/releases
Скачайте файл для вашей платформы и разархивируйте. Внутри будет доступно bin/crystal
.
Чтобы проще использовать это, вы можете создать символьную ссылку:
ln -s [full path to bin/crystal] /usr/local/bin/crystal
Затем вы можете вызвать компилятор, просто набрав crystal
.
Из исходников
Если вы хотите стать контрибутором, вы, наверное, хотите установить Crystal из исходников. Но Crystal написан на Crystal! Поэтому для начала вам необходимо использовать один из предыдущих методов для использования компилятора.
Вам также будет необходим LLVM 3.5 или 3.6. Если Вы используете Mac и Homebrew, то LLVM будет автоматически сконфигурирован для Вас, просто добавьте флаг --with-llvm
при установке Crystal.
Потом склонируйте репозиторий:
git clone https://github.com/manastech/crystal.git
и все готово.
Чтобы собрать свою личную версию компилятора, запустите make
. Новый компилятор будет размещен в .build/crystal
.
Будьте уверены, что установили все нужные библиотеки. Также советую Вам прочитать contributing guide.
В репозитории Вы также можете найти скрипт враппера в bin/crystal
. Этот скрипт запустит глобально установленный компилятор или тот, который вы только что собрали (если имеется).
На Arch Linux
Arch Linux включает в себя компилятор Crystal в хранилище Сообщества.
Установка
sudo pacman -S crystal
На Debian и Ubuntu
В Debian вы можете использовать официальный Crystal репозиторий.
Установка репозитория
Во-первых, вы должны добавить репозиторий в вашу APT конфигурацию. Для легкой установки просто запустите в командной строке:
curl http://dist.crystal-lang.org/apt/setup.sh | sudo bash
Это добавит ключ подписи и конфигурацию репозитория. Если вы предпочитаете делать это вручную, выполните:
apt-key adv --keyserver keys.gnupg.net --recv-keys 09617FD37CC06B54 echo "deb http://dist.crystal-lang.org/apt crystal main" > /etc/apt/sources.list.d/crystal.list
Установка
После того, как репозиторий настроен, Вы готовы к установке Crystal:
sudo apt-get install crystal
Обновление
Вы можете обновить Crystal с помощью:
sudo apt-get update sudo apt-get install crystal
На Mac OSX, используя Homebrew
Для легкой установки Crystal на Mac, Вы можете использовать Homebrew.
brew update brew install crystal-lang
Если вы планируете стать контрибутором, вам будет полезно установить LLVM. Так что замените последнюю строчку с:
brew install crystal-lang --with-llvm
На RedHat и CentOS
В RedHat вы можете использовать официальный Crystal репозиторий.
Установка из репозитория
Во-первых, вы должны добавить репозиторий в вашу YUM конфигурацию. Для легкой установки просто запустите в командной строке:
curl http://dist.crystal-lang.org/rpm/setup.sh | sudo bash
Это добавит ключ подписи и конфигурацию репозитория. Если вы предпочитаете делать это вручную, выполните:
rpm --import http://dist.crystal-lang.org/rpm/RPM-GPG-KEY cat > /etc/yum.repos.d/crystal.repo <<END [crystal] name = Crystal baseurl = http://dist.crystal-lang.org/rpm/ END
Установка
После того, как репозиторий настроен, Вы готовы к установке Crystal:
sudo yum install crystal
Обновление
Вы можете обновить Crystal с помощью:
sudo yum update crystal
Используя компилятор
После того как Вы установили компилятор, будет доступна команда crystal
.
В следующих секциях знак доллара ($
) представляет коммандную строку.
Компиляция и запуск сразу
Для компиляции и запуска программы в одну команду, Вы можете вызвать crystal
с одним именем файла:
$ crystal some_program.cr
Crystal файлы оканчиваются с .cr
расширением.
Также можно использовать команду run
:
$ crystal run some_program.cr
Создание исполняемого файла
Для создания исполняемого файла используйте команду build
:
$ crystal build some_program.cr
В результате будет создан исполняемый файл some_program
.
$ ./some_program
Заметка: По умолчания сгенерированные файлы недостаточно оптимизированы. Для запуска оптимизации, используйте флаг --release
:
$ crystal build some_program.cr --release
Убедитесь, что вы постоянно используете --release
для production-ready исполняемых файлов, и когда вы запускаете бенчмарки.
Создание проекта или библиотеки
Используйте команду init
для создания Crystal проекта со стандартной структурой директорий.
$ crystal init lib MyCoolLib create MyCoolLib/.gitignore create MyCoolLib/LICENSE create MyCoolLib/README.md create MyCoolLib/.travis.yml create MyCoolLib/shard.yml create MyCoolLib/src/MyCoolLib.cr create MyCoolLib/src/MyCoolLib/version.cr create MyCoolLib/spec/spec_helper.cr create MyCoolLib/spec/MyCoolLib_spec.cr Initialized empty Git repository in ~/MyCoolLib/.git/
Другие команды и опции
Чтобы увидеть весь список команд, запустите crystal
без аргументов.
$ crystal Usage: crystal [command] [switches] [program file] [--] [arguments] Command: init generate new crystal project build compile program file deps install project dependencies docs generate documentation eval eval code from args or standard input run (default) compile and run program file spec compile and run specs (in spec directory) tool run a tool --help, -h show this help --version, -v show version
Чтобы увидеть опции определенной команды, используйте флаг --help
после команды:
$ crystal build --help Usage: crystal build [options] [programfile] [--] [arguments] Options: --cross-compile flags cross-compile -d, --debug Add symbolic debug info -D FLAG, --define FLAG Define a compile-time flag --emit [asm|llvm-bc|llvm-ir|obj] Comma separated list of types of output for the compiler to emit -h, --help Show this message --ll Dump ll to .crystal directory --link-flags FLAGS Additional flags to pass to the linker --mcpu CPU Target specific cpu type --no-color Disable colored output --no-codegen Don't do code generation -o Output filename --prelude Use given file as prelude --release Compile in release mode -s, --stats Enable statistics output --single-module Generate a single LLVM module --threads Maximum number of threads to use --target TRIPLE Target triple --verbose Display executed commands
Синтаксис и семантика
Исходный код программы должен иметь кодировку UTF-8.
Программа
Программа представляет собой глобальный объект, в котором вы можете определить типы, методы и локальные переменные.
# Defines a method in the program def add(x, y) x + y end # Invokes the add method in the program add(1, 2) #=> 3
Значение метода является значение его последнего выражения, нет необходимости явного return
выражения. Тем не менее, явное return
возможно:
def even?(num) if num % 2 == 0 return true end return false end
При вызове метода без приемника, как add(1, 2)
, поиск кода будет осуществлен в программе, если не будет найден в текущем типе или одном из его предков.
def add(x, y) x + y end class Foo def bar # invokes the program's add method add(1, 2) # invokes Foo's baz method baz(1, 2) end def baz(x, y) x * y end end
Если вы хотите вызвать метод программы, даже если текущий тип определяет метод с тем же именем, вызовите его с префиксом ::
:
def baz(x, y) x + y end class Foo def bar baz(4, 2) #=> 2 ::baz(4, 2) #=> 6 end def baz(x, y) x - y end end
Переменные, объявленные в программе, не видимы внутри методов:
x = 1 def add(y) x + y # error: undefined local variable or method 'x' end add(2)
Круглые скобки в вызове методов являются необязательными:
add 1, 2 # same as add(1, 2)
Литералы
Доступны несколько литералов для создания многих основных типов в языке.
C-обвязки
Crystal позволяет использовать библиотеки на C, не написав ни единой строки на C.
Кроме того, он предоставляет некоторые удобства типа `out` и `to_unsafe`, так что написание обвязок наиболее безболезненно.
Еще: C bindings on Crystal docs
Макросы
Макрос – это метод, который получает AST узлы при компиляции, и предоставляет код, который вставляется в программу.
Соглашения
Следуйте этим соглашениям, чтобы Ваш код был более понятным для других разработчиков
- Используйте стандартный стиль кода и Ваш проект будет легко управляем и читаем для других.
- Пишите документацию.
Стиль кода
Этот стиль используется в стандартной библиотеке. Вы можете использовать его в своем проекте, чтобы сделать его знакомым другим разработчиков.
Именование
Имена типов обозначаются в CamelCase. Например:
class ParseError < Exception end module HTTP class RequestHandler end end alias NumericValue = Int32 | Int64 | Float32 | Float64 lib LibYAML end struct TagDirective end enum Time::DayOfWeek end
Имена методов обозначаются в Underscore-case. Например:
class Person def first_name end def date_of_birth end def homepage_url end end
Имена переменных обозначаются в Underscore-case. Например:
$global_greeting = "Hello world" class Greeting @@default_greeting = "Hello world" def initialize(@custom_greeting=nil) end def print_greeting greeting = @custom_greeting || @@default_greeting puts greeting end end
Константы обозначаются в SCREAMING-case. Например:
LUCKY_NUMBERS = [3, 7, 11] DOCUMENTATION_URL = "http://crystal-lang.org/docs"
Сокращения
В именах классах, сокращения обозначаются в верхнем регистре. Например: HTTP
, и LibXML
.
В именах методов, сокращения обозначаются в нижнем регистре. Например: #from_json
, #to_io
.
Библиотеки
Lib
имена имеют префикс Lib
. Например: LibC
, LibEvent2
.
Директории и имена файлов
В проекте:
-
/
содержит readme, любую конфигурацию проекта (например, CI или конфиги редактора), и любую другую проектную документацию (например, changelog или contributing guide). -
src/
содержит исходный код проекта. -
spec/
содержит спецификацию проекта, которая может быть запущена с помощью командыcrystal spec
. -
bin/
содержит любые исполняемые файлы.
Пути файлов соответствую пространству имен их контента. Файлы имени класса или пространства имен определяют через underscore-case.
Например, HTTP::WebSocket
определен в src/http/web_socket.cr
.
Пробелы
Используйте два пробела для отступа кода внутри пространства имен, методов, блоков или других вложенных контекстах. Например:
module Scorecard class Parser def parse(score_text) begin score_text.scan(SCORE_PATTERN) do |match| handle_match(match) end rescue err : ParseError # handle error ... end end end end
В классе, отдельные определения методов, констант и внутренних определений класса c одним пробелом. Например:
module Money CURRENCIES = { "EUR" => 1.0, "ARS" => 10.55, "USD" => 1.12, "JPY" => 134.15, } class Amount getter :currency, :value def initialize(@currency, @value) end end class CurrencyConversion def initialize(@amount, @target_currency) end def amount # implement conversion ... end end end
Документация
Комментарии документации Crystal используют Markdown.
- Документация должна быть расположена прямо над определениями классов, модулей и методов. Не ставьте пробелы между ними.
# A unicorn is a **legendary animal** (see the `Legendary` module) that has been # described since antiquity as a beast with a large, spiraling horn projecting # from its forehead. class Unicorn end # Bad: This is not attached to any class.class Legendary end
- Документация метода включается в его содержание и детали. Первое включает в себя только первую строку, последний включает в себя всю документацию. Короче говоря, предпочтительнее:
- Статус цели метода или функциональность в первой строчке
- Дополнение в виде деталей и использования после
Например:
# Returns the number of horns this unicorn has. # # ``` # Unicorn.new.horns #=> 1 # ``` def horns @horns end
- Пишите от третьего лица:
Возвращает количество рогов единорога
вместоВозвращение количества рогов единорога
. - Названия параметров должны быть выделены курсивом (заключены в одинарные звездочки
*
или подчеркивания_
):
# Creates a unicorn with the specified number of *horns*. def initialize(@horns = 1) raise "Not a unicorn" if @horns != 1 end
- Блоки кода, которые имеют Crystal код могут быть окружены тройными обратными кавычками или отступом в четыре пробела.
# ``` # unicorn = Unicorn.new # unicorn.speak # ```
или
# unicorn = Unicorn.new # unicorn.speak
- Текстовые блоки, например, чтобы показать вывод программы, должны быть окружены тройными обратными кавычками сопровождаемыми ключевым словом "text".
# ```text # "I'm a unicorn" # ```
- Чтобы автоматически связать с другими типами, заключите их в одиночные обратные кавычки.
# the `Legendary` module
- Для автоматического ссылки на методы, используйте хэш
#horns
или#index(char)
, и заключите его в одинарные обратные кавычки. - Чтобы автоматически связать с методами в других видах, используйте
OtherType#method(arg1, arg2)
или простоOtherType#method
, и заключите его в одинарные обратные кавычки.
Например:
# Check the number of horns with `#horns`. # See what a unicorn would say with `Unicorn#speak`.
- Чтобы показать результат выражения внутри блока кода, используйте
#=>
.
1 + 2 #=> 3 Unicorn.new.speak #=> "I'm a unicorn"
- Используйте
ditto
для использования тот же комментарий, как в предыдущем объявлении.
# ditto def number_of_horns horns end
- Используйте
:nodoc:
, чтобы скрыть публичное определение из сгенерированной документации. "Private" и "protected" методы всегда скрыты.
class Unicorn # :nodoc: class Helper end end
Полный пример
# A unicorn is a **legendary animal** (see the `Legendary` module) that has been # described since antiquity as a beast with a large, spiraling horn projecting # from its forhead. # # To create a unicorn: # # ``` # unicorn = Unicorn.new # unicorn.speak # ``` # # The above produces: # # ```text # "I'm a unicorn" # ``` # # Check the number of horns with `#horns`. class Unicorn include Legendary # Creates a unicorn with the specified number of *horns*. def initialize(@horns = 1) raise "Not a unicorn" if @horns != 1 end # Returns the number of horns this unicorn has # # ``` # Unicorn.new.horns #=> 1 # ``` def horns @horns end # ditto def number_of_horns horns end # Makes the unicorn speak to STDOUT def speak puts "I'm a unicorn" end # :nodoc: class Helper end end
Генерация документации
Чтобы создать документацию для проекта, вызовите crystal doc
. Это создаст doc
каталог, с doc/index.html
точкой входа. Все файлы внутри корневого каталога src
будут рассматриваться для генерации документации.
ISSN 2542-0356
Следуй за Полисом
Оставайся в курсе последних событий
Лицензия
Если не указано иное, содержание этой страницы доступно по лицензии Creative Commons «Attribution-NonCommercial-NoDerivatives» 4.0, а примеры кода – по лицензии Apache 2.0. Подробнее см. Условия использования.