Цей документ має на меті надати швидкий огляд мови програмування Raku. Новачкам у Raku цей документ надасть можливість почати вивчення та виркористання цієї мови.
Деякі розділи цього документа посилаються на інші (більш досконалі та точні) частини документації до Raku. Вам слід прочитати їх, якщо потребуєте більше інформації на окремі теми.
Всюди у цьому документі ви знайдете приклади до найбільш обговорюваних тем. Аби краще їх зрозуміти, будь ласка, знайдіть трохи часу аби відтворити їх.
Цей документ ліцензовано за міжнародною ліцензією Creative Commons Attribution Share-Alike 4.0 (Із зазначенням авторства — Розповсюдження на тих самих умовах). Аби побачити копію цієї лізензії, перейдіть за посиланням:
Якщо ви хочете долучитися до вдосконалення цього документа, перейдіть до:
Будь-які відгуки вдячно приймають на:
-
[email protected] - English
-
[email protected] - Українська
Якщо вам сподобалася ця робота, позначте зірочкою репозиторій за посиланням: Github.
-
Болгарський: https://raku.guide/bg
-
Китайський: https://raku.guide/zh
-
Голландський: https://raku.guide/nl
-
Французький: https://raku.guide/fr
-
Німецький: https://raku.guide/de
-
Індонезійський: https://raku.guide/id
-
Італійський https://raku.guide/it
-
Японський: https://raku.guide/ja
-
Португальський: https://raku.guide/pt
-
Іспаньский: https://raku.guide/es
-
Турецький: https://raku.guide/tr
-
Украінський: https://raku.guide/uk
Raku це високорівнева мова програмування загального призначення з поступовою типізацією. Raku є багатопарадигмальною мовою, яка підтримує процедурне, об’єктно-орієнтоване та функціональне програмування.
-
ІБНОСЗЦ Існує більш ніж один спосіб зробити це. TMTOWTDI (Вимовляється Tiм Tоуді).
-
Прості речі мають лишатися простими, складні мають простішати, а неможливі мають стати складними.
-
Raku: Позначення мови програмування в межах добірки тестів. Реалізації, які проходять добірку тестів без помилок, вважаються Raku.
-
Rakudo: Компілятор Raku.
-
Rakudobrew: менеджер встановлення Rakudo.
-
Zef: менеджер модулів Raku.
-
Rakudo Star: колекція, яка містить Rakudo, Zef, добірку модулів Raku та документацію.
Аби встановити Rakudo Star, виконайте наступні команди у своєму терміналі:
mkdir ~/rakudo && cd $_
curl -LJO https://rakudo.org/latest/star/src
tar -xzf rakudo-star-*.tar.gz
mv rakudo-star-*/* .
rm -fr rakudo-star-*
./bin/rstar install
echo "export PATH=$(pwd)/bin/:$(pwd)/share/perl6/site/bin:$(pwd)/share/perl6/vendor/bin:$(pwd)/share/perl6/core/bin:\$PATH" >> ~/.bashrc
source ~/.bashrc
Аби дізнатися про інші способи, перейдіть до https://rakudo.org/star/source
Доступними є чотири варіанти:
-
Дотримуватися тих самих кроків, що й для Linux
-
Встановити через homebrew:
brew install rakudo-star
-
Встановити з MacPorts:
sudo port install rakudo
-
Завантажити найсвіжіший встановлювач з https://rakudo.perl6.org/downloads/star/ (файл з розширенням .dmg)
-
Завантажте останній встановлювач (файл з розширенням .msi) з https://rakudo.perl6.org/downloads/star/
Якщо у вас 32-бітна система, завантажте файл х86; якщо 64-бітна, файл х86_64. -
Піcля встановлення переконайтеся, що
C:\rakudo\bin
додано до змінної PATH.
-
Отримайте офіційний образ для Docker
docker pull rakudo-star
-
Далі запустіть контейнер з цим образом
docker run -it rakudo-star
Виконувати код Raku можна в режимі інтерактивного інтерпретатора команд або REPL (Read-Eval-Print Loop). Для цього відкрийте вікно термінала, наберіть raku
та натисніть [Enter]. Це призведе до появи запрошення >
. Далі, наберіть рядок коду та натисніть [Enter], інтерпретатор надрукує значення або результат виконання цього рядка. Далі ви можете ввести інший рядок, або набрати exit
та натиснути [Enter] аби завершити сесію інтерпретатора.
Також ви можете записати свій код у файл, зберегти та виконати його. Є рекомендованим надавати скриптам Raku розширення .raku
. Виконати такий файл можна набравши raku ваш_скрипт.raku
у термінальному вікні та натиснувши [Enter]. На відміну від інтерактивного режиму це не призведе до негайного друку результатів виконання коду: код має містити команди на кшталт say
аби надрукувати результати виконання.
Інтерактивний режим здебільшого вживають, коли треба виконати якийсь конкретний фрагмент коду, зазвичай єдиний рядок. Програми більші за один рядое краще зберігати у файл і потім виконувати їх.
Один рядок можна також виконати з командного рядка в неінтерактивному режимі, написавши raku -e 'ваш код тут'
та натиснувши [Enter].
Tip
|
Rakudo Star вже містить редактор, який допоможе вам отримати якнайбільше від інтерактивного режиму. Якщо ви встановили звичайний Rakudo замість Rakudo Star, тоді ви, можливо, не маєте змоги редагувати рядки (стрілки вгору та вниз для навігації по історії, ліворуч та праворуч для редагування поточного рядку, TAB для автодоповненя). Виконайте наступні команди, аби отримати все це:
|
Оскільки більшість часу ми писатимемо та зберігатимемо наші програми Raku у файлах, нам стане у пригоді будь-який пристойний текстовий редактор, який розуміє синтаксис Raku.
Особисто я надаю перевагу Vim, автор оригінального (англомовного) тексту використовує Atom - це модерні текстові редактори, які вміють підсвічувати синтаксис Raku одразу після встановлення. Raku FE це альтернативний плагін для підсвічування синтаксису, який походить від оригінального пакету, але містить багато виправлень та доповнень.
Свіжі версії Vim розуміють синтаксис Raku одразу після встановлення, Emacs та Padre потребують встановлення додаткових пакетів.
Ми почнемо з ритуалу Вітаю світ
.
say 'Вітання Світові!';
Це також може бути написане як
'Вітаю світ!'.say;
Raku є вільною за формою мовою: більшість часу ви можете використовувати довільну кількість пробілів, проте у певних випадках пробіл має значення.
Твердження це, зазвичай, логічний рядок коду, який має закінчуватися крапкою з комою:
say "Hello" if True;
say "World" if False;
Крапка з комою не є обовʼязковою після останнього твердження у файлі чи блоку коду, але є доброю практикою додавати її у будь-якому випадку.
Блоки можуть складатися з набору тверджень. Візьміть твердження у фігурні скобки аби створити блок:
{
say "Перше твердження у блоці.";
say "Друге треврдження у блоці.";
}
Вираз це спеціальний тип твердження, який повертає значення:
1+2
поверне 3
Значення бувають:
-
Змінними: це значення, якими можна керувати та їх міняти.
-
Літералами: це сталі значення, як число чи рядок.
Оператори класифіковані за типами:
Тип |
Пояснення |
Приклад |
Префіксні |
Перед значенням |
++1 |
Інфіксні |
Між значеннями |
1+2 |
Постфіксні |
Після значення |
1++ |
Контейнерні |
Навколо значення |
(1) |
Постконтейнерні |
Після значення, навколо іншого |
Array[1] |
Ідентифікатори - це імена, які ви даєте значенням, коли визначаете їх.
-
Вони мають починатися з алфавітного символа, чи нижнього підкреслювання * Вони можуть містити числа, за винятком першого символа
-
Вони можуть містити дефіси та апострофи, (за винятком першої та останньої позиції) за умови, що праворуч від кожного дефіса чи апострофа знаходиться алфавітний символ.
Вірно |
Невірно |
var1 |
1var |
var-one |
var-1 |
var’one |
var'1 |
var1_ |
var1' |
_var1 |
-var |
змінна1 |
1змінна |
-
Стиль верблюда:
variableNo1
-
Шашличний стиль:
variable-no1
-
Стиль змії:
variable_no1
Ви можете довільно іменувати ваші ідентифікатори, але ознакою гарного тону є використання якогось одного стилю.
Використання осмислених назв полегшить ваше життя (та життя інших).
-
var1 = var2 * var3
синтаксично вірно, але призначення кожної змінної не є очевидним. -
monthly-salary = daily-rate * working-days
значно кращій варіант іменування змінних.
Коментар - це текст, ігнорований компілятором, який слугує для пояснення (саме пояснення, а не цитування) коду.
Коментарі поділяють на три типи:
-
Однорядкові:
# Це коментар в один рядок
-
Вбудовані:
say #`(Це вбудований коментар) "Hello World."
-
Багаторядкові:
=begin comment
Це багаторядковий коментар.
Коментар 1
Коментар 2
=end comment
Рядки мають бути обмежені поодинокими чи подвійними лапками.
Завжди використовуйте подвійні лапки якщо:
-
Ваш рядок містить апостроф.
-
Ваш рядок містить змінну, яку має бути розгорнуто.
say 'Вітаю, Світ'; # Вітаю, Світ
say "Вітаю, світ"; # Вітаю, Світ
say "Об'єм"; # Об'єм
my $name = 'Андрій Кузьменко';
say 'Вітаю $name'; # Вітаю $name
say "Вітаю $name"; # Вітаю Андрій Кузьменко
У таблиці нижче перераховані найбільш уживані оператори.
Оператор | Тип | Опис | Приклад | Результат |
---|---|---|---|---|
|
|
Додавання |
|
|
|
|
Віднімання |
|
|
|
|
Множення |
|
|
|
|
Ступінь |
|
|
|
|
Ділення |
|
|
|
|
Цілочисленне ділення (округлення до меншого) |
|
|
|
|
Залишок від ділення |
|
|
|
|
Ділимість |
|
|
|
|
|||
|
|
Найбільший спільній дільник |
|
|
|
|
Найменше спільне кратне |
|
|
|
|
Арифметичне порівняння |
|
|
|
|
Арифметичне не дорівнює |
|
|
|
|
Менше |
|
|
|
|
Більше |
|
|
|
|
Менше чи дорівнює |
|
|
|
|
Більше чи дорівнює |
|
|
|
|
Текстове порівняння |
|
|
|
|
Текстове не дорівнює |
|
|
|
|
Привласнення |
|
|
|
|
Злиття рядків |
|
|
|
|
|||
|
|
Повторення рядків |
|
|
|
|
|||
|
|
Розумний пошук входження |
|
|
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
Інкремент |
|
|
|
Інкремент |
|
|
|
|
|
Декремент |
|
|
|
Декремент |
|
|
|
|
|
Привести операнд до числового типу |
|
|
|
|
|||
|
|
|||
|
|
Привести операнд до числового типу та інвертувати знак |
|
|
|
|
|||
|
|
|||
|
|
Привести операнд до логічного типу |
|
|
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
Привести операнд до логічного типу та повернути протилежне значення |
|
|
|
|
Конструктор послідовностей |
|
|
|
|
Конструктор послідовностей |
|
|
|
|
Конструктор послідовностей |
|
|
|
|
Конструктор послідовностей |
|
|
|
|
Конструктор послідовностей |
|
|
|
|
Ледащий конструктор списків |
|
|
|
|
Сплощення |
|
|
|
|
Додавання R перед будь-яким оператором призведе до обертання напрямку їх дії.
Звичайний оператор | Результат | Зворотній оператор | Результат |
---|---|---|---|
|
|
|
|
|
|
|
|
Оператори згортання працюють зі списками значень.
Звичайний оператор | Результат | Оператор згортання | Результат |
---|---|---|---|
|
|
|
|
|
|
|
|
Note
|
Аби отримати повний список операторів разом з їх пріоритетами, перейдіть до https://docs.raku.org/language/operators |
Змінні Raku класифіковано за трьома категоріями: скаляри, масиви, та хеші (асоціативні масиви).
Сигіл ("Знак" Латиною) - це символ, який слугує префіксом для категоризації змінних.
-
$
позначає скаляри -
@
позначає масиви -
%
позначає хеші
Скаляр зберігає єдине значення чи посилання
# Рядок
my $name = 'Андрій Кузьменко';
say $name;
# Ціле число
my $age = 99;
say $age;
Залежно від значення, яке зберігає скаляр, над ним можна виконувати певний набір операцій.
my $name = 'Андрій Кузьменко';
say $name.uc;
say $name.chars;
say $name.flip;
АНДРІЙ КУЗЬМЕНКО
16
окнемьзуК йірднА
Note
|
Аби переглянути повний список методів, які придатні до застосування до рядків перейдіть до https://docs.raku.org/type/Str |
my $age = 17;
say $age.is-prime;
True
Note
|
Аби дізнатися про повний список методів, які придатні до застосування до цілих чисел перейдіть до https://docs.raku.org/type/Int |
my $age = 2.3;
say $age.numerator;
say $age.denominator;
say $age.nude;
23
10
(23 10)
Note
|
Аби дізнатися про повний список методів, які придатні до застосування до раціональних чисел перейдіть до https://docs.raku.org/type/Rat |
Масиви - це списки, які містять багато значень
my @animals = 'верблюд','лама','сова';
say @animals;
Багато операцій може бути виконано надо масивами, як показано в наступному прикладі:
Tip
|
Тільда ~ призначена для конкатенації рядків.
|
Програма
my @animals = 'верблюд','вікунья','лама';
say "У зоопарку є " ~ @animals.elems ~ " тварин";
say "Ці тварини: " ~ @animals;
say "Я маю намір віддати до зоопарку сову";
@animals.push("сова");
say "Тепер у зоопарку є: " ~ @animals;
say "Перша тварина, яка в нас з'явилася, це " ~ @animals[0];
@animals.pop;
say "На жаль сова втекла та в нас лишилися: " ~ @animals;
say "Ми закриваємо зоопарк та залишаемо собі лише одну тварину";
say "Ми плануємо віддати: " ~ @animals.splice(1,2) ~ " та залишити " ~ @animals;
Вивід
У зоопарку є 3 тварини
Ці тварини: верблюд вікунья лама
Я маю намір віддати до зоопарку сову
Тепер у зоопарку є: верблюд вікунья лама сова
Перша тварина, яка в нас з'явилася, це верблюд
На жаль сова втекла та в нас лишилися: верблюд вікунья лама
Ми закриваємо зоопарк та залишаємо собі лише одну тварину
Ми плануємо віддати: вікунья лама та залишити верблюд
.elems
повертає кількість елементів масиву.
.push()
додає один чи більше елементів в кінець масиву.
Ми можемо звернутися до певного елемента масиву вказавши його положення @animals[0]
.
.pop
видаляє останній елемент масиву та повертає його.
.splice(a,b)
видалить (та поверне) b
елементів починаючи з позиції a
.
Оголошення звичайного масиву виглядає наступним чином:
my @array;
Звичайний масив може бути довільного розміру, тому його називають автоматично розширюваним.
Такий масив приймає довільну кількість значень без будь-яких обмежень.
На противагу, ми можемо створити масив фіксованого розміру.
Доступ до таких масивів є неможливим за межами їх визначеного розміру.
my @array[3];
Цей масив здатен зберігати лише 3 значення, з індексами від 0 до 2.
my @array[3];
@array[0] = "перше значення";
@array[1] = "друге значення";
@array[2] = "третє значення";
Ви не зможете додати четверте значення до такого масиву.
my @array[3];
@array[0] = "перше значення";
@array[1] = "друге значення";
@array[2] = "третє значення";
@array[3] = "четверте значення";
Index 3 for dimension 1 out of range (must be 0..2)
Масиви, які ми бачили до цього часу є одновимірними.
На щастя, у Raku ми можемо визначати багатовимірні масиви.
my @tbl[3;2];
Цей масив двовимірний. Перший вимір може зберігати завбільшки 3 значення, та другий вимір не більше ніж 2 значення.
Думайте про нього, як про таблицю 3х2.
my @tbl[3;2];
@tbl[0;0] = 1;
@tbl[0;1] = "x";
@tbl[1;0] = 2;
@tbl[1;1] = "y";
@tbl[2;0] = 3;
@tbl[2;1] = "z";
say @tbl
[[1 x] [2 y] [3 z]]
[1 x]
[2 y]
[3 z]
Note
|
Повну документацію про масиви можна знайти за посиланням: https://docs.raku.org/type/Array |
my %capitals = ('UK','Лондон','Ukraine','Київ');
say %capitals;
my %capitals = (UK => 'London',Ukraine => 'Kyiv');
say %capitals;
Деякі методи, які можуть бути застосовані до хешів:
Програма
my %capitals = (UK => 'Лондон', Ukraine => 'Київ');
%capitals.push: (France => 'Париж');
say %capitals.kv;
say %capitals.keys;
say %capitals.values;
say "Столиця Франції це: " ~ %capitals<France>;
Вивід
(France Париж UK Лондон Ukraine Київ)
(France UK Ukraine)
(Київ Лондон Париж)
Столиця Франції це: Париж
.push: (ключ ⇒ 'Значення')
додає нову пару ключ/значення.
.kv
повертає список, який містить усі ключі та значення.
.keys
повертає список, який містить усі ключі.
.values
повертає список, який містить усі значення.
Ви можете звернутися до необхідного значення у хеші, вказавши його ключ %hash<ключ>
Note
|
Повну довідку по хешам ви можете отримати тут: https://docs.raku.org/type/Hash |
У попередніх прикладах ми не вказували типи значень, які мають зберігати змінні.
Tip
|
.WHAT поверне тип значення, збереженого у змінній.
|
my $var = 'Text';
say $var;
say $var.WHAT;
$var = 123;
say $var;
say $var.WHAT;
Як бачимо з прикладу наведеного вище, тип значення у $var
спочатку був (Str), потім став (Int).
Такий стиль програмування називають динамічною типізацією. Динамічною в тому сенсі, що змінні можуть зберігати значення будь-якого типу.
Тепер спробуйте виконати приклад ничже:
Зверніть увагу на Int
перед ім’ям змінної.
my Int $var = 'Text';
say $var;
say $var.WHAT;
Цей код не буде виконано, натомість з’явиться помилка: Type check failed in assignment to $var; expected Int but got Str
Відмінність у тому, що ми заздалегідь вказали, що змінна має бути типу (Int). Коли ми спробували присвоїти змінній значення типу (Str), компілятор повернув помилку.
Такий стиль програмування називають статичною типізацією. Статичною в тому сенсі, що тип змінної визначають перед тим, як присвоїти значення і він не може бути змінений.
Raku класифіковано як мову з поступовою типізацією, тобто вона дозволяє як статичну, так і динамічну типізацію.
my Int @array = 1,2,3;
say @array;
say @array.WHAT;
my Str @multilingual = "Hello","Вітаю","Hallo","您好","안녕하세요","こんにちは";
say @multilingual;
say @multilingual.WHAT;
my Str %capitals = (UK => 'London', Ukraine => 'Kyiv');
say %capitals;
say %capitals.WHAT;
my Int %country-codes = (UK => 44, Ukraine => 38);
say %country-codes;
say %country-codes.WHAT;
Скоріш за все, ви ніколи не використаєте перші два - вони наведені для інформації.
|
|
|
|
|
|
||
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Інтроспекція це процес отримання інформації про властивості об’єкта, такої як тип.
В одному з попередніх прикладів ми використали .WHAT
аби отримати тип змінної.
my Int $var;
say $var.WHAT; # (Int)
my $var2;
say $var2.WHAT; # (Any)
$var2 = 1;
say $var2.WHAT; # (Int)
$var2 = "Hello";
say $var2.WHAT; # (Str)
$var2 = True;
say $var2.WHAT; # (Bool)
$var2 = Nil;
say $var2.WHAT; # (Any)
Тип змінної, яка зберігає значення, має відношення до її значення.
Тип явно оголошеної пустої змінної є типом, з яким її оголосили.
Типом пустої змінної, тип якої не було оголошено явно, є (Any)
Аби очистити значення змінної, треба присвоїти їй значення Nil
.
Перш ніж вперше використати змінну, вона має бути оголошена.
У Raku існує декілька способів це зробити. Досі ми використовували my
.
my $var=1;
Оголошення у вигляді my
надає змінній область видимості.
Іншими словами, змінна буде досяжна лише у тому блоці, де вона була оголошена.
У Raku блок обмежений { }
.
Якщо межі блоку не знайдені, змінна буде досяжною у всьому скрипті Raku.
{
my Str $var = 'Text';
say $var; # is accessible
}
say $var; # is not accessible, returns an error
Оскільки змінна досяжна лише у межах блоку, те саме ім’я змінної можна використати також в іншому блоці.
{
my Str $var = 'Text';
say $var;
}
my Int $var = 123;
say $var;
У попередніх прикладах ми бачили як привласнити значення змінній.
Привласнення виконують за допомогою оператора =
.
my Int $var = 123;
say $var;
Ми маємо змогу змінити значення, привласнене змінній:
my Int $var = 123;
say $var;
$var = 999;
say $var;
Виведення
123
999
З іншого боку, ми не можемо змінити значення, яке є зв’язаним зі змінною.
Зв’язування роблять за допомогою оператора :=
.
my Int $var := 123;
say $var;
$var = 999;
say $var;
Виведення
123
Cannot assign to an immutable value
my $a;
my $b;
$b := $a;
$a = 7;
say $b;
$b = 8;
say $a;
Виведення
7
8
Зв’язування змінних є двонаправленим.
$a := $b
та $b := $a
мають однаковий ефект.
Note
|
Аби дізнатися більше про змінні, завітайте до https://docs.raku.org/language/variables |
Важливо відрізняти функції та мутатори. Функції не змінюють стан об’єкта, на якому їх було викликано. Мутатори змінюють стан об’єкта.
Скрипт
my @numbers = [7,2,4,9,11,3];
@numbers.push(99);
say @numbers; #1
say @numbers.sort; #2
say @numbers; #3
@numbers.=sort;
say @numbers; #4
Виведення
[7 2 4 9 11 3 99] #1
(2 3 4 7 9 11 99) #2
[7 2 4 9 11 3 99] #3
[2 3 4 7 9 11 99] #4
.push
це мутатор, він змінює стан об’єкту (#1)
.sort
це функція; вона повертає відсортований масив, але не змінює стан вихідного масиву.
-
(#2) показує, що було повернено відсортований масив.
-
(#3) показує, що вихідний масив не було змінено.
Аби змусити функцію поводитися, як мутатор, ми використовуємо .=
замість .
(#4) (Рядок 9 скрипта)
Raku має багато варіантів будови умов та циклів.
Код буде виконано лише у разі задовільнення умови; тобто вираз має повернути істину.
my $age = 19;
if $age > 18 {
say 'Welcome'
}
У Raku ми можемо поміняти місцями код та умову.
Навіть якщо код та умову було поміняно місцями, перевірка умови завжди буде виконана першою.
my $age = 19;
say 'Welcome' if $age > 18;
Якщо умову не було задовільнено, ми можемо вказати альтернативні блоки для виконання за допомогою
-
else
-
elsif
# run the same code for different values of the variable
my $number-of-seats = 9;
if $number-of-seats <= 5 {
say 'I am a sedan'
} elsif $number-of-seats <= 7 {
say 'I am 7 seater'
} else {
say 'I am a van'
}
Заперечна версія if
("Якщо не") може бути записана за допомогою unless
.
Наступний код:
my $clean-shoes = False;
if not $clean-shoes {
say 'Clean your shoes'
}
може бути записаний як:
my $clean-shoes = False;
unless $clean-shoes {
say 'Clean your shoes'
}
Заперечення у Raku виконують за допомогою !
або not
.
unless (умова)
використовують замість if not (умова)
.
unless
не може мати блока else
.
with
поводиться як if
, але перевіряє чи визначена змінна.
my Int $var=1;
with $var {
say 'Hello'
}
Якщо ви виконуєте код без присвоєння значення змінній, нічого не станеться.
my Int $var;
with $var {
say 'Hello'
}
without
це заперечена версія with
. Ви можете порівняти її з unless
.
Якщо першу умову with
не було задовільнено, альтернативну путь може бути визначено за допомогою orwith
.
with
та orwith
можна порівняти з if
та elsif
.