diff options
author | Suzane Sant Ana <tetestonaldo@gmail.com> | 2017-12-31 14:27:06 -0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-31 14:27:06 -0200 |
commit | 42f9329bb3a028d374d6397991ac48b44064741e (patch) | |
tree | 1e75e2b3e122aeb863e3ffa037f6f64c4027fbf8 /uk-ua | |
parent | e6b77595f2669d66ac7be43c6e6083cbff80a9a7 (diff) | |
parent | 70a36c9bd970b928adde06afb2bd69f6ba8e5d5c (diff) |
Merge pull request #1 from adambard/master
update
Diffstat (limited to 'uk-ua')
-rw-r--r-- | uk-ua/bash-ua.html.markdown | 294 | ||||
-rw-r--r-- | uk-ua/java-ua.html.markdown | 784 | ||||
-rw-r--r-- | uk-ua/javascript-ua.html.markdown | 494 | ||||
-rw-r--r-- | uk-ua/json-ua.html.markdown | 73 | ||||
-rw-r--r-- | uk-ua/ruby-ua.html.markdown | 625 |
5 files changed, 2270 insertions, 0 deletions
diff --git a/uk-ua/bash-ua.html.markdown b/uk-ua/bash-ua.html.markdown new file mode 100644 index 00000000..c6e9ebb1 --- /dev/null +++ b/uk-ua/bash-ua.html.markdown @@ -0,0 +1,294 @@ +--- +category: tool +tool: bash +contributors: + - ["Max Yankov", "https://github.com/golergka"] + - ["Darren Lin", "https://github.com/CogBear"] + - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"] + - ["Denis Arh", "https://github.com/darh"] + - ["akirahirose", "https://twitter.com/akirahirose"] + - ["Anton Strömkvist", "http://lutic.org/"] + - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gregrory Kielian", "https://github.com/gskielian"] + - ["Etan Reisner", "https://github.com/deryni"] +translators: + - ["Ehreshi Ivan", "https://github.com/IvanEh"] + - ["Serhii Maksymchuk", "https://github.com/Serg-Maximchuk"] +lang: uk-ua +--- + +Bash - командна оболонка unix (unix shell), що також розповсюджувалась як оболонка для +операційної системи GNU і зараз використовується як командна оболонка за замовчуванням +для Linux i Max OS X. +Майже всі приклади, що наведені нижче можуть бути частиною shell-скриптів або +виконані в оболонці + +[Більш детально тут.](http://www.gnu.org/software/bash/manual/bashref.html) + +```bash +#!/bin/bash +# Перший рядок скрипта - це shebang, який вказує системі, як потрібно виконувати +# скрипт. Як ви вже зрозуміли, коментарі починаються з #. Shebang - також коментар + +# Простий приклад hello world: +echo Hello world! + +# Окремі команди починаються з нового рядка або розділяються крапкою з комкою: +echo 'Перший рядок'; echo 'Другий рядок' + +# Оголошення змінної +VARIABLE="Просто рядок" + +# Але не так! +VARIABLE = "Просто рядок" +# Bash вирішить, що VARIABLE - це команда, яку він може виконати, +# і видасть помилку, тому що не зможе знайти її + +# І так також не можна писати: +VARIABLE= 'Просто рядок' +# Bash сприйме рядок 'Просто рядок' як команду. Але такої команди не має, тому +# видасть помилку. +# (тут 'VARIABLE=' інтерпретується як присвоєння тільки в контексті +# виконання команди 'Просто рядок') + +# Використання змінних: +echo $VARIABLE +echo "$VARIABLE" +echo '$VARIABLE' +# Коли ви використовуєте змінну - присвоюєте значення, експортуєте і т.д. - +# пишіть її імя без $. А для отримання значення змінної використовуйте $. +# Одинарні лапки ' не розкривають значення змінних + +# Підстановка рядків в змінні +echo ${VARIABLE/Просто/A} +# Цей вираз замінить перше входження підрядка "Просто" на "А" + +# Отримання підрядка із рядка +LENGTH=7 +echo ${VARIABLE:0:LENGTH} +# Цей вираз поверне тільки перші 7 символів змінної VARIABLE + +# Значення за замовчуванням +echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"} +# Це спрацює при відсутності значення (FOO=) і при пустому рядку (FOO="") +# Нуль (FOO=0) поверне 0. +# Зауважте, що у всіх випадках значення самої змінної FOO не зміниться + +# Вбудовані змінні: +# В bash є корисні вбудовані змінні, наприклад +echo "Значення, яке було повернуте в останній раз: $?" +echo "PID скрипта: $$" +echo "Кількість аргументів: $#" +echo "Аргументи скрипта: $@" +echo "Аргументи скрипта, розподілені по різним змінним: $1 $2..." + +# Зчитування змінних з пристроїв введення +echo "Як вас звати?" +read NAME # Зверніть увагу, що вам не потрібно оголошувати нову змінну +echo Привіт, $NAME! + +# В bash є звичайна умовна конструкція if: +# наберіть 'man test', щоб переглянути детальну інформацію про формати умов +if [ $NAME -ne $USER ] +then + echo "Ім’я користувача не збігається з введеним" +else + echo "Ім’я збігаєтьяс з іменем користувача" +fi + +# Зауважте! якщо $Name пуста, bash інтерпретує код вище як: +if [ -ne $USER ] +# що є неправильним синтаксисом +# тому безпечний спосіб використання потенційно пустих змінних має вигляд: +if [ "$Name" -ne $USER ] ... +# коли $Name пуста, інтерпретується наступним чином: +if [ "" -ne $USER ] ... +# що працює як і очікувалося + +# Умовне виконання (conditional execution) +echo "Виконується завжди" || echo "Виконається, якщо перша команда завершиться з помилкою" +echo "Виконується завжди" && echo "Виконається, якщо перша команда завершиться успішно" + +# Щоб використати && і || у конструкції if, потрібно декілька пар дужок: +if [ $NAME == "Steve" ] && [ $AGE -eq 15 ] +then + echo "Виконається, якщо $NAME="Steve" i AGE=15." +fi + +if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ] +then + echo "Виконається, якщо NAME="Steve" або NAME="Zach"." +fi + +# Вирази позначаються наступним форматом: +echo $(( 10 + 5 )) + +# На відміну від інших мов програмування, Bash - це командна оболонка, а +# отже, працює в контексті поточної директорії +ls + +# Ця команда може використовуватися з опціями +ls -l # Показати кожен файл і директорію на окремому рядку + +# Результат попередньої команди можна перенаправити на вхід наступної. +# Команда grep фільтрує вхід по шаблону. +# Таким чином ми можемо переглянути тільки *.txt файли в поточній директорії: +ls -l | grep "\.txt" + +# Ви можете перенаправити вхід і вихід команди (stdin, stdout, stderr). +# Наступна команда означає: читати із stdin, поки не зустрінеться ^EOF$, і +# перезаписати hello.py наступними рядками (до рядка "EOF"): +cat > hello.py << EOF +#!/usr/bin/env python +from __future__ import print_function +import sys +print("#stdout", file=sys.stdout) +print("#stderr", file=sys.stderr) +for line in sys.stdin: + print(line, file=sys.stdout) +EOF + +# Запуск hello.py з різними варіантами перенаправлення stdin, +# stdout, stderr (стандартні потоки введення, виведення і помилок): +python hello.py < "input.in" +python hello.py > "output.out" +python hello.py 2> "error.err" +python hello.py > "output-and-error.log" 2>&1 +python hello.py > /dev/null 2>&1 +# Потік помилок перезапише файл, якщо цей файл існує +# тому, якщо ви хочете дописувати до файлу, використовуйте ">>": +python hello.py >> "output.out" 2>> "error.err" + +# Перезаписати output.txt, дописати error.err і порахувати кількість рядків: +info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err +wc -l output.out error.err + +# Запустити команду і вивести її файловий дескриптор (див.: man fd; наприклад /dev/fd/123) +echo <(echo "#helloworld") + +# Перезаписати output.txt рядком "#helloworld": +cat > output.out <(echo "#helloworld") +echo "#helloworld" > output.out +echo "#helloworld" | cat > output.out +echo "#helloworld" | tee output.out >/dev/null + +# Очистити тимчасові файли з детальним виводом (додайте '-i' +# для інтерактивного режиму) +rm -v output.out error.err output-and-error.log + +# Команди можуть бути підставлені в інші команди використовуючи $(): +# наступна команда виводить кількість файлів і директорій в поточній директорії +echo "Тут $(ls | wc -l) елементів." + +# Те саме можна зробити використовуючи зворотні лапки +# Але вони не можуть бути вкладеними, тому перший варіант бажаніший +echo "Тут `ls | wc -l` елементів." + +# В Bash є структура case, яка схожа на switch в Java и C++: +case "$VARIABLE" in + # перерахуйте шаблони, які будуть використовуватися в якості умов + 0) echo "Тут нуль.";; + 1) echo "Тут один.";; + *) echo "Не пусте значення.";; +esac + +# Цикл for перебирає елементи передані в аргумент: +# Значення $VARIABLE буде надруковано тричі. +for VARIABLE in {1..3} +do + echo "$VARIABLE" +done + +# Aбо можна використати звичний синтаксис for: +for ((a=1; a <= 3; a++)) +do + echo $a +done + +# Цикл for можно використати, щоб виконувати дії над файлами. +# Цей код запустить команду 'cat' для файлів file1 и file2 +for VARIABLE in file1 file2 +do + cat "$VARIABLE" +done + +# ... або дії над виводом команд +# Запустимо cat для виведення із ls. +for OUTPUT in $(ls) +do + cat "$OUTPUT" +done + +# Цикл while: +while [ true ] +do + echo "Тіло циклу..." + break +done + +# Ви також можете оголосити функцію +# Оголошення: +function foo () +{ + echo "Аргументи функції доступні так само, як і аргументи скрипта: $@" + echo "$1 $2..." + echo "Це функція" + return 0 +} + +# Або просто +bar () +{ + echo "Інший спосіб оголошення функцій!" + return 0 +} + +# Виклик функцій +foo "Мое имя" $NAME + +# Є багато корисних команд: +# вивести останні 10 рядків файла file.txt +tail -n 10 file.txt +# вивести перші 10 рядків файла file.txt +head -n 10 file.txt +# відсортувати рядки file.txt +sort file.txt +# відібрати або пропустити рядки, що дублюються (з опцією -d відбирає) +uniq -d file.txt +# вивести тільки першу колонку перед символом ',' +cut -d ',' -f 1 file.txt +# замінити кожне 'okay' на 'great' у файлі file.txt (підтримується regex) +sed -i 's/okay/great/g' file.txt +# вивести в stdout всі рядки з file.txt, що задовольняють шаблону regex; +# цей приклад виводить рядки, що починаються на foo і закінчуються на bar: +grep "^foo.*bar$" file.txt +# використайте опцію -c, щоб вивести кількість входжень +grep -c "^foo.*bar$" file.txt +# щоб здійснити пошук по рядку, а не по шаблону regex, використовуйте fgrea (або grep -F) +fgrep "^foo.*bar$" file.txt + +# Читайте вбудовану документацію Bash командою 'help': +help +help help +help for +help return +help source +help . + +# Читайте Bash man-документацію +apropos bash +man 1 bash +man bash + +# Читайте документацію info (? для допомоги) +apropos info | grep '^info.*(' +man info +info info +info 5 info + +# Читайте bash info документацію: +info bash +info bash 'Bash Features' +info bash 6 +info --apropos bash +``` diff --git a/uk-ua/java-ua.html.markdown b/uk-ua/java-ua.html.markdown new file mode 100644 index 00000000..1d600400 --- /dev/null +++ b/uk-ua/java-ua.html.markdown @@ -0,0 +1,784 @@ +--- +language: java +filename: LearnJava-ua.java +contributors: + - ["Jake Prather", "http://github.com/JakeHP"] + - ["Jakukyo Friel", "http://weakish.github.io"] + - ["Madison Dickson", "http://github.com/mix3d"] + - ["Simon Morgan", "http://sjm.io/"] + - ["Zachary Ferguson", "http://github.com/zfergus2"] + - ["Cameron Schermerhorn", "http://github.com/cschermerhorn"] + - ["Rachel Stiyer", "https://github.com/rstiyer"] +translators: + - ["Oleksandr Tatarchuk", "https://github.com/tatarchuk"] + - ["Andre Polykanine", "https://github.com/Oire"] +lang: uk-ua + +--- + +Java є об’єктно-орієнтованою мовою програмування загального призначення з підтримкою паралельного програмування, яка базується на класах. +[Детальніше читайте тут, англ.](http://docs.oracle.com/javase/tutorial/java/) + +```java +// Однорядковий коментар починається з // +/* +Багаторядковий коментар виглядає так. +*/ +/** +JavaDoc-коментар виглядає так. Використовується для опису класу та членів класу. +*/ + +// Імпорт класу ArrayList з пакета java.util +import java.util.ArrayList; +// Імпорт усіх класів з пакета java.security +import java.security.*; + +// Кожний .java файл містить один зовнішній публічний клас, ім’я якого співпадає +// з іменем файлу. +public class LearnJava { + + // Для запуску програма, написана на java, повинна мати точку входу у вигляді методу main. + public static void main (String[] args) { + + // Використання System.out.println() для виводу на друк рядків. + System.out.println("Привіт, світе!"); + System.out.println( + " Ціле число: " + 10 + + " Число з рухомою комою подвійної точности: " + 3.14 + + " Булеве значення: " + true); + + // Для друку без переходу на новий рядок використовується System.out.print(). + System.out.print("Привіт, "); + System.out.print("світе"); + + // Використання System.out.printf() для простого форматованого виводу на друк. + System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159 + + /////////////////////////////////////// + // Змінні + /////////////////////////////////////// + + /* + * Оголошення змінних + */ + // Для оголошення змінних використовується формат <тип> <змінна> + int fooInt; + // Оголошення декількох змінних одного типу <тип> <ім’я1>, <ім’я2>, <ім’я3> + int fooInt1, fooInt2, fooInt3; + + /* + * Ініціалізація змінних + */ + + // Ініціалізація змінної з використанням формату <тип> <ім’я> = <значення> + int fooInt = 1; + // Ініціалізація декількох змінних одного типу з одним значенням <тип> <ім’я1>, <ім’я2>, <ім’я3> = <значення> + int fooInt1, fooInt2, fooInt3; + fooInt1 = fooInt2 = fooInt3 = 1; + + /* + * Типи змінних + */ + // Байт — 8-бітне ціле число зі знаком + // (-128 <= byte <= 127) + byte fooByte = 100; + + // Short — 16-бітне ціле число зі знаком + // (-32 768 <= short <= 32 767) + short fooShort = 10000; + + // Integer — 32-бітне ціле число зі знаком + // (-2 147 483 648 <= int <= 2 147 483 647) + int fooInt = 1; + + // Long — 64-бітне ціле число зі знаком + // (-9 223 372 036 854 775 808 <= long <= 9 223 372 036 854 775 807) + long fooLong = 100000L; + // L використовується для позначення того, що число має тип Long; + // інакше число буде трактуватись як integer. + + // Примітка: Java не має беззнакових типів. + + // Float — 32-бітне число з рухомою комою одиничної точності за стандартом IEEE 754 + // 2^-149 <= float <= (2-2^-23) * 2^127 + float fooFloat = 234.5f; + // f або F використовується для позначення того, що змінна має тип float; + // інакше трактується як double. + + // Double — 64-бітне число з рухомою комою подвійної точності за стандартом IEEE 754 + // 2^-1074 <= x <= (2-2^-52) * 2^1023 + double fooDouble = 123.4; + + // Boolean — true & false (істина чи хиба) + boolean fooBoolean = true; + boolean barBoolean = false; + + // Char — 16-бітний символ Unicode + char fooChar = 'A'; + + // final - посилання на такі змінні не можуть бути присвоєні іншим об’єктам, + final int HOURS_I_WORK_PER_WEEK = 9001; + // але вони можуть мати відкладену ініціалізацію. + final double E; + E = 2.71828; + + + // BigInteger -Незмінні знакові цілі числа довільної точності + // + // BigInteger є типом даних, який дає можливість розробнику виконувати операції + // з цілими числами, розрядність яких більша за 64 біти. Числа зберігаються у масиві + // байтів, операції над ними виконуються функціями, які мають клас BigInteger + // + // BigInteger можна ініціалізувати, використовуючи масив байтів чи рядок. + + BigInteger fooBigInteger = new BigInteger(fooByteArray); + + + // BigDecimal — Незмінні знакові дробові числа довільної точності + // + // BigDecimal складається з двох частин: цілого числа довільної точності + // з немасштабованим значенням та 32-бітного масштабованого цілого числа + // + // BigDecimal дозволяє розробникам контролювати десяткове округлення. + // Рекомендовано використовувати BigDecimal зі значеннями валют + // і там, де необхідна точність дробових обчислень. + // + // BigDecimal може бути ініціалізований типами даних int, long, double або String + // чи немасштабованим значенням (BigInteger) і масштабованим значенням (int). + + BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt); + + // Для дотримання заданої точності рекомендується використовувати + // конструктор, який приймає String + + BigDecimal tenCents = new BigDecimal("0.1"); + + + // Рядки + String fooString = "Це мій рядок!"; + + // \n є символом переходу на новий рядок + String barString = "Друк з нового рядка?\nНема питань!"; + // \t — це символ табуляції + String bazString = "Хочете додати табуляцію?\tТримайте!"; + System.out.println(fooString); + System.out.println(barString); + System.out.println(bazString); + + // Масиви + // Розмір масиву має бути визначений перед ініціалізацією + // Наведений формат ілюструє ініціалізацію масивів + // <тип даних>[] <ім’я змінної> = new <тип даних>[<розмір масиву>]; + // <тип даних> <ім’я змінної>[] = new <тип даних>[<розмір масиву>]; + int[] intArray = new int[10]; + String[] stringArray = new String[1]; + boolean boolArray[] = new boolean[100]; + + // Інший шлях оголошення та ініціалізації масиву + int[] y = {9000, 1000, 1337}; + String names[] = {"Bob", "John", "Fred", "Juan Pedro"}; + boolean bools[] = new boolean[] {true, false, false}; + + // Індексація масиву — доступ за елементами + System.out.println("intArray @ 0: " + intArray[0]); + + // Масиви є змінними та мають нульовий елемент. + intArray[1] = 1; + System.out.println("intArray @ 1: " + intArray[1]); // => 1 + + // Додатково + // ArrayLists — Схожі на масив, але мають більший функціонал та змінний розмір. + // LinkedLists — Реалізація двозв’язного списку. Всі операції + // виконуються так, як очікується від + // двозв’язного списку. + // Maps — Множина об’єктів, які пов’язують ключ зі значенням. Map є + // інтерфейсом, тому не може бути успадкований. + // Типи ключів і значень, які зберігаються в Map, мають + // вказуватись у класі, який його реалізує. + // Ключ не може повторюватись і пов’язаний лише з одним значенням + // HashMaps — Цей клас використовує хеш-таблицю для реалізації інтерфейсу Map. + // Це дозволяє виконувати певні операції, + // такі, як отримання та вставка елемента, + // залишаючись постійними навіть для великої кількості елементів. + + /////////////////////////////////////// + // Оператори + /////////////////////////////////////// + System.out.println("\n->Оператори"); + + int i1 = 1, i2 = 2; // Коротка форма присвоєння + + // Арифметичні операції виконуються очевидним способом + System.out.println("1+2 = " + (i1 + i2)); // => 3 + System.out.println("2-1 = " + (i2 - i1)); // => 1 + System.out.println("2*1 = " + (i2 * i1)); // => 2 + System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int повертається як int) + System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5 + + // Ділення з остачею + System.out.println("11%3 = "+(11 % 3)); // => 2 + + // Оператори порівняння + System.out.println("3 == 2? " + (3 == 2)); // => false + System.out.println("3 != 2? " + (3 != 2)); // => true + System.out.println("3 > 2? " + (3 > 2)); // => true + System.out.println("3 < 2? " + (3 < 2)); // => false + System.out.println("2 <= 2? " + (2 <= 2)); // => true + System.out.println("2 >= 2? " + (2 >= 2)); // => true + + // Логічні оператори + System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false + System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true + System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true + + // Бітові оператори! + /* + ~ Унарне бітове доповнення + << Знаковий зсув уліво + >> Знаковий/Арифметичний зсув управо + >>> Беззнаковий/Логічний зсув управо + & Бітове І + ^ Бітови виключне АБО + | Бітове АБО + */ + + // Інкремент + int i = 0; + System.out.println("\n->Інкремент/Декремент"); + // Оператори ++ і -- здійснюють інкремент та декремент ретроспективно. + // Якщо вони розташовані перед змінною, операція виконається перед поверненням; + // якщо після неї — повернеться інкремент або декремент. + System.out.println(i++); // i = 1, друкує 0 (постінкремент) + System.out.println(++i); // i = 2, друкує 2 (преінкремент) + System.out.println(i--); // i = 1, друкує 2 (постдекремент) + System.out.println(--i); // i = 0, друкує 0 (предекремент) + + /////////////////////////////////////// + // Керуючі конструкції + /////////////////////////////////////// + System.out.println("\n->Керуючі конструкції"); + + // Оператор if використовується так само, як у мові C + int j = 10; + if (j == 10) { + System.out.println("Це надрукується"); + } else if (j > 10) { + System.out.println("А це — ні"); + } else { + System.out.println("Це — також ні"); + } + + // Цикл з передумовою While + int fooWhile = 0; + while(fooWhile < 100) { + System.out.println(fooWhile); + // Інкремент лічильника + // Виконається 100 разів, fooWhile 0,1,2...99 + fooWhile++; + } + System.out.println("fooWhile Value: " + fooWhile); + + // Цикл з післяумовою Do While + int fooDoWhile = 0; + do { + System.out.println(fooDoWhile); + // Інкремент лічильника + // Виконається 99 разів, fooDoWhile 0->99 + fooDoWhile++; + } while(fooDoWhile < 100); + System.out.println("Значення fooDoWhile: " + fooDoWhile); + + // Цикл з параметром For + // структура циклу => for(<початковий стан>; <умова завершення>; <крок>) + for (int fooFor = 0; fooFor < 10; fooFor++) { + System.out.println(fooFor); + // Виконається 10 разів, fooFor 0->9 + } + System.out.println("Значення fooFor: " + fooFor); + + // Вихід із вкладеного циклу через мітку + outer: + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + if (i == 5 && j ==5) { + break outer; + // вихід із зовнішнього циклу, а не лише внутрішнього + } + } + } + + // Цикл For Each + // Призначений для перебору масивів та колекцій + int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + + for (int bar : fooList) { + System.out.println(bar); + // Повторюється 9 разів та друкує числа від 1 до 9 на нових рядках + } + + // Оператор вибору Switch Case + // Оператор вибору працює з типами даних byte, short, char, int. + // Також працює з переліками Enum, + // класом String та класами-обгортками примітивних типів: + // Character, Byte, Short та Integer. + int month = 3; + String monthString; + switch (month) { + case 1: monthString = "Січень"; + break; + case 2: monthString = "Лютий"; + break; + case 3: monthString = "Березень"; + break; + default: monthString = "Інший місяць"; + break; + } + System.out.println("Результат Switch Case: " + monthString); + + // Починаючи з Java 7 і далі, вибір рядкових змінних здійснюється так: + String myAnswer = "можливо"; + switch(myAnswer) { + case "так": + System.out.println("Ви відповіли «Так»."); + break; + case "ні": + System.out.println("Ви відповіли «ні»."); + break; + case "можливо": + System.out.println("Ви відповіли «Можливо»."); + break; + default: + System.out.println("Ви відповіли «" + myAnswer + "»"); + break; + } + + // Тернарний оператор вибору + // Можна використовувати оператор «?» (знак питання) для визначення умови. + // Читається так: «Якщо (умова) вірна, то <перше значення>, інакше + // <друге значення>» + int foo = 5; + String bar = (foo < 10) ? "A" : "B"; + System.out.println(bar); // Надрукується А, бо умова вірна + + + //////////////////////////////////////// + // Перетворення типів + //////////////////////////////////////// + + // Перетворення String на Integer + Integer.parseInt("123");//поверне числову версію рядка "123" + + // Перетворення Integer на String + Integer.toString(123);//повертає рядкову версію 123 + + // Для інших перетворень є наступні класи: + // Double + // Long + // String + + // Приведення типів + // Тут можна прочитати про приведення об’єктів (англ.): + // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html + + + /////////////////////////////////////// + // Класи та функції + /////////////////////////////////////// + + System.out.println("\n->Класи та функції"); + + // (Клас Bicycle наведений нижче) + + // Новий об’єкт класу + Bicycle trek = new Bicycle(); + + // Виклик методу об’єкта + trek.speedUp(3); // Постійно використовуються методи з назвами set і get + trek.setCadence(100); + + // toString повертає рядкове представлення об’єкту. + System.out.println("Інформація про об’єкт trek: " + trek.toString()); + + // У Java немає синтаксису для явного створення статичних колекцій. + // Це можна зробити так: + + private static final Set<String> COUNTRIES = new HashSet<String>(); + static { + validCodes.add("DENMARK"); + validCodes.add("SWEDEN"); + validCodes.add("FINLAND"); + } + + // Але є інший спосіб — ініціалізація з подвійними фігурними дужками. + + private static final Set<String> COUNTRIES = new HashSet<String>() {{ + add("DENMARK"); + add("SWEDEN"); + add("FINLAND"); + }} + + // Використовується анонімний внутрішній клас + + } // Кінець методу main +} // Кінець класу LearnJava + + +// У .java-файл можна додавати інші, не public класи зовнішнього рівня, +// але це не є хорошою практикою. Розміщуйте класи в окремих файлах. + + +// Синтаксис оголошення класу: +// <public/private/protected> class <ім’я класу> { +// // поля, конструктори, функції та ін. +// // у Java функції називаються методами. +// } + +class Bicycle { + + // Поля (змінні) класу Bicycle + public int cadence; // Public: доступно звідусіль + private int speed; // Private: доступно лише у межах класу + protected int gear; // Protected: доступно лише класові та його нащадкам + String name; // за замовчанням: доступно у даному пакеті + + static String className; // статична змінна класу + + // статичний блок + // Java не має статичних конструкторів, але + // має статичний блок ініціалізації змінних класу + // Цей блок виконується при завантаженні класу. + static { + className = "Bicycle"; + } + + // Конструктори є способом створення класу + // Оце — конструктор + public Bicycle() { + // Можна викликати інший конструктор: + // this(1, 50, 5, "Bontrager"); + gear = 1; + cadence = 50; + speed = 5; + name = "Bontrager"; + } + + // Цей конструктор приймає аргументи + public Bicycle(int startCadence, int startSpeed, int startGear, + String name) { + this.gear = startGear; + this.cadence = startCadence; + this.speed = startSpeed; + this.name = name; + } + + // Синтаксис методу: + // <public/private/protected> <тип повернутого значення> <ім’я методу>(<аргументи>) + + // Java-класи часто мають методи для отримання та встановлення змінних + + // Синтаксис оголошення методу: + // <модифікатор доступу> <тип повернутого значення> <ім’я методу>(<аргументи>) + public int getCadence() { + return cadence; + } + + // void-методи не повертають значень + public void setCadence(int newValue) { + cadence = newValue; + } + + public void setGear(int newValue) { + gear = newValue; + } + + public void speedUp(int increment) { + speed += increment; + } + + public void slowDown(int decrement) { + speed -= decrement; + } + + public void setName(String newName) { + name = newName; + } + + public String getName() { + return name; + } + + //Метод показує значення змінних об’єкту. + @Override // Успадковано від класу Object. + public String toString() { + return "gear: " + gear + " cadence: " + cadence + " speed: " + speed + + " name: " + name; + } +} // кінець класу Bicycle + +// PennyFarthing є розширенням (нащадком) класу Bicycle +class PennyFarthing extends Bicycle { + // (Penny Farthings мають велике переднє колесо. + // Вони не мають передач.) + + public PennyFarthing(int startCadence, int startSpeed){ + // Виклик батьківського конструктора через super + super(startCadence, startSpeed, 0, "PennyFarthing"); + } + + // Перевизначений метод має бути відмічений аннотацією, яка починається зі знака @. + // Для ознайомлення з аннотаціями перейдіть за посиланням + // http://docs.oracle.com/javase/tutorial/java/annotations/ + @Override + public void setGear(int gear) { + gear = 0; + } +} + +// Інтерфейси +// Синтаксис оголошення інтерфейсів +// <рівень доступу> interface <ім’я інтерфейсу> extends <батьківський інтерфейс> { +// // Константи +// // Оголошення методів +// } + +//Приклад — їжа (Food): +public interface Edible { + public void eat(); // Будь-які класи, що реалізують цей інтерфейс, + // повинні реалізувати цей метод. +} + +public interface Digestible { + public void digest(); +} + + +// Можна створити клас, що реалізує обидва інтерфейси. +public class Fruit implements Edible, Digestible { + + @Override + public void eat() { + // ... + } + + @Override + public void digest() { + // ... + } +} + +// В Java можна успадковувати лише один клас, але реалізовувати багато +// інтерфейсів. Наприклад: +public class ExampleClass extends ExampleClassParent implements InterfaceOne, + InterfaceTwo { + + @Override + public void InterfaceOneMethod() { + } + + @Override + public void InterfaceTwoMethod() { + } + +} + +// Абстрактні класи + +// Синтаксис оголошення абстрактних класів: +// <рівень доступу> abstract <ім’я класу> extends <батьківський абстрактний клас> { +// // Константи і змінні +// // Оголошення методів +// } + +// Позначення класу як абстрактного означає, що оголошені у ньому методи мають +// бути реалізовані у дочірніх класах. Подібно до інтерфейсів, не можна створити екземпляри +// абстракних класів, але їх можна успадковувати. Нащадок зобов’язаний реалізувати всі абстрактні +// методи. на відміну від інтерфейсів, абстрактні класи можуть мати як визначені, +// так і абстрактні методи. Методи в інтерфейсах не мають тіла, +// за винятком статичних методів, а змінні неявно мають модифікатор final, на відміну від +// абстрактного класу. Абстрактні класи МОЖУТЬ мати метод «main». + +public abstract class Animal +{ + public abstract void makeSound(); + + // Метод може мати тіло + public void eat() + { + System.out.println("Я тварина, і я їм."); + // Зауваження: є доступ до приватних змінних. + age = 30; + } + + // Ініціалізація не потрібна + protected int age; + + public void printAge() + { + System.out.println(age); + } + + // Абстрактні класи МОЖУТЬ мати метод «main». + public static void main(String[] args) + { + System.out.println("Я абстрактний"); + } +} + +class Dog extends Animal +{ + // Слід помічати перевизначення абстрактних методів + @Override + public void makeSound() + { + System.out.println("Гав!"); + // age = 30; ==> ПОМИЛКА! age є private для Animal + } + + // Зауваження: Буде помилка, якщо використати аннотацію + // @Override тут, так як у java не можна + // перевизначати статичні методи. + // Те, що тут відбувається, називається приховування методів. + // Більш детально: http://stackoverflow.com/questions/16313649/ + public static void main(String[] args) + { + Dog pluto = new Dog(); + pluto.makeSound(); + pluto.eat(); + pluto.printAge(); + } +} + +// Фінальні класи + +// Синтаксис оголошення фінальних класів +// <рівень доступу> final <ім’я класу> { +// // Константи і змінні +// // Оголошення методів +// } + +// Фінальні класи не можуть мати нащадків, також самі вони є останніми нащадками. +// Фінальні класи є протилежністю абстрактних у цьому плані. + +public final class SaberToothedCat extends Animal +{ + // Перевизначення методу + @Override + public void makeSound() + { + System.out.println("Гррр!"); + } +} + +// Фінальні методи +public abstract class Mammal() +{ + // Синтаксис фінальних методів: + // <модифікатор доступу> final <тип повернутого значення> <ім’я функції>(<аргументи>) + + // Фінальні методи не можуть бути перевизначені класом-нащадком, + // вони є остаточною реалізацією методу. + public final boolean isWarmBlooded() + { + return true; + } +} + + +// Тип Enum (перелік) +// +// Enum є спеціальним типом даних, який дозволяє змінним бути певною множиною +// визначених констант. Змінна має відповідати одному зі значень, що +// заздалегідь визначені для неї. Оскільки це константи, імена типів полів у enum +// задаються у верхньому регістрі. Тип «перелік» у Java задається за допомогою +// ключового слова enum. Наприклад, перелік днів тижня можна задати так: + +public enum Day { + SUNDAY, MONDAY, TUESDAY, WEDNESDAY, + THURSDAY, FRIDAY, SATURDAY +} + +// Перелік Day можна використовувати так: + +public class EnumTest { + + // Змінна того же типу, що й перелік + Day day; + + public EnumTest(Day day) { + this.day = day; + } + + public void tellItLikeItIs() { + switch (day) { + case MONDAY: + System.out.println("Понеділкі важкі."); + break; + + case FRIDAY: + System.out.println("П’ятниці краще."); + break; + + case SATURDAY: + case SUNDAY: + System.out.println("Вихідні найліпші."); + break; + + default: + System.out.println("Середина тижня так собі."); + break; + } + } + + public static void main(String[] args) { + EnumTest firstDay = new EnumTest(Day.MONDAY); + firstDay.tellItLikeItIs(); // => Понеділки важкі. + EnumTest thirdDay = new EnumTest(Day.WEDNESDAY); + thirdDay.tellItLikeItIs(); // => Середина тижня так собі. + } +} + +// Переліки набагато потужніші, ніж тут показано. +// Тіло переліків може містити методи та інші змінні. +// Дивіться більше тут: https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html + +``` + +## Додатково для читання + +Посилання, наведені нижче, дозволяють тільки зрозуміти тему. Щоб знайти конкретні приклади, використовуйте Ґуґл. + +**Офіційні посібники Oracle**: + +* [Посібник Java від Sun / Oracle](http://docs.oracle.com/javase/tutorial/index.html) + +* [Java — модифікатори доступу](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) + +* [ООП-концепції](http://docs.oracle.com/javase/tutorial/java/concepts/index.html): + * [Наслідування](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) + * [Поліморфізм](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) + * [Абстракція](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) + +* [Виключення](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) + +* [Інтерфейси](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html) + +* [параметризація](http://docs.oracle.com/javase/tutorial/java/generics/index.html) + +* [Стиль коду у Java](http://www.oracle.com/technetwork/java/codeconvtoc-136057.html) + +**Online-практика та посібники** + +* [Learneroo.com — Вивчаємо Java](http://www.learneroo.com) + +* [Codingbat.com](http://codingbat.com/java) + + +**Книжки**: + +* [Head First Java](http://www.headfirstlabs.com/books/hfjava/) + +* [Thinking in Java](http://www.mindview.net/Books/TIJ/) + +* [Objects First with Java](http://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660) + +* [Java The Complete Reference](http://www.amazon.com/gp/product/0071606300) diff --git a/uk-ua/javascript-ua.html.markdown b/uk-ua/javascript-ua.html.markdown new file mode 100644 index 00000000..397b1c5e --- /dev/null +++ b/uk-ua/javascript-ua.html.markdown @@ -0,0 +1,494 @@ +--- +language: javascript +contributors: + - ["Adam Brenecki", "http://adam.brenecki.id.au"] + - ["Ariel Krakowski", "http://www.learneroo.com"] + - ["clearsense", "https://github.com/clearsense"] +filename: javascript-uk.js +translators: + - ["Ivan", "https://github.com/IvanEh"] + - ["Serhii Maksymchuk", "https://github.com/Serg-Maximchuk"] +lang: uk-ua +--- + +JavaScript було створено в 1995 році Бренданом Айком, який працював у компанії Netscape. +Він був задуманий як проста мова сценаріїв для веб-сайтів, який би доповнював Java +для більш складних веб-застосунків. Але тісна інтеграція з веб-сторінками і +вбудована підтримка браузерами призвела до того, що JavaScript став популярніший +за власне Java. + +Зараз JavaScript не обмежується тільки веб-браузером. Наприклад, Node.js, +програмна платформа, що дозволяє виконувати JavaScript код з використанням +рушія V8 від браузера Google Chrome, стає все більш і більш популярною. + +```js +// С-подібні коментарі. Однорядкові коментарі починаються з двох символів /(слеш) +/* а багаторядкові коментарі починаються з послідовності слеша та зірочки і + закінчуються символами зірочка-слеш */ + +//Інструкції можуть закінчуватися крапкою з комою ; +doStuff(); + +// ... але не обов’язково, тому що крапка з комою автоматично вставляється на +// місці символу нового рядка, крім деяких випадків. +doStuff() + +// Ми завжди будемо використовувати крапку з комою в цьому посібнику, тому що ці +// винятки можуть призвести до неочікуваних результатів + +/////////////////////////////////// +// 1. Числа, Рядки і Оператори + +// В JavaScript числа зберігаються тільки в одному форматі (64-bit IEEE 754 double) +// Цей тип має 52-бітну мантису, якої достатньо для збереження чисел з +// точністю до 9✕10¹⁵. +3; // = 3 +1.5; // = 1.5 + +// Деякі прості арифметичні операції працють так, як ми очікуємо. +1 + 1; // = 2 +0.1 + 0.2; // = 0.30000000000000004 (а деякі - ні) +8 - 1; // = 7 +10 * 2; // = 20 +35 / 5; // = 7 + +// В тому числі ділення з остачею +5 / 2; // = 2.5 + +// В JavaScript є побітові операції; коли ви виконуєте таку операцію, +// число з плаваючою точкою переводиться в ціле зі знаком +// довжиною *до* 32 розрядів. +1 << 2; // = 4 + +// Пріоритет у виразах можна задати явно круглими дужками +(1 + 3) * 2; // = 8 + +// Є три спеціальні значення, які не є реальними числами: +Infinity; // "нескінченність", наприклад, як результат ділення на 0 +-Infinity; // "мінус нескінченність", як результат ділення від’ємного числа на 0 +NaN; // "не число", наприклад, ділення 0/0 + +// Логічні типи +true; +false; + +// Рядки створюються за допомогою подвійних та одинарних лапок +'абв'; +"Привіт, світе!"; + +// Для логічного заперечення використовується знак оклику. +!true; // = false +!false; // = true + +// Строга рівність === +1 === 1; // = true +2 === 1; // = false + +// Строга нерівність !== +1 !== 1; // = false +2 !== 1; // = true + +// Інші оператори порівняння +1 < 10; // = true +1 > 10; // = false +2 <= 2; // = true +2 >= 2; // = true + +// Рядки об’єднуються за допомогою оператора + +"hello, " + "world!"; // = "hello, world!" + +// І порівнюються за допомогою > та < +"a" < "b"; // = true + +// Перевірка на рівність з приведнням типів здійснюється оператором == +"5" == 5; // = true +null == undefined; // = true + +// ... але приведення не виконується при === +"5" === 5; // = false +null === undefined; // = false + +// ... приведення типів може призвести до дивних результатів +13 + !0; // 14 +"13" + !0; // '13true' + +// Можна отримати доступ до будь-якого символа рядка за допомгою charAt +"Це рядок".charAt(0); // = 'Ц' + +// ... або використати метод substring, щоб отримати більший кусок +"Hello, world".substring(0, 5); // = "Hello" + +// length - це не метод, а поле +"Hello".length; // = 5 + +// Типи null и undefined +null; // навмисна відсутність результату +undefined; // використовується для позначення відсутності присвоєного значення + +// false, null, undefined, NaN, 0 та "" — хиба; все інше - істина. +// Потрібно відмітити, що 0 — це хиба, а "0" — істина, не зважаючи на те що: +// 0 == "0". + +/////////////////////////////////// +// 2. Змінні, Масиви, Об’єкти + +// Змінні оголошуються за допомогою ключового слова var. JavaScript — мова з +// динамічною типізацією, тому не потрібно явно вказувати тип. Для присвоєння +// значення змінної використовується символ = +var someVar = 5; + +// якщо пропустити слово var, ви не отримаєте повідомлення про помилку, ... +someOtherVar = 10; + +// ... але вашу змінну буде створено в глобальному контексті, а не там, де +// ви її оголосили + +// Змінні, які оголошені без присвоєння, автоматично приймають значення undefined +var someThirdVar; // = undefined + +// У математичних операцій є скорочені форми: +someVar += 5; // як someVar = someVar + 5; +someVar *= 10; // тепер someVar = 100 + +// Інкремент і декремент +someVar++; // тепер someVar дорівнює 101 +someVar--; // а зараз 100 + +// Масиви — це нумеровані списки, які зберігають значення будь-якого типу. +var myArray = ["Привіт", 45, true]; + +// Доступ до елементів можна отримати за допомогою синтаксиса з квадратними дужками +// Індексація починається з нуля +myArray[1]; // = 45 + +// Масиви в JavaScript змінюють свою довжину при додаванні нових елементів +myArray.push("Привіт"); +myArray.length; // = 4 + +// Додавання і редагування елементів +myArray[3] = "світ"; + +// Об’єкти в JavaScript схожі на словники або асоціативні масиви в інших мовах +var myObj = {key1: "Hello", key2: "World"}; + +// Ключі - це рядки, але лапки не обов’язкі, якщо ключ задовольняє +// правилам формування назв змінних. Значення можуть бути будь-яких типів. +var myObj = {myKey: "myValue", "my other key": 4}; + +// Атрибути можна отримати використовуючи квадратні дужки +myObj["my other key"]; // = 4 + +// Або через точку, якщо ключ є правильним ідентифікатором +myObj.myKey; // = "myValue" + +// Об’єкти можна динамічно змінювати й додавати нові поля +myObj.myThirdKey = true; + +// Коли ви звертаєтесь до поля, що не існує, ви отримуєте значення undefined +myObj.myFourthKey; // = undefined + +/////////////////////////////////// +// 3. Керуючі конструкції + +// Синтаксис для цього розділу майже такий самий, як у Java + +// Умовна конструкція +var count = 1; +if (count == 3) { + // виконується, якщо count дорівнює 3 +} else if (count == 4) { + // .. +} else { + // ... +} + +// ... цикл while. +while (true){ + // Нескінченний цикл! +} + +// Цикл do-while такий самий, як while, але завжди виконується принаймні один раз. +var input +do { + input = getInput(); +} while (!isValid(input)) + +// цикл for такий самий, як в C і Java: +// ініціалізація; умова; крок. +for (var i = 0; i < 5; i++) { + // виконається 5 разів +} + +// && — логічне І, || — логічне АБО +if (house.size == "big" && house.color == "blue") { + house.contains = "bear"; +} +if (color == "red" || color == "blue") { + // колір червоний або синій +} + +// && та || використовують скорочене обчислення +// тому їх можна використовувати для задання значень за замовчуванням. +var name = otherName || "default"; + +// Оператор switch виконує перевірку на рівність за допомогою === +// використовуйте break, щоб призупити виконання наступного case, +grade = 4; +switch (grade) { + case 5: + console.log("Відмінно"); + break; + case 4: + console.log("Добре"); + break; + case 3: + console.log("Можна краще"); + break; + default: + console.log("Погано!"); + break; +} + + +/////////////////////////////////// +// 4. Функції, область видимості і замикання + +// Функції в JavaScript оголошуються за допомогою ключового слова function. +function myFunction(thing) { + return thing.toUpperCase(); +} +myFunction("foo"); // = "FOO" + +// Зверніть увагу, що значення яке буде повернено, повинно починатися на тому ж +// рядку, що і ключове слово return, інакше завжди буде повертатися значення undefined +// через автоматичну вставку крапки з комою +function myFunction() +{ + return // <- крапка з комою вставляється автоматично + { + thisIsAn: 'object literal' + } +} +myFunction(); // = undefined + +// В JavaScript функції - це об`єкти першого класу, тому вони можуть присвоюватися +// іншим змінним і передаватися іншим функціям, наприклад, щоб визначити обробник +// події. +function myFunction() { + // код буде виконано через 5 сек. +} +setTimeout(myFunction, 5000); +// setTimeout не є частиною мови, але реалізований в браузерах і Node.js + +// Функції не обов’язково мають мати ім’я при оголошенні — ви можете написати +// анонімну функцію як аргумент іншої функції +setTimeout(function() { + // Цей код буде виконано через п’ять секунд +}, 5000); + +// В JavaScript реалізована концепція області видимості; функції мають свою +// область видимості, а інші блоки не мають +if (true) { + var i = 5; +} +i; // = 5, а не undefined, як це звичайно буває в інших мовах + +// Така особливість призвела до шаблону "анонімних функцій, які викликають самих себе" +// що дозволяє уникнути проникнення змінних в глобальну область видимості +(function() { + var temporary = 5; + // об’єкт window зберігає глобальний контекст; таким чином ми можемо також додавати + // змінні до глобальної області + window.permanent = 10; +})(); +temporary; // повідомлення про помилку ReferenceError +permanent; // = 10 + +// Замикання - один з найпотужніших інструментів JavaScript. Якщо функція визначена +// всередині іншої функції, то внутрішня функція має доступ до змінних зовнішньої +// функції навіть після того, як код буде виконуватися поза контекстом зовнішньої функції +function sayHelloInFiveSeconds(name) { + var prompt = "Привіт, " + name + "!"; + // Внутрішня функція зберігається в локальній області так, + // ніби функція була оголошена за допомогою ключового слова var + function inner() { + alert(prompt); + } + setTimeout(inner, 5000); + // setTimeout асинхронна, тому функція sayHelloInFiveSeconds одразу завершиться, + // після чого setTimeout викличе функцію inner. Але функція inner + // «замкнута» кругом sayHelloInFiveSeconds, вона все рівно має доступ до змінної prompt +} +sayHelloInFiveSeconds("Адам"); // Через 5 с відкриється вікно «Привіт, Адам!» + +/////////////////////////////////// +// 5. Об’єкти: конструктори і прототипи + +// Об’єкти можуть містити функції +var myObj = { + myFunc: function() { + return "Hello, world!"; + } +}; +myObj.myFunc(); // = "Hello, world!" + +// Функції, що прикріплені до об’єктів мають доступ до поточного об’єкта за +// допомогою ключового слова this. +myObj = { + myString: "Hello, world!", + myFunc: function() { + return this.myString; + } +}; +myObj.myFunc(); // = "Hello, world!" + +// Значення this залежить від того, як функція викликається +// а не від того, де вона визначена. Таким чином наша функція не працює, якщо +// вона викликана не в контексті об’єкта +var myFunc = myObj.myFunc; +myFunc(); // = undefined + +// Функція може бути присвоєна іншому об’єкту. Тоді вона матиме доступ до +// цього об’єкта через this +var myOtherFunc = function() { + return this.myString.toUpperCase(); +} +myObj.myOtherFunc = myOtherFunc; +myObj.myOtherFunc(); // = "HELLO, WORLD!" + +// Контекст виконання функції можна задати за допомогою сall або apply +var anotherFunc = function(s) { + return this.myString + s; +} +anotherFunc.call(myObj, " Hello!"); // = "Hello, world! Hello!" + +// Функцiя apply приймає в якості аргументу масив +anotherFunc.apply(myObj, [" Hello!"]); // = "Hello, world! Hello!" + +// apply можна використати, коли функція працює послідовністю аргументів, а +// ви хочете передати масив +Math.min(42, 6, 27); // = 6 +Math.min([42, 6, 27]); // = NaN (Ой-ой!) +Math.min.apply(Math, [42, 6, 27]); // = 6 + +// Але call і apply — тимчасові. Коли ми хочемо зв’язати функцію і об’єкт +// використовують bind +var boundFunc = anotherFunc.bind(myObj); +boundFunc(" Hello!"); // = "Hello world, Hello!" + +// Bind можна використати для задання аргументів +var product = function(a, b) { return a * b; } +var doubler = product.bind(this, 2); +doubler(8); // = 16 + +// Коли ви викликаєте функцію за допомогою ключового слова new, створюється новий об’єкт, +// доступний функції за допомогою this. Такі функції називають конструкторами. +var MyConstructor = function() { + this.myNumber = 5; +} +myNewObj = new MyConstructor(); // = {myNumber: 5} +myNewObj.myNumber; // = 5 + +// У кожного об’єкта є прототип. Коли ви звертаєтесь до поля, яке не існує в цьому +// об’єкті, інтерпретатор буде шукати поле в прототипі + +// Деякі реалізації мови дозволяють отримати доступ до прототипа об’єкта через +// "магічну" властивість __proto__. Це поле не є частиною стандарта, але існують +// стандартні способи використання прототипів, які ми побачимо пізніше +var myObj = { + myString: "Hello, world!" +}; +var myPrototype = { + meaningOfLife: 42, + myFunc: function() { + return this.myString.toLowerCase() + } +}; + +myObj.__proto__ = myPrototype; +myObj.meaningOfLife; // = 42 + +// Аналогічно для функцій +myObj.myFunc(); // = "hello, world!" + +// Якщо інтерпретатор не знайде властивості в прототипі, то він продовжить пошук +// в прототипі прототипа і так далі +myPrototype.__proto__ = { + myBoolean: true +}; +myObj.myBoolean; // = true + +// Кожен об’єкт зберігає посилання на свій прототип. Це значить, що ми можемо змінити +// наш прототип, і наші зміни будуть всюди відображені. +myPrototype.meaningOfLife = 43; +myObj.meaningOfLife; // = 43 + +// Ми сказали, що властивість __proto__ нестандартна, і нема ніякого стандартного способу +// змінити прототип об’єкта, що вже існує. Але є два способи створити новий об’єкт із заданим +// прототипом + +// Перший спосіб — це Object.create, який з’явився в JavaScript недавно, +// а тому в деяких реалізаціях може бути недоступним. +var myObj = Object.create(myPrototype); +myObj.meaningOfLife; // = 43 + +// Другий спосіб: у конструкторів є властивість з іменем prototype. Це *не* +// прототип функції-конструктора, це прототип для нових об’єктів, які будуть створені +// цим конструктором і ключовим словом new. +MyConstructor.prototype = { + myNumber: 5, + getMyNumber: function() { + return this.myNumber; + } +}; +var myNewObj2 = new MyConstructor(); +myNewObj2.getMyNumber(); // = 5 +myNewObj2.myNumber = 6 +myNewObj2.getMyNumber(); // = 6 + +// У вбудованих типів(рядок, число) теж є конструктори, які створють еквівалентні +// об’єкти-обгортки +var myNumber = 12; +var myNumberObj = new Number(12); +myNumber == myNumberObj; // = true + +// Але вони не ідентичні +typeof myNumber; // = 'number' +typeof myNumberObj; // = 'object' +myNumber === myNumberObj; // = false + +// Об’єкти-обгортки і вбудовані типи мають спільні прототипи, тому +// ви можете розширити функціонал рядків: +String.prototype.firstCharacter = function() { + return this.charAt(0); +} +"abc".firstCharacter(); // = "a" + +// Такий прийом часто використовуються в поліфілах, які реалізують нові можливості +// JavaScript в старій реалізації мови, так що вони можуть бути використані в старих +// середовищах + +// Наприклад, Object.create доступний не у всіх реалізаціях, але ми можемо +// використати функції за допомогою наступного поліфіла: +if (Object.create === undefined) { // не перезаписуємо метод, якщо він існує + Object.create = function(proto) { + // Створюємо правильний конструктор з правильним прототипом + var Constructor = function(){}; + Constructor.prototype = proto; + + return new Constructor(); + } +} +``` + +## Що почитати + +* [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript +* [2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript +* [3]: https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core +* [4]: http://www.learneroo.com/modules/64/nodes/350 +* [5]: http://bonsaiden.github.io/JavaScript-Garden/ +* [6]: http://www.amazon.com/gp/product/0596805527/ +* [7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript +* [8]: http://eloquentjavascript.net/ +* [9]: http://jstherightway.org/ diff --git a/uk-ua/json-ua.html.markdown b/uk-ua/json-ua.html.markdown new file mode 100644 index 00000000..c9a3d3fb --- /dev/null +++ b/uk-ua/json-ua.html.markdown @@ -0,0 +1,73 @@ +--- +language: json +filename: learnjson-ua.json +contributors: + - ["Anna Harren", "https://github.com/iirelu"] + - ["Marco Scannadinari", "https://github.com/marcoms"] +translators: + - ["Ehreshi Ivan", "https://github.com/IvanEh"] + - ["Serhii Maksymchuk", "https://github.com/Serg-Maximchuk"] +lang: uk-ua +--- + +JSON - це надзвичайно простий формат обміну даними. Згідно з [json.org](http://json.org), для людей він легкий в написанні і читанні, а для комп’ютерів в розборі та генерації. + +JSON підтримує наступні структури даних: + +* Колекція пар ключ/значення (`{ "ключ": "значення" }`). У різних мовах програмування реалізується як об’єкт, запис, структура, словник, хеш-таблиця, іменований список або асоціативний масив. +* Впорядкований список значень (`[ "елемент0", "елемент1" ]`). У різних мовах програмування реалізується як масив, вектор, список або послідовність. +* Рядки: `"привіт"`, `"\"Лапки\""`, `"\u0abe"`, `"Новий рядок.\n"` +* Числа: `23`, `0.11`, `12e10`, `3.141e-10`, `1.23e+4` +* Інші: `true`, `false`, `null` + +JSON в чистій формі не містить коментарів, але більшість парсерів підтримують коментарі в C-стилі (`//`, `/* */`). Деякі парсери також не звертають уваги на кому після останнього поля, але їх варто уникати для кращої сумісності. + +```json +{ + "ключ": "значення", + + "ключі": "завжди мають бути обгорнуті в подвійні лапки", + "числа": 0, + "рядки": "Пρивіт, світe. Допускаються всі unicode-символи разом із \"екрануванням\".", + "логічний тип": true, + "нічого": null, + + "велике число": 1.2e+100, + + "об’єкти": { + "коментар": "Більшість ваших структур будуть складатися з об’єктів", + + "масив": [0, 1, 2, 3, "масиви можуть містити будь-які типи", 5], + + "інший об’єкт": { + "коментар": "Об’єкти можуть містити інші об’єкти. Це дуже корисно." + } + }, + + "безглуздя": [ + { + "джерело калію": ["банани"] + }, + [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, "нео"], + [0, 0, 0, 1] + ] + ], + + "альтернативний стиль": { + "коментар": "Гляньте!" + , "позиція коми": "неважлива, коректно якщо вона знаходиться перед наступним полем" + , "інший коментар": "класно" + }, + + "Це було не довго": "І ви впорались! Тепер ви знаєте все про JSON." +} + +Одиничний масив значень теж є правильним JSON + +[1, 2, 3, "text", true] + + +``` diff --git a/uk-ua/ruby-ua.html.markdown b/uk-ua/ruby-ua.html.markdown new file mode 100644 index 00000000..74346dfe --- /dev/null +++ b/uk-ua/ruby-ua.html.markdown @@ -0,0 +1,625 @@ +--- +language: ruby +filename: learnruby-ua.rb +contributors: + - ["David Underwood", "http://theflyingdeveloper.com"] + - ["Joel Walden", "http://joelwalden.net"] + - ["Luke Holder", "http://twitter.com/lukeholder"] + - ["Tristan Hume", "http://thume.ca/"] + - ["Nick LaMuro", "https://github.com/NickLaMuro"] + - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"] + - ["Ariel Krakowski", "http://www.learneroo.com"] + - ["Dzianis Dashkevich", "https://github.com/dskecse"] + - ["Levi Bostian", "https://github.com/levibostian"] + - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gabriel Halley", "https://github.com/ghalley"] + - ["Persa Zula", "http://persazula.com"] + - ["Jake Faris", "https://github.com/farisj"] +translators: + - ["Serhii Maksymchuk", "https://github.com/Serg-Maximchuk"] +lang: uk-ua +--- + +Rubi — це інтерпретована, повністю об'єктно-орієнтована мова програмування з чіткою динамічною типізацією. + +```ruby +# Це коментар + +=begin +Це багаторядковий коментар +Ніхто їх не використовує +Тобі теж не варто +=end + +# В першу чергу: все являється об’єктом. + +# Числа це об’єкти + +3.class #=> Fixnum + +3.to_s #=> "3" + + +# Базова арифметика +1 + 1 #=> 2 +8 - 1 #=> 7 +10 * 2 #=> 20 +35 / 5 #=> 7 +2**5 #=> 32 +5 % 3 #=> 2 + +# Побітові оператори +3 & 5 #=> 1 +3 | 5 #=> 7 +3 ^ 5 #=> 6 + +# Арифметика це просто синтаксичний цукор +# для виклику методу об’єкта +1.+(3) #=> 4 +10.* 5 #=> 50 + +# Спеціальні значення теж об’єкти +nil # еквівалентно null в інших мовах +true # істина +false # хиба + +nil.class #=> NilClass +true.class #=> TrueClass +false.class #=> FalseClass + +# Рівність +1 == 1 #=> true +2 == 1 #=> false + +# Нерівність +1 != 1 #=> false +2 != 1 #=> true + +# Окрім власне false, nil це ще одне "хибне" значення + +!nil #=> true +!false #=> true +!0 #=> false + +# Інші порівняння +1 < 10 #=> true +1 > 10 #=> false +2 <= 2 #=> true +2 >= 2 #=> true + +# Комбінований оператор порівняння +1 <=> 10 #=> -1 +10 <=> 1 #=> 1 +1 <=> 1 #=> 0 + +# Логічні оператори +true && false #=> false +true || false #=> true +!true #=> false + +# Є альтернативні версії логічних операторів з набагато меншим +# прецедентом. Вони використовуються в конструкціях з контролем +# виконання ланцюга виразів які повертають булевий результат. + +# `do_something_else` викликається лише якщо `do_something` повертає true. +do_something() and do_something_else() +# `log_error` викликається лише якщо `do_something` повертає false. +do_something() or log_error() + + +# Strings це об’єкти + +'Я — рядок'.class #=> String +"Я теж рядок".class #=> String + +placeholder = 'використовувати інтерполяцію рядків' +"Я можу #{placeholder} коли користуюсь рядками в подвійних лапках" +#=> "Я можу використовувати інтерполяцію рядків коли користуюсь рядками в подвійних лапках" + +# Варто надавати перевагу рядкам в одинарних лапках де це можливо +# Рядки в подвійних лапках викликають додаткові внутрішні обчислення + +# Об’єднуйте рядки, але не з числами +'hello ' + 'world' #=> "hello world" +'hello ' + 3 #=> TypeError: can't convert Fixnum into String +'hello ' + 3.to_s #=> "hello 3" + +# Об’єднуйте рядки з операторами +'hello ' * 3 #=> "hello hello hello " + +# Додавання до рядка +'hello' << ' world' #=> "hello world" + +# Вивести рядок з переходом на новий рядок вкінці +puts "Я надрукований!" +#=> Я надрукований! +#=> nil + +# Вивести рядок без переходу на новий +print "Я надрукований!" +#=> Я надрукований! => nil + +# Змінні +x = 25 #=> 25 +x #=> 25 + +# Зверніть увагу, оператор присвоєння повертає присвоєне значення +# Отже можна робити одночасне присвоєння кількох змінних: +x = y = 10 #=> 10 +x #=> 10 +y #=> 10 + +# Для назв змінних використовується зміїний_регістр +snake_case = true + +# Використовуйте назви змінних які їх характеризують +path_to_project_root = '/good/name/' +path = '/bad/name/' + +# Символи (теж об’єкти) +# Символи є незмінними константами багаторазового використання, внутрішньо +# представлені цілочисельним значенням. Вони часто використовуються замість +# рядків щоб ефективно передати конкретні, значущі значення. + +:pending.class #=> Symbol + +status = :pending + +status == :pending #=> true + +status == 'pending' #=> false + +status == :approved #=> false + +# Масиви + +# Ось масив +array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] + +# Масиви можуть містити елементи різних типів +[1, 'hello', false] #=> [1, "hello", false] + +# Масиви можуть бути проіндексовані +# З початку +array[0] #=> 1 +array.first #=> 1 +array[12] #=> nil + +# Як і арифметика, доступ до елемента масиву у вигляді [індекс] — це лише +# синтаксичний цукор виклику методу [] об’єкта +array.[] 0 #=> 1 +array.[] 12 #=> nil + +# З кінця +array[-1] #=> 5 +array.last #=> 5 + +# З початковим індексом та довжиною +array[2, 3] #=> [3, 4, 5] + +# Реверс масиву +a=[1,2,3] +a.reverse! #=> [3,2,1] + +# Елементи масиву за діапазоном індексів +array[1..3] #=> [2, 3, 4] + +# Додавати елементи в масив можна так: +array << 6 #=> [1, 2, 3, 4, 5, 6] +# Або так: +array.push(6) #=> [1, 2, 3, 4, 5, 6] + +# Перевірити чи масив містить елемент +array.include?(1) #=> true + +# Хеш — це масив пар ключ/значення. +# Хеш оголошується з використанням фігурних дужок: +hash = { 'color' => 'green', 'number' => 5 } + +hash.keys #=> ['color', 'number'] + +# Значення в хеші може бути швидко знайдене за ключем: +hash['color'] #=> 'green' +hash['number'] #=> 5 + +# Запит значення за неіснуючим ключем повертає nil: +hash['nothing here'] #=> nil + +# Починаючи з Ruby 1.9 з’явився спеціальний синтаксис при використанні +# символів в якості ключів: +new_hash = { defcon: 3, action: true } + +new_hash.keys #=> [:defcon, :action] + +# Перевірка наявності ключів та значень в хеші +new_hash.key?(:defcon) #=> true +new_hash.value?(3) #=> true + +# Хеші та масиви — перелічувальні типи даних +# Вони мають багато корисних методів, такі як each, map, count, та інші. + +# Оператор вибору "if" +if true + 'якщо' +elsif false + 'інакше якщо, опціонально' +else + 'інакше, також опціонально' +end + +# Оператор циклу "for" +for counter in 1..5 + puts "ітерація #{counter}" +end +#=> ітерація 1 +#=> ітерація 2 +#=> ітерація 3 +#=> ітерація 4 +#=> ітерація 5 + +# Проте, ніхто не використовує "for" в циклах. +# Замість цього варто використовувати метод "each" і передати йому блок. +# Блок — це відокремлений код який можна передати в метод, наприклад в "each". +# Це аналог лямбда-виразів, анонімних функцій або замикань в інших мовах програмування. + +# Метод "each" для діапазону запускає блок один раз для кожного елементу діапазону. +# Лічильник передається блоку в якості аргументу. + +# Виклик методу "each" з блоком виглядає наступним чином: +(1..5).each do |counter| + puts "ітерація #{counter}" +end +#=> ітерація 1 +#=> ітерація 2 +#=> ітерація 3 +#=> ітерація 4 +#=> ітерація 5 + +# Також можна загорнути блок в фігурні дужки: +(1..5).each { |counter| puts "ітерація #{counter}" } + +# Вміст структур даних також може бути ітерований використовуючи метод "each": +array.each do |element| + puts "#{element} є елементом масиву" +end +hash.each do |key, value| + puts "#{key} є #{value}" +end + +# Якщо є необхідність індексувати ітерацію, можна використати метод "each_with_index": +array.each_with_index do |element, index| + puts "#{element} під номером #{index} в масиві" +end + +# Оператор циклу "while" +counter = 1 +while counter <= 5 do + puts "ітерація #{counter}" + counter += 1 +end +#=> ітерація 1 +#=> ітерація 2 +#=> ітерація 3 +#=> ітерація 4 +#=> ітерація 5 + +# Є й інші корисні функції для циклів, такі як "map", "reduce", +# "inject" та інші. Наприклад "map" в циклі проходить по масиву, +# виконує над елементами операцію(-ї) в блоці і повертає абсолютно +# новий масив. +array = [1,2,3,4,5] +doubled = array.map do |element| + element * 2 +end +puts doubled +#=> [2,4,6,8,10] +puts array +#=> [1,2,3,4,5] + +# Оператор множинного вибору +grade = 'B' + +case grade +when 'A' + puts 'Відмінно!' +when 'B' + puts 'Пощастить наступного разу' +when 'C' + puts 'Ти можеш краще' +when 'D' + puts 'Майже четвірка' +when 'E' + puts 'Випросив' +when 'F' + puts 'Не здав!' +else + puts 'Інша система оцінювання, так?' +end +#=> "Пощастить наступного разу" + +# Оператор "case" також може використовувати діапазон: +grade = 82 +case grade +when 90..100 + puts 'Ура!' +when 80...90 + puts 'Хороша робота' +when 60...80 + puts 'Ну, хоч щось' +else + puts 'Не здав!' +end +#=> "Хороша робота" + +# Обробка вийнятків: +begin + # код з можливим вийнятком + raise NoMemoryError, 'Ви використали всю пам’ять.' +rescue NoMemoryError => exception_variable + puts 'Помилка NoMemoryError', exception_variable +rescue RuntimeError => other_exception_variable + puts 'Помилка RuntimeError' +else + puts 'Цей код запуститься якщо вийнятків не було взагалі' +ensure + puts 'Цей код запуститься в будь-якому випадку' +end + +# Функції + +def double(x) + x * 2 +end + +# Функції (і всі блоки) неявно повертають значення останнього виразу +double(2) #=> 4 + +# Дужки не є обов’язковими якщо результат недвозначний +double 3 #=> 6 + +double double 3 #=> 12 + +def sum(x, y) + x + y +end + +# Аргументи методів розділяються комою +sum 3, 4 #=> 7 + +sum sum(3, 4), 5 #=> 12 + +# yield +# Всі методи мають неявний, опціональний параметр, який +# можна викликат за допомогою ключового слова 'yield' +def surround + puts '{' + yield + puts '}' +end + +surround { puts 'привіт світ' } + +# { +# привіт світ +# } + + +# Ви можете передати блок у функцію +# "&" позначає посилання на блок +def guests(&block) + block.call 'some_argument' +end + +# Ви можете передати список аргументів, вони будуть перетворені в масив +# Для цього існує оператор ("*") +def guests(*array) + array.each { |guest| puts guest } +end + +# Якщо метод повертає масив, ви можете використати деструктуризацію +def foods + ['млинці', 'бутерброд', 'лазанья'] +end +breakfast, lunch, dinner = foods +breakfast #=> 'млинці' +dinner #=> 'лазанья' + +# Зазвичай методи які повертають булевий результат закінчуються знаком питання +5.even? # false +5.odd? # true + +# І якщо метод закінчується знаком оклику, то він робить щось деструктивне +# типу зміни отриманого аргументу. Багато методів мають версію з "!" які +# змінюють аргумент, та без "!" що повертають новий об’єкт +company_name = "Дандер Міфлін" +company_name.upcase #=> "ДАНДЕР МІФЛІН" +company_name #=> "Дандер Міфлін" +company_name.upcase! # змінна company_name зміниться цього разу! +company_name #=> "ДАНДЕР МІФЛІН" + + +# Клас оголошується ключовим словом class +class Human + + # Змінна класу. Вона поширюється на всі екземпляри цього класу. + @@species = 'Homo sapiens' + + # Основний ініціалізатор + def initialize(name, age = 0) + # Призначення аргументу "name" до однойменної змінної екземпляру + @name = name + # Якщо аргумент "age" не заданий, то йому буде присвоєно дефолтне значення + # зі списку аргументів + @age = age + end + + # Метод-сетер + def name=(name) + @name = name + end + + # Метод-ґетер + def name + @name + end + + # Функціональність вище може бути інкапсульована використовуючи метод attr_accessor: + attr_accessor :name + + # Ґетери і сетери можуть бути створені індивідуально, наприклад: + attr_reader :name + attr_writer :name + + # Метод класу позначається ключовим словом "self", щоб відрізнити від + # методів екземпляра класу. + # Він може бути викликаний лише в класі, але не в екземплярі. + def self.say(msg) + puts msg + end + + def species + @@species + end +end + + +# Ініціалізуємо клас +jim = Human.new('Джим Галперт') + +dwight = Human.new('Дуайт Шрут') + +# Викличемо кілька методів +jim.species #=> "Homo sapiens" +jim.name #=> "Джим Галперт" +jim.name = "Джим Галперт II" #=> "Джим Галперт II" +jim.name #=> "Джим Галперт II" +dwight.species #=> "Homo sapiens" +dwight.name #=> "Дуайт Шрут" + +# Викликати метод класу +Human.say('Привіт') #=> "Привіт" + +# Область видимості змінних визначається способом оголошення імені змінної. +# Змінні, що починаються на "$" мають глобальну область видимості. +$var = "Я глобальна змінна" +defined? $var #=> "global-variable" + +# Зміннні, що опчинають на "@" мають область видимості екзкмпляра +@var = "Я змінна екземпляра" +defined? @var #=> "instance-variable" + +# Змінні, що починаються на "@@" мають область видимості класу +@@var = "Я змінна класу" +defined? @@var #=> "class variable" + +# Змінні, що починаються з великої букви, є константами +Var = "Я константа" +defined? Var #=> "constant" + +# Клас теж об’єкт. Тому клас може мати змінні екземпляра. +# Змінна класу поширюється між класом і всіма його нащадками. + +# Базовий клас +class Human + @@foo = 0 + + def self.foo + @@foo + end + + def self.foo=(value) + @@foo = value + end +end + +# Похідний клас (нащадок) +class Worker < Human +end + +Human.foo # 0 +Worker.foo # 0 + +Human.foo = 2 # 2 +Worker.foo # 2 + +# Змінна екземпляра класу не поширюється між класами-нащадками. +class Human + @bar = 0 + + def self.bar + @bar + end + + def self.bar=(value) + @bar = value + end +end + +class Doctor < Human +end + +Human.bar # 0 +Doctor.bar # nil + +module ModuleExample + def foo + 'foo' + end +end + +# Включення модулів додає їхні методи до екземплярів класу +# Розширення модулів додає їхні методи в сам клас + +class Person + include ModuleExample +end + +class Book + extend ModuleExample +end + +Person.foo # => NoMethodError: undefined method `foo' for Person:Class +Person.new.foo # => 'foo' +Book.foo # => 'foo' +Book.new.foo # => NoMethodError: undefined method `foo' + +# Колбек виконується при включенні і розширенні модуля + +module ConcernExample + def self.included(base) + base.extend(ClassMethods) + base.send(:include, InstanceMethods) + end + + module ClassMethods + def bar + 'bar' + end + end + + module InstanceMethods + def qux + 'qux' + end + end +end + +class Something + include ConcernExample +end + +Something.bar # => 'bar' +Something.qux # => NoMethodError: undefined method `qux' +Something.new.bar # => NoMethodError: undefined method `bar' +Something.new.qux # => 'qux' +``` + +## Додаткові ресурси + +- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - A variant of this reference with in-browser challenges. +- [An Interactive Tutorial for Ruby](https://rubymonk.com/) - Learn Ruby through a series of interactive tutorials. +- [Official Documentation](http://ruby-doc.org/core) +- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/) +- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - An older [free edition](http://ruby-doc.com/docs/ProgrammingRuby/) is available online. +- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - A community-driven Ruby coding style guide. +- [Try Ruby](http://tryruby.org) - Learn the basic of Ruby programming language, interactive in the browser. |