diff options
Diffstat (limited to 'ru-ru')
| -rw-r--r-- | ru-ru/.directory | 4 | ||||
| -rw-r--r-- | ru-ru/bash-ru.html.markdown | 293 | ||||
| -rw-r--r-- | ru-ru/brainfuck-ru.html.markdown | 2 | ||||
| -rw-r--r-- | ru-ru/clojure-ru.html.markdown | 2 | ||||
| -rw-r--r-- | ru-ru/css-ru.html.markdown | 250 | ||||
| -rw-r--r-- | ru-ru/d-ru.html.markdown | 753 | ||||
| -rw-r--r-- | ru-ru/erlang-ru.html.markdown | 2 | ||||
| -rw-r--r-- | ru-ru/java-ru.html.markdown | 2 | ||||
| -rw-r--r-- | ru-ru/javascript-ru.html.markdown | 5 | ||||
| -rw-r--r-- | ru-ru/objective-c-ru.html.markdown | 659 | ||||
| -rw-r--r-- | ru-ru/perl-ru.html.markdown | 195 | ||||
| -rw-r--r-- | ru-ru/php-ru.html.markdown | 65 | ||||
| -rw-r--r-- | ru-ru/python-ru.html.markdown | 7 | ||||
| -rw-r--r-- | ru-ru/python3-ru.html.markdown | 2 | ||||
| -rw-r--r-- | ru-ru/ruby-ru.html.markdown | 1 | 
15 files changed, 2121 insertions, 121 deletions
| diff --git a/ru-ru/.directory b/ru-ru/.directory new file mode 100644 index 00000000..4d20336b --- /dev/null +++ b/ru-ru/.directory @@ -0,0 +1,4 @@ +[Dolphin] +SortRole=size +Timestamp=2015,10,31,18,6,13 +Version=3 diff --git a/ru-ru/bash-ru.html.markdown b/ru-ru/bash-ru.html.markdown new file mode 100644 index 00000000..5e99afc2 --- /dev/null +++ b/ru-ru/bash-ru.html.markdown @@ -0,0 +1,293 @@ +--- +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: +    - ["Andrey Samsonov", "https://github.com/kryzhovnik"] +    - ["Andre Polykanine", "https://github.com/Oire"] +filename: LearnBash-ru.sh +lang: ru-ru +--- + +Bash - это командная оболочка unix (unix shell), которая распространялась как оболочка для операционной системы GNU и используется в качестве оболочки по умолчанию для Linux и Mac OS X. +Почти все нижеприведенные примеры могут быть частью shell-скриптов или исполнены напрямую в shell. + +[Подробнее.](http://www.gnu.org/software/bash/manual/bashref.html) + +```bash +#!/bin/bash +# Первая строка скрипта - это shebang, который сообщает системе, как исполнять +# этот скрипт: http://en.wikipedia.org/wiki/Shebang_(Unix) +# Как вы уже поняли, комментарии начинаются с #. Shebang - тоже комментарий. + +# Простой пример hello world: +echo Hello world! + +# Отдельные команды начинаются с новой строки или разделяются точкой с запятой: +echo 'Это первая строка'; echo 'Это вторая строка' + +# Вот так объявляется переменная: +VARIABLE="Просто строка" + +# но не так: +VARIABLE = "Просто строка" +# Bash решит, что VARIABLE - это команда, которую он должен исполнить, +# и выдаст ошибку, потому что не сможет найти ее. + +# и не так: +VARIABLE= 'Просто строка' +# Тут Bash решит, что 'Просто строка' - это команда, которую он должен исполнить, +# и выдаст ошибку, потому что не сможет найти такой команды +# (здесь 'VARIABLE=' выглядит как присвоение значения переменной, +# но только в контексте исполнения команды 'Просто строка'). + +# Использование переменой: +echo $VARIABLE +echo "$VARIABLE" +echo '$VARIABLE' +# Когда вы используете переменную - присваиваете, экспортируете и т.д. - +# пишите её имя без $. А для получения значения переменной используйте $. +# Заметьте, что ' (одинарные кавычки) не раскрывают переменные в них. + +# Подстановка строк в переменные +echo ${VARIABLE/Просто/A} +# Это выражение заменит первую встреченную подстроку "Просто" на "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! + +# У нас есть обычная структура if: +# наберите 'man test' для получения подробной информации о форматах условия +if [ $NAME -ne $USER ] +then +    echo "Имя не совпадает с именем пользователя" +else +    echo "Имя совпадает с именем пользователя" +fi + +# Примечание: если $Name пустой, bash интерпретирует код как: +if [ -ne $USER ] +# а это ошибочная команда +# поэтому такие переменные нужно использовать так: +if [ "$Name" -ne $USER ] ... +# когда $Name пустой, bash видит код как: +if [ "" -ne $USER ] ... +# что работает правильно + +# Также есть условное исполнение +echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой" +echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно" + +# Можно использовать && и || в выражениях if, когда нужно несколько пар скобок: +if [ $NAME == "Steve" ] && [ $AGE -eq 15 ] +then +    echo "Исполнится, если $NAME равно Steve И $AGE равно 15." +fi + +if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ] +then +    echo "Исполнится, если $NAME равно Daniya ИЛИ Zach." +fi + +# Выражения обозначаются таким форматом: +echo $(( 10 + 5 )) + +# В отличие от других языков программирования, Bash - это командная оболочка, +# а значит, работает в контексте текущей директории. +# Вы можете просматривать файлы и директории в текущей директории командой ls: +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 с разными вариантами перенаправления потоков +# стандартных ввода, вывода и ошибок: +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) +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 + +# Или с использованием "традиционного" синтаксиса цикла 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, используйте fgrep (или 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/ru-ru/brainfuck-ru.html.markdown b/ru-ru/brainfuck-ru.html.markdown index 500ac010..fcee185f 100644 --- a/ru-ru/brainfuck-ru.html.markdown +++ b/ru-ru/brainfuck-ru.html.markdown @@ -11,6 +11,8 @@ lang: ru-ru  Brainfuck (пишется маленькими буквами, кроме начала предложения) - это очень  маленький Тьюринг-полный язык программирования лишь с 8 командами. +Вы можете испытать brainfuck в вашем браузере с помощью [brainfuck-визуализатора](http://fatiherikli.github.io/brainfuck-visualizer/). +  ```  Любой символ, кроме "><+-.,[]", игнорируется, за исключением кавычек. diff --git a/ru-ru/clojure-ru.html.markdown b/ru-ru/clojure-ru.html.markdown index 2f508a00..451da312 100644 --- a/ru-ru/clojure-ru.html.markdown +++ b/ru-ru/clojure-ru.html.markdown @@ -144,7 +144,7 @@ Clojure, это представитель семейства Lisp-подобн  ;;;;;;;;;;;;;;;;;;;;;  ; Функция создается специальной формой fn. -; "Тело"" функции может состоять из нескольких форм, +; "Тело" функции может состоять из нескольких форм,  ; но результатом вызова функции всегда будет результат вычисления  ; последней из них.  (fn [] "Hello World") ; => fn diff --git a/ru-ru/css-ru.html.markdown b/ru-ru/css-ru.html.markdown new file mode 100644 index 00000000..2e2d40b7 --- /dev/null +++ b/ru-ru/css-ru.html.markdown @@ -0,0 +1,250 @@ +--- +language: css +contributors: +    - ["Mohammad Valipour", "https://github.com/mvalipour"] +    - ["Marco Scannadinari", "https://github.com/marcoms"] +    - ["Geoffrey Liu", "https://github.com/g-liu"] +filename: learncss-ru.css +lang: ru-ru +--- + +В свои ранние дни веб состоял в основном из чистого текста. С развитием браузеров +веб-страницы с графическими элементами стали обычным делом. +CSS - язык, разграничивающий содержимое (HTML) и внешний вид веб-страниц. + +Если коротко, то CSS предоставляет синтаксис, позволяющий выбирать различные +HTML элементы и определять их внешний вид. + +Как и у других языков, у CSS много версий. Мы описываем CSS2.0 - не самую новую, +но самую поддерживаемую и распространенную версию. + +**ВАЖНО:** Так как результатом применения CSS является изменение внешнего вида +элементов, постарайтесь использовать CSS-песочницы при изучении языка. +Например [dabblet](http://dabblet.com/). +В данной статье рассматриваются в первую очередь синтаксис и общие рекомендации. + + +```css +/* Для комментариев используется слеш-астериск, как на этой строчке. +   В CSS нет однострочных комментариев; все комментарии записываются таким способом */ + +/* #################### +   ## СЕЛЕКТОРЫ +   #################### */ + +/* Выражения в CSS очень просты */ +селектор { атрибут: значение; /* другие атрибуты...*/ } + +/* селекторы используются для выбора элементов на странице + +Чтобы выбрать все элементы, используйте астериск: */ +* { color:red; } + +/* +Если на странице присутствует такой элемент: + +<div class='some-class class2' id='someId' attr='value' otherAttr='en-us foo bar' /> +*/ + +/* его можно выбрать по одному классу */ +.some-class { } + +/* или по обоим классам */ +.some-class.class2 { } + +/* по названию тега */ +div { } + +/* по идентификатору */ +#someId { } + +/* по имеющемуся атрибуту */ +[attr] { font-size:smaller; } + +/* или по атрибуту с определенным значением */ +[attr='value'] { font-size:smaller; } + +/* можно выбрать атрибуты, начинающиеся с определенного значения (CSS3) */ +[attr^='val'] { font-size:smaller; } + +/* или заканчивающиеся определенным значением (CSS3) */ +[attr$='ue'] { font-size:smaller; } + +/* содержащие отделенное пробелами значение в названии атрибута (CSS3)  */ +[otherAttr~='foo'] { font-size:smaller; } + +/* можно выбрать атрибут как с точным, так и со стоящим после значения “-” (U+002D) */ +[otherAttr|='en'] { font-size:smaller; } + + +/* Более того, все это можно использовать вместе - между разными частями +не должно быть пробелов, иначе селектор будет иметь совершенно иное значение  */ +div.some-class[attr$='ue'] { } + +/* Вы можете выбрать элемент по его родителю */ + +/* прямой потомок другого элемента (выбранного с помощью селектора) */ +div.some-parent > .class-name {} + +/* потомок любого родителя в дереве элементов +   следующая строка означает: "любой элемент класса "class-name", +   являющийся потомком div-элемента класса "some-parent" +   НЕЗАВИСИМО ОТ УРОВНЯ ВЛОЖЕННОСТИ" */ +div.some-parent .class-name {} + +/* важно: этот же селектор без пробелов имеет иное значение +   можете догадаться, какое? */ +div.some-parent.class-name {} + +/* вы можете выбрать элемент по первому предшествующему +   родственному элементу */ +.i-am-before + .this-element { } + +/* или любому предшествующему родственнику перед элементом */ +.i-am-any-before ~ .this-element {} + + +/* Существуют псевдо-классы, позволяющие изменять внешний вид элемента +   в зависимости от событий, произошедших с элементом */ + +/* например, когда курсор наведен на элемент */ +element:hover {} + +/* когда пользователь проходил по ссылке ранее */ +element:visited {} + +/* или еще не проходил по ней */ +element:link {} + +/* выбранное поле воода (input) */ +element:focus {} + + +/* #################### +   ## АТРИБУТЫ +   #################### */ + +selector { +     +    /* Единицы измерения */ +    width: 50%; /* проценты */ +    font-size: 2em; /* умножается на высоту шрифта (2em - в два раза больше) */ +    width: 200px; /* пиксели */ +    font-size: 20pt; /* пункты */ +    width: 5cm; /* сантиметры */ +    min-width: 50mm; /* милиметры */ +    max-width: 5in; /* дюймы */ +    height: 0.2vh; /* умножается на высоту окна браузера (CSS3) */ +    width: 0.4vw; /* умножается на ширину окна браузера (CSS3) */ +    min-height: 0.1vmin; /* наименьшее из vh и vw (CSS3) */ +    max-width: 0.3vmax; /* наибольшее из vh и vw (CSS3) */ +     +    /* Цвета */ +    background-color: #F6E;  /* сокращенная запись шестнадцатеричного кода */ +    background-color: #F262E2; /* стандартная запись шестнадцатеричного кода */ +    background-color: tomato; /* название цвета */ +    background-color: rgb(255, 255, 255); /* цветовая модель rgb */ +    background-color: rgb(10%, 20%, 50%); /* цветовая модель rgb в процентах */ +    background-color: rgba(255, 0, 0, 0.3); /* цветовая модель rgb (последний аргумент отвечает за прозрачность цвета) (CSS3) */ +    background-color: transparent; /* прозрачный цвет */ +    background-color: hsl(0, 100%, 50%); /* в формате hsl (CSS3) */ +    background-color: hsla(0, 100%, 50%, 0.3); /* в формате hsl (последний аргумент отвечает за непрозрачность цвета) (CSS3) */ + +     +    /* Изображения */ +    background-image: url(/path-to-image/image.jpg); /* кавычки внутри url() опциональны */ +     +    /* Шрифты */ +    font-family: Arial; +    font-family: "Courier New"; /* если в названии есть пробелы, заключите его в кавычки */ +    font-family: "Courier New", Trebuchet, Arial, sans-serif; /* если шрифт не найден, +                             будет использован следующий за ним в списке */ +} + +``` + +## Использование + +Сохраните готовый файл с расширением .css + +```xml +<!-- добавьте css файл в тег <head> на странице: --> +<link rel='stylesheet' type='text/css' href='path/to/style.css' /> + +<!-- Можно использовать встроенные стили. Рекомендуется избегать подобного подхода. --> +<body> +  <style> +     a { color: purple; } +  </style> +</body> + +<!-- Можно установить стиль элемента напрямую. +Используйте этот способ только в случае крайней необходимости. --> +<div style="border: 1px solid red;"> +</div> + +``` + +## Приоритет + +Как вы заметили, внешний вид элемента может определяться несколькими селекторами, +а значение атрибута элемента может быть установлено больше одного раза. +В подобных случаях одно из значений оказывается приоритетнее остальных. + +Если взять следующую таблицу стилей: + +```css +/*A*/ +p.class1[attr='value'] + +/*B*/ +p.class1 {} + +/*C*/ +p.class2 {} + +/*D*/ +p {} + +/*E*/ +p { property: value !important; } + +``` + +и следующую разметку: + +```xml +<p style='/*F*/ property:value;' class='class1 class2' attr='value'> +</p> +``` + +Приоритет стилей будет таким: +Помните: приоритет выставляется для **атрибута**, а не для всего блока стилей. + +* `E` имеет наивысший приоритет благодаря ключевому слову `!important`. +    Используйте только в случае крайней необходимости. +* `F` идет следующим, так как является встроенным стилем. +* `A` следующий, как самый конкретизированный.   +    конкретизированный == большее количество определителей. +    В этом примере 3 определителя: 1 тег `p` +    +    название класса `class1` + 1 атрибут `attr='value'` +* `C` следующий. Несмотря на одинаковое с `B` количество определителей, +    `C` определен позже. +* Затем `B` +* И последний `D`. + +## Совместимость + +Несмотря на то, что большая часть функций CSS2 (а также CSS3) подеррживается всеми +браузерами и устройствами, не забывайте проверять совместимость CSS-правил +с современными браузерами. + +[QuirksMode CSS](http://www.quirksmode.org/css/) замечательно подходит для этого. + +To run a quick compatibility check, [CanIUse](http://caniuse.com) is a great resource. + +## Ресурсы для самостоятельного изучения + +* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) +* [QuirksMode CSS](http://www.quirksmode.org/css/) +* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) diff --git a/ru-ru/d-ru.html.markdown b/ru-ru/d-ru.html.markdown new file mode 100644 index 00000000..8f4233fd --- /dev/null +++ b/ru-ru/d-ru.html.markdown @@ -0,0 +1,753 @@ +--- +language: d +filename: learnd-ru.d +contributors: +    - ["Anton Pastukhov", "http://dprogramming.ru/"] +    - ["Robert Brights-Gray", "http://lhs-blog.info/"] +    - ["Andre Polykanine", "http://oire.me/"] +lang: ru-ru +--- +D - современный компилируемый язык общего назначения с Си-подобным синтаксисом, +который сочетает удобство, продуманный дизайн и высокую производительность. +D - это С++, сделанный правильно. + +```d +// Welcome to D! Это однострочный комментарий + +/* многострочный +   комментарий  */ + +/+ +    // вложенные комментарии + +    /* еще вложенные +       комментарии */ + +    /+ +        // мало уровней вложенности? Их может быть сколько угодно. +    +/ ++/ + +/* +    Имя модуля. Каждый файл с исходным кодом на D — модуль. +    Если имя не указано явно, то предполагается, что оно совпадает с именем +    файла. Например, для файла "test.d" имя модуля будет "test", если явно +    не указать другое + */ +module app; + +// импорт модуля. Std — пространство имен стандартной библиотеки (Phobos) +import std.stdio; + +// можно импортировать только нужные части, не обязательно модуль целиком +import std.exception : enforce; + +// точка входа в программу — функция main, аналогично C/C++ +void main() +{ +    writeln("Hello, world!"); +} + + + +/*** типы и переменные ***/ + +int a; // объявление переменной типа int (32 бита) +float b = 12.34; // тип с плавающей точкой +double c = 56.78; // тип с плавающей точкой (64 бита) + +/* +    Численные типы в D, за исключением типов с плавающей точкой и типов +    комплексных чисел, могут быть беззнаковыми. +    В этом случае название типа начинается с префикса "u" +*/ +uint d = 10; ulong e = 11; +bool b = true; // логический тип +char d = 'd';  // UTF-символ, 8 бит. D поддерживает UTF "из коробки" +wchar e = 'é';   // символ UTF-16 +dchar f;       // и даже UTF-32, если он вам зачем-то понадобится + +string s = "для строк есть отдельный тип, это не просто массив char-ов из Си"; +wstring ws = "поскольку у нас есть wchar, должен быть и  wstring"; +dstring ds = "...и dstring, конечно"; + +string кириллица = "Имена переменных должны быть в Unicode, но не обязательно на латинице."; + +typeof(a) b = 6; // typeof возвращает тип своего выражения. +                 // В результате, b имеет такой же тип, как и a + +// Тип переменной, помеченной ключевым словом auto, +// присваивается компилятором исходя из значения этой переменной +auto x = 1;              // Например, тип этой переменной будет int. +auto y = 1.1;            // этой — double +auto z = "Zed is dead!"; // а этой — string + +int[3] arr = [1, 2, 3]; // простой одномерный массив с фиксированным размером +int[] arr2 = [1, 2, 3, 4]; // динамический массив +int[string] aa = ["key1": 5, "key2": 6]; // ассоциативный массив + +/* +   Строки и массивы в D — встроенные типы. Для их использования не нужно +   подключать ни внешние, ни даже стандартную библиотеку, хотя в последней +   есть множество дополнительных инструментов для работы с ними. + */ +immutable int ia = 10;  // неизменяемый тип, +                        // обозначается ключевым словом immutable +ia += 1;                // — вызовет ошибку на этапе компиляции + +// перечислимый (enumerable) тип, +// более правильный способ работы с константами в D +enum myConsts = { Const1, Const2, Const3 }; + +// свойства типов +writeln("Имя типа               : ", int.stringof); // int +writeln("Размер в байтах        : ", int.sizeof);   // 4 +writeln("Минимальное значение   : ", int.min);      // -2147483648 +writeln("Максимальное значение : ", int.max);      // 2147483647 +writeln("Начальное значение     : ", int.init);     // 0. Это значение, +                                                    // присвоенное по умолчанию + +// На самом деле типов в D больше, но все мы здесь описывать не будем, +// иначе не уложимся в Y минут. + + + +/*** Приведение типов ***/ + +// to!(имя типа)(выражение) - для большинства конверсий +import std.conv : to; // функция "to" - часть стандартной библиотеки, а не языка +double d = -1.75; +short s = to!short(d); // s = -1 + +/* +   cast - если вы знаете, что делаете. Кроме того, это единственный способ +   преобразования типов-указателей в "обычные" и наоборот +*/ +void* v; +int* p = cast(int*)v; + +// Для собственного удобства можно создавать псевдонимы +// для различных встроенных объектов +alias int newInt; // теперь можно обращаться к newInt так, как будто бы это int +newInt a = 5; + +alias newInt = int; // так тоже допустимо +alias uint[2] pair; // дать псевдоним можно даже сложным структурам данных + + + +/*** Операторы ***/ + +int x = 10; // присваивание +x = x + 1;  // 11 +x -= 2;     // 9 +x++;        // 10 +++x;        // 11 +x *= 2;     // 22 +x /= 2;     // 11 +x = x ^^ 2; // 121 (возведение в степень) +x ^^= 2;    // 1331 (то же самое) + +string str1 = "Hello"; +string str2 = ", world!"; +string hw = str1 ~ str2; // Конкатенация строк + +int[] arr = [1, 2, 3]; +arr ~= 4; // [1, 2, 3, 4] - добавление элемента в конец массива + + + +/*** Логика и сравнения ***/ + +int x = 0; int y = 1; + +x == y;         // false +x > y;          // false +x < y;          // true +x >= y;         // false +x != y;         // true. ! — логическое "не" +x > 0 || x < 1; // true. || — логическое "или" +x > 0 && x < 1; // false && — логическое "и" +x ^ y           // true; ^ - xor (исключающее "или") + +// Тернарный оператор +auto y = (x > 10) ? 1 : 0; // если x больше 10, то y равен 1, +                           // в противном случае y равен нулю + + +/***  Управляющие конструкции  ***/ + +// if - абсолютно привычен +if (a == 1) { +    // .. +} else if (a == 2) { +    // .. +} else { +    // .. +} + +// switch +switch (a) { +    case 1: +        // делаем что-нибудь +        break; +    case 2: +        // делаем что-нибудь другое +        break; +    case 3: +        // делаем что-нибудь еще +        break; +    default: +        // default обязателен, без него будет ошибка компиляции +        break; +} + +// в D есть констукция "final switch". Она не может содержать секцию "defaul" +// и применяется, когда все перечисляемые в switch варианты должны быть +// обработаны явным образом + +int dieValue = 1; +final switch (dieValue) { +    case 1: +        writeln("You won"); +        break; + +    case 2, 3, 4, 5: +        writeln("It's a draw"); +        break; + +    case 6: +        writeln("I won"); +        break; +} + +// while +while (a > 10) { +    // .. +    if (number == 42) { +        break; +    } +} + +while (true) { +    // бесконечный цикл +} + +// do-while +do { +    // .. +} while (a == 10); + +// for +for (int number = 1; number < 11; ++number) { +    writeln(number); // все абсолютно стандартно +} + +for ( ; ; ) { +    // секции могут быть пустыми. Это бесконечный цикл в стиле Си +} + +// foreach - универсальный и самый "правильный" цикл в D +foreach (element; array) { +    writeln(element); // для простых массивов +} + +foreach (key, val; aa) { +    writeln(key, ": ", val); // для ассоциативных массивов +} + +foreach (c; "hello") { +    writeln(c); // hello. Поскольку строки - это вариант массива, +                // foreach применим и к ним +} + +foreach (number; 10..15) { +    writeln(number); // численные интервалы можно указывать явным образом +                     // этот цикл выведет значения с 10 по 14, но не 15, +                     // поскольку диапазон не включает в себя верхнюю границу +} + +// foreach_reverse - в обратную сторону +auto container = [1, 2, 3]; +foreach_reverse (element; container) { +    writefln("%s ", element); // 3, 2, 1 +} + +// foreach в массивах и им подобных структурах не меняет сами структуры +int[] a = [1, 2 ,3 ,4 ,5]; +foreach (elem; array) { +    elem *= 2; // сам массив останется неизменным +} + +writeln(a); // вывод: [1, 2, 3, 4, 5] Т.е изменений нет + +// добавление ref приведет к тому, что массив будет изменяться +foreach (ref elem; array) { +    elem *= 2; +} + +writeln(a); // [2, 4, 6, 8, 10] + +// foreach умеет рассчитывать индексы элементов +int[] a = [1, 2, 3, 4, 5]; +foreach (ind, elem; array) { +    writeln(ind, " ", elem); // через ind - доступен индекс элемента, +                             // а через elem - сам элемент +} + + + +/*** Функции ***/ + +test(42); // Что, вот так сразу? Разве мы где-то уже объявили эту функцию? + +// Нет, вот она. Это не Си, здесь объявление функции не обязательно должно быть +// до первого вызова +int test(int argument) { +    return argument * 2; +} + + +// В D используется единый синтаксис вызова функций +// (UFCS, Uniform Function Call Syntax), поэтому так тоже можно: +int var = 42.test(); + +// и даже так, если у функции нет аргументов: +int var2 = 42.test; + +// можно выстраивать цепочки: +int var3 = 42.test.test; + +/* +    Аргументы в функцию передаются по значению (т.е. функция работает не с +    оригинальными значениями, переданными ей, а с их локальными копиями. +    Исключение составляют объекты классов, которые передаются по ссылке. +    Кроме того, любой параметр можно передать в функцию по ссылке с помощью +    ключевого слова "ref" +*/ +int var = 10; + +void fn1(int arg) { +    arg += 1; +} + +void fn2(ref int arg) { +    arg += 1; +} + +fn1(var); // var все еще = 10 +fn2(var); // теперь var = 11 + +// Возвращаемое значение тоже может быть auto, +// если его можно "угадать" из контекста +auto add(int x, int y) { +    return x + y; +} + +auto z = add(x, y); // тип int - компилятор вывел его автоматически + +// Значения аргументов по умолчанию +float linearFunction(float k, float x, float b = 1) +{ +    return k * x + b; +} + +auto linear1 = linearFunction(0.5, 2, 3); // все аргументы используются +auto linear2 = linearFunction(0.5, 2);    // один аргумент пропущен, но в функции +                                          // он все равно использован и равен 1 + +// допускается описание вложенных функций +float quarter(float x) { +    float doubled(float y) { +        return y * y; +    } + +    return doubled(doubled(x)); +} + +// функции с переменным числом аргументов +int sum(int[] a...) +{ +    int s = 0; +    foreach (elem; a) { +        s += elem; +    } +    return s; +} + +auto sum1 = sum(1); +auto sum2 = sum(1,2,3,4); + +/* +   модификатор "in" перед аргументами функций говорит о том, что функция имеет +    право их только просматривать. При попытке модификации такого аргумента +    внутри функции - получите ошибку +*/ +float printFloat(in float a) +{ +    writeln(a); +} +printFloat(a); // использование таких функций - самое обычное + +// модификатор "out" позволяет вернуть из функции несколько результатов +// без посредства глобальных переменных или массивов +uint remMod(uint a, uint b, out uint modulus) +{ +    uint remainder = a / b; +    modulus = a % b; +    return remainder; +} + +uint modulus;                   // пока в этой переменной ноль +uint rem = remMod(5, 2, modulus); // наша "хитрая" функция, и теперь +                                // в modulus - остаток от деления +writeln(rem, " ", modulus);     // вывод: 2 1 + + + +/*** Структуры, классы, базовое ООП ***/ + +// Объявление структуры. Структуры почти как в Си +struct MyStruct { +    int a; +    float b; + +    void multiply() { +        return a * b; +    } +} + +MyStruct str1; // Объявление переменной с типом MyStruct +str1.a = 10;   // Обращение к полю +str1.b = 20; +auto result = str1.multiply(); +MyStruct str2 = {4, 8}          // Объявление + инициализация  в стиле Си +auto str3 = MyStruct(5, 10);    // Объявление + инициализация  в стиле D + + +// области видимости полей и методов - 3 способа задания +struct MyStruct2 { +    public int a; + +    private: +        float b; +        bool c; + +    protected { +        float multiply() { +            return a * b; +        } +    } +    /* +        в дополнение к знакомым public, private и protected, в D есть еще +        область видимости "package". Поля и методы с этим атрибутом будут +        доступны изо всех модулей, включенных в "пакет" (package), но не +        за его пределами. package - это "папка", в которой может храниться +        несколько модулей. Например, в "import.std.stdio", "std" - это +        package, в котором есть модуль stdio (и еще множество других) +    */ +    package: +        string d; + +    /* помимо этого, имеется еще один модификатор - export, который позволяет +    использовать объявленный с ним идентификатор даже вне самой программы ! +    */ +    export: +         string description; +} + +// Конструкторы и деструкторы +struct MyStruct3 { +    this() { // конструктор. Для структур его не обязательно указывать явно, +             // в этом случае пустой конструктор добавляется компилятором +        writeln("Hello, world!"); +    } + + +    // а вот это конструкция - одна из интересных идиом и представляет собой +    // конструктор копирования, т.е конструктор, возвращающий копию структуры. +    // Работает только в структурах. +    this(this) +    { +        return this; +    } + +    ~this() { // деструктор, также необязателен +        writeln("Awww!"); +    } +} + +// Объявление простейшего класса +class MyClass { +    int a;  // в D по умолчанию данные-члены являются public +    float b; +} + +auto mc = new MyClass(); // ...и создание его экземпляра +auto mc2 = new MyClass; // ... тоже сработает + +// Конструктор +class MyClass2 { +    int a; +    float b; + +    this(int a, float b) { +        this.a = a; // ключевое слово "this" - ссылка на объект класса +        this.b = b; +    } +} + +auto mc2 = new MyClass2(1, 2.3); + +// Классы могут быть вложенными +class Outer +{ +    int m; + +    class Inner +    { +        int foo() +        { +            return m; // можно обращаться к полям "внешнего" класса +        } +    } +} + +// наследование +class Base { +    int a = 1; +    float b = 2.34; + + +    // это статический метод, т.е метод который можно вызывать, обращаясь +    // к классу напрямую, а не через создание экземпляра объекта +    static void multiply(int x, int y) +    { +        writeln(x * y); +    } +} + +Base.multiply(2, 5); // используем статический метод. Результат: 10 + +class Derived : Base { +    string c = "Поле класса - наследника"; + + +    // override означает то, что наследник предоставит свою реализацию метода, +    // переопределив метод базового класса +    override static void multiply(int x, int y) +    { +        super.multiply(x, y);  // super - это ссылка на класс-предок, или базовый класс +        writeln(x * y * 2); +    } +} + +auto mc3 = new Derived(); +writeln(mc3.a); // 1 +writeln(mc3.b); // 2.34 +writeln(mc3.c); // Поле класса - наследника + +// Финальный класс, наследовать от него нельзя +// кроме того, модификатор final работает не только для классов, но и для методов +// и даже для модулей ! +final class FC { +    int a; +} + +class Derived : FC { // это вызовет ошибку +    float b; +} + +// Абстрактный класс не может быть истанциирован, но может иметь наследников +abstract class AC { +    int a; +} + +auto ac = new AC(); // это вызовет ошибку + +class Implementation : AC { +    float b; + +     // final перед методом нефинального класса означает запрет возможности +     // переопределения метода +    final void test() +    { +       writeln("test passed !"); +    } +} + +auto impl = new Implementation(); // ОК + + + +/*** Примеси (mixins) ***/ + +// В D можно вставлять код как строку, если эта строка известна на этапе +// компиляции. Например: +void main() { +   mixin(`writeln("Hello World!");`); +} + +// еще пример +string print(string s) { +   return `writeln("` ~ s ~ `");`; +} + +void main() { +   mixin (print("str1")); +   mixin (print("str2")); +} + + + +/*** Шаблоны ***/ + +/* +    Шаблон функции. Эта функция принимает аргументы разных типов, которые +    подставляются вместо T на этапе компиляции. "T" - это не специальный +    символ, а просто буква. Вместо "T" может быть любое слово, кроме ключевого. + */ +void print(T)(T value) { +   writefln("%s", value); +} + +void main() { +   print(42);     // В одну и ту же функцию передается: целое +   print(1.2);    // ...число с плавающей точкой, +   print("test"); // ...строка +} + +// "Шаблонных" параметров может быть сколько угодно +void print(T1, T2)(T1 value1, T2 value2) { +   writefln(" %s %s", value1, value2); +} + +void main() { +   print(42, "Test"); +   print(1.2, 33); +} + +// Шаблон класса +class Stack(T) +{ +    private: +        T[] elements; + +    public: +        void push(T element) { +            elements ~= element; +        } + +        void pop() { +            --elements.length; +        } + +        T top() const @property { +            return elements[$ - 1]; +        } + +        size_t length() const @property { +            return elements.length; +        } +} + +void main() { +    /* +        восклицательный знак - признак шаблона. В данном случае мы создаем +        класс и указываем, что "шаблонное" поле будет иметь тип string +    */ +   auto stack = new Stack!string; + +   stack.push("Test1"); +   stack.push("Test2"); + +   writeln(stack.top); +   writeln(stack.length); + +   stack.pop; +   writeln(stack.top); +   writeln(stack.length); +} + + + +/*** Диапазоны (ranges) ***/ + +/* +   Диапазоны - это абстракция, которая позволяет легко использовать разные +   алгоритмы с разными структурами данных. Вместо того, чтобы определять свои +   уникальные алгоритмы для каждой структуры, мы можем просто указать для нее +   несколько единообразных функций, определяющих, _как_ мы получаем доступ +   к элементам контейнера, вместо того, чтобы описывать внутреннее устройство +   этого контейнера. Сложно? На самом деле не очень. + +    Простейший вид диапазона - Input Range. Для того, чтобы превратить любой +    контейнер в Input Range, достаточно реализовать для него 3 метода: +    - empty - проверяет, пуст ли контейнер +    - front - дает доступ к первому элементу контейнера +    - popFront - удаляет из контейнера первый элемент +*/ +struct Student +{ +    string name; +    int number; +    string toString() { +        return format("%s(%s)", name, number); +    } +} + +struct School +{ +    Student[] students; +} + +struct StudentRange +{ +    Student[] students; + +    this(School school) { +        this.students = school.students; +    } + +    bool empty() { +        return students.length == 0; +    } + +    Student front() { +        return students[0]; +    } + +    void popFront() { +        students = students[1 .. $]; +    } +} + +void main(){ +    auto school = School([ +            Student("Mike", 1), +            Student("John", 2) , +            Student("Dan", 3) +    ]); +    auto range = StudentRange(school); +    writeln(range);                     // [Mike(1), John(2), Dan(3)] +    writeln(school.students.length);    // 3 +    writeln(range.front());             // Mike(1) +    range.popFront(); +    writeln(range.empty());             // false +    writeln(range);                     // [John(2), Dan(3)] +} +/* +   Смысл в том, что нам не так уж важно внутреннее устройство контейнера, если +   у нас есть унифицированные методы доступа к его элементам. +   Кроме Input Range в D есть и другие типы диапазонов, которые требуют +   реализации большего числа методов, зато дают больше контроля. Это большая +   тема и мы не будем в подробностях освещать ее здесь. + +   Диапазоны - это важная часть D, они используются в нем повсеместно. +*/ +``` +## Что дальше? + +- [Официальный сайт](http://dlang.org/) +- [Онлайн-книга](http://ddili.org/ders/d.en/) +- [Официальная вики](http://wiki.dlang.org/) diff --git a/ru-ru/erlang-ru.html.markdown b/ru-ru/erlang-ru.html.markdown index 99ea79ee..69f81800 100644 --- a/ru-ru/erlang-ru.html.markdown +++ b/ru-ru/erlang-ru.html.markdown @@ -18,7 +18,7 @@ lang: ru-ru  % Пунктуационные знаки, используемые в Erlang:  % Запятая (`,`) разделяет аргументы в вызовах функций, структурах данных и  % образцах. -% Точка (`.`) (с пробелом после них) разделяет функции и выражения в +% Точка (`.`) (с пробелом после неё) разделяет функции и выражения в  % оболочке.  % Точка с запятой (`;`) разделяет выражения в следующих контекстах:  % формулы функций, выражения `case`, `if`, `try..catch` и `receive`. diff --git a/ru-ru/java-ru.html.markdown b/ru-ru/java-ru.html.markdown index 005495cc..b24ad555 100644 --- a/ru-ru/java-ru.html.markdown +++ b/ru-ru/java-ru.html.markdown @@ -451,7 +451,7 @@ public class Fruit implements Edible, Digestible {      }  } -// В Java Вы можете наследоватьтолько один класс, однако можете реализовывать +// В Java Вы можете наследовать только один класс, однако можете реализовывать  // несколько интерфейсов. Например:  public class ExampleClass extends ExampleClassParent implements InterfaceOne, InterfaceTwo {      public void InterfaceOneMethod() { diff --git a/ru-ru/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown index 79844565..54499f46 100644 --- a/ru-ru/javascript-ru.html.markdown +++ b/ru-ru/javascript-ru.html.markdown @@ -330,7 +330,7 @@ function sayHelloInFiveSeconds(name) {  sayHelloInFiveSeconds("Адам"); // Через 5 с откроется окно «Привет, Адам!»  /////////////////////////////////// -// 5. Подробнее об объектах; конструкторы и прототипы +// 5. Подробнее об объектах; Конструкторы и Прототипы  // Объекты могут содержать в себе функции.  var myObj = { @@ -470,9 +470,6 @@ myNumber === myNumberObj; // = false  if (0) {      // Этот код не выполнится, потому что 0 - это ложь.  } -if (Number(0)) { -    // Этот код *выполнится*, потому что Number(0) истинно. -}  // Впрочем, объекты-обёртки и встроенные типы имеют общие прототипы,  // поэтому вы можете расширить функционал строк, например: diff --git a/ru-ru/objective-c-ru.html.markdown b/ru-ru/objective-c-ru.html.markdown index 3246de82..d60db1d8 100644 --- a/ru-ru/objective-c-ru.html.markdown +++ b/ru-ru/objective-c-ru.html.markdown @@ -1,106 +1,171 @@  ---  language: Objective-C -filename: LearnObjectiveC.m +filename: LearnObjectiveC-ru.m  contributors:      - ["Eugene Yagrushkin", "www.about.me/yagrushkin"]      - ["Yannick Loriot", "https://github.com/YannickL"] +    - ["Levi Bostian", "https://github.com/levibostian"]  translators:      - ["Evlogy Sutormin", "http://evlogii.com"] +    - ["Dmitry Bessonov", "https://github.com/TheDmitry"]  lang: ru-ru  --- -Objective-C — компилируемый объектно-ориентированный язык программирования, используемый корпорацией Apple, -построенный на основе языка Си и парадигм Smalltalk. -В частности, объектная модель построена в стиле Smalltalk — то есть объектам посылаются сообщения. +Objective-C — основной язык программирования, используемый корпорацией Apple +для операционных систем OS X и iOS и их соответствующих фреймворках Cocoa и +Cocoa Touch. +Он является объектно-ориентированным языком программирования общего назначения, +который добавляет обмен сообщениями в Smalltalk-стиле к языку программирования C. -```objective_c -// Однострочный комментарий +```objective-c +// Однострочные комментарии начинаются с //  /* -Многострочный -комментарий +Так выглядят многострочные комментарии  */ -// Импорт файлов фреймворка Foundation с помощью #import +// Импорт заголовочных файлов фреймворка Foundation с помощью #import +// Используйте <>, чтобы импортировать глобальные файлы (обычно фреймворки) +// Используйте "", чтобы импортировать локальные файлы (из проекта)  #import <Foundation/Foundation.h>  #import "MyClass.h" -// Точка входа в программу это функция main, -// которая возвращает целый тип integer +// Если вы включили модули для iOS >= 7.0 или OS X >= 10.9 проектов в +// Xcode 5, вы можете импортировать фреймворки подобным образом: +@import Foundation; + +// Точка входа в программу - это функция main, +// которая возвращает целый тип  int main (int argc, const char * argv[])  { -    // Создание autorelease pool для управления памятью +    // Создание autorelease pool для управления памятью в программе      NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; -  +    // В место этого воспользуйтесь @autoreleasepool, если вы используете +    // автоматический подсчет ссылок (ARC) +    @autoreleasepool { +          // Используйте NSLog для печати в консоль -    NSLog(@"Hello World!"); // Напечатает строку "Hello World!" +    NSLog(@"Привет Мир!"); // Напечатает строку "Привет Мир!"      ///////////////////////////////////////      // Типы и переменные      /////////////////////////////////////// -    // Простое объявление +    // Объявление простых типов      int myPrimitive1  = 1;      long myPrimitive2 = 234554664565; +    // Объявление объектов      // Помещайте * в начало названия объекта для строго типизированного объявления      MyClass *myObject1 = nil;  // Строгая типизация	      id       myObject2 = nil;  // Слабая типизация  - -    NSLog(@"%@ and %@", myObject1, [myObject2 description]); // напечатает "(null) and (null)"      // %@ – это объект -    // 'description' это общий для всех объектов метод вывода данных +    // 'description' - это общий для всех объектов метод вывода данных +    NSLog(@"%@ and %@", myObject1, [myObject2 description]); // напечатает "(null) and (null)"      // Строка -    NSString *worldString = @"World"; -    NSLog(@"Hello %@!", worldString); // напечатает "Hello World!" +    NSString *worldString = @"Мир"; +    NSLog(@"Привет %@!", worldString); // напечатает "Привет Мир!" +    // NSMutableString - это изменяемая версия NSString-объекта +    NSMutableString *mutableString = [NSMutableString stringWithString:@"Привет"]; +    [mutableString appendString:@" Мир!"]; +    NSLog(@"%@", mutableString); // напечатает => "Привет Мир!"      // Символьные литералы      NSNumber *theLetterZNumber = @'Z'; -    char theLetterZ            = [theLetterZNumber charValue]; +    char theLetterZ            = [theLetterZNumber charValue]; // или 'Z'      NSLog(@"%c", theLetterZ); -    // Целочисленный литералы +    // Целочисленные литералы      NSNumber *fortyTwoNumber = @42; -    int fortyTwo             = [fortyTwoNumber intValue]; +    int fortyTwo             = [fortyTwoNumber intValue]; // или '42'      NSLog(@"%i", fortyTwo);      // Беззнаковый целочисленный литерал      NSNumber *fortyTwoUnsignedNumber = @42U; -    unsigned int fortyTwoUnsigned    = [fortyTwoUnsignedNumber unsignedIntValue]; +    unsigned int fortyTwoUnsigned    = [fortyTwoUnsignedNumber unsignedIntValue]; // или 42      NSLog(@"%u", fortyTwoUnsigned);      NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42]; -    short fortyTwoShort           = [fortyTwoShortNumber shortValue]; +    short fortyTwoShort           = [fortyTwoShortNumber shortValue]; // или 42      NSLog(@"%hi", fortyTwoShort); +    NSNumber *fortyOneShortNumber   = [NSNumber numberWithShort:41]; +    unsigned short fortyOneUnsigned = [fortyOneShortNumber unsignedShortValue]; // или 41 +    NSLog(@"%u", fortyOneUnsigned); +          NSNumber *fortyTwoLongNumber = @42L; -    long fortyTwoLong            = [fortyTwoLongNumber longValue]; +    long fortyTwoLong            = [fortyTwoLongNumber longValue]; // или 42      NSLog(@"%li", fortyTwoLong); +     +    NSNumber *fiftyThreeLongNumber   = @53L; +    unsigned long fiftyThreeUnsigned = [fiftyThreeLongNumber unsignedLongValue]; // или 53 +    NSLog(@"%lu", fiftyThreeUnsigned);      // Вещественный литерал      NSNumber *piFloatNumber = @3.141592654F; -    float piFloat           = [piFloatNumber floatValue]; -    NSLog(@"%f", piFloat); +    float piFloat           = [piFloatNumber floatValue]; // или 3.141592654f +    NSLog(@"%f", piFloat); // напечатает 3.141592654 +    NSLog(@"%5.2f", piFloat); // напечатает " 3.14"      NSNumber *piDoubleNumber = @3.1415926535; -    double piDouble                 = [piDoubleNumber doubleValue]; +    double piDouble                 = [piDoubleNumber doubleValue]; // или 3.1415926535      NSLog(@"%f", piDouble); - +    NSLog(@"%4.2f", piDouble); // напечатает "3.14" + +    // NSDecimalNumber - это класс с фиксированной точкой, который является +    // более точным, чем float или double +    NSDecimalNumber *oneDecNum = [NSDecimalNumber decimalNumberWithString:@"10.99"]; +    NSDecimalNumber *twoDecNum = [NSDecimalNumber decimalNumberWithString:@"5.002"]; +    // NSDecimalNumber не способен использовать стандартные +, -, *, / операторы, +    // поэтому он предоставляет свои собственные: +    [oneDecNum decimalNumberByAdding:twoDecNum];  +    [oneDecNum decimalNumberBySubtracting:twoDecNum]; +    [oneDecNum decimalNumberByMultiplyingBy:twoDecNum]; +    [oneDecNum decimalNumberByDividingBy:twoDecNum]; +    NSLog(@"%@", oneDecNum); // напечатает "10.99", т.к. NSDecimalNumber - изменяемый +          // BOOL (булевый) литерал      NSNumber *yesNumber = @YES;      NSNumber *noNumber  = @NO; - +    // или +    BOOL yesBool = YES; +    BOOL noBool  = NO; +    NSLog(@"%i", yesBool); // напечатает 1 +          // Массив +    // Может содержать различные типы данных, но должен быть объектом Objective-C      NSArray *anArray      = @[@1, @2, @3, @4];      NSNumber *thirdNumber = anArray[2]; -    NSLog(@"Third number = %@", thirdNumber); // Print "Third number = 3" +    NSLog(@"Третье число = %@", thirdNumber); // Напечатает "Третье число = 3" +    // NSMutableArray - это изменяемая версия NSArray, допускающая вам изменять +    // элементы в массиве и расширять или сокращать массив. +    // Удобный, но не эффективный как NSArray. +    NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2]; +    [mutableArray addObject:@"Привет"]; +    [mutableArray addObject:@"Мир"]; +    [mutableArray removeObjectAtIndex:0]; +    NSLog(@"%@", [mutableArray objectAtIndex:0]); // напечатает "Мир"      // Словарь -    NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" }; -    NSObject *valueObject     = aDictionary[@"A Key"]; -    NSLog(@"Object = %@", valueObject); // Напечатает "Object = (null)" - +    NSDictionary *aDictionary = @{ @"ключ1" : @"значение1", @"ключ2" : @"значение2" }; +    NSObject *valueObject     = aDictionary[@"Ключ"]; +    NSLog(@"Объект = %@", valueObject); // Напечатает "Объект = (null)" +    // NSMutableDictionary тоже доступен, как изменяемый словарь +    NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2]; +    [mutableDictionary setObject:@"значение1" forKey:@"ключ1"]; +    [mutableDictionary setObject:@"значение2" forKey:@"ключ2"]; +    [mutableDictionary removeObjectForKey:@"ключ1"]; + +    // Множество +    NSSet *set = [NSSet setWithObjects:@"Привет", @"Привет", @"Мир", nil]; +    NSLog(@"%@", set); // напечатает {(Hello, World)} (порядок может отличаться) +    // NSMutableSet тоже доступен, как изменяемое множество +    NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2]; +    [mutableSet addObject:@"Привет"]; +    [mutableSet addObject:@"Привет"]; +    NSLog(@"%@", mutableSet); // напечатает => {(Привет)} +          ///////////////////////////////////////      // Операторы      /////////////////////////////////////// @@ -124,13 +189,13 @@ int main (int argc, const char * argv[])      // Условный оператор      if (NO)      { -        NSLog(@"I am never run"); +        NSLog(@"Я никогда не выполнюсь");      } else if (0)      { -        NSLog(@"I am also never run"); +        NSLog(@"Я тоже никогда не выполнюсь");      } else      { -        NSLog(@"I print"); +        NSLog(@"Я напечатаюсь");      }      // Ветвление с множественным выбором @@ -138,15 +203,15 @@ int main (int argc, const char * argv[])      {          case 0:          { -            NSLog(@"I am never run"); +            NSLog(@"Я никогда не выполнюсь");          } break;          case 1:          { -            NSLog(@"I am also never run"); +            NSLog(@"Я тоже никогда не выполнюсь");          } break;          default:          { -            NSLog(@"I print"); +            NSLog(@"Я напечатаюсь");          } break;      } @@ -170,7 +235,7 @@ int main (int argc, const char * argv[])        //               "2,"        //               "3," -    // // Цикл просмотра            +    // Цикл просмотра                 NSArray *values = @[@0, @1, @2, @3];      for (NSNumber *value in values)      { @@ -180,20 +245,32 @@ int main (int argc, const char * argv[])        //               "2,"        //               "3," +    // Цикл for для объектов. Может использоваться с любым объектом Objective-C +    for (id item in values) {  +        NSLog(@"%@,", item);  +    } // напечатает => "0,"  +      //           "1," +      //           "2," +      //           "3,"       +            // Обработка исключений      @try      {          // Ваше исключение здесь          @throw [NSException exceptionWithName:@"FileNotFoundException" -                            reason:@"File Not Found on System" userInfo:nil]; +                            reason:@"Файл не найден в системе" userInfo:nil];      } @catch (NSException * e)      { -        NSLog(@"Exception: %@", e); +        NSLog(@"Исключение: %@", e);      } @finally      { -        NSLog(@"Finally"); -    } // => напечатает "Exception: File Not Found on System" -      //               "Finally" +        NSLog(@"В конце отводится время для очистки."); +    } // => напечатает "Исключение: Файл не найден в системе" +      //               "В конце отводится время для очистки." +  +    // NSError - это полезные объекты для аргументов функции, чтобы заполнить их +    // пользовательскими ошибками. +    NSError *error = [NSError errorWithDomain:@"Неправильный эл. адрес." code:4 userInfo:nil];      ///////////////////////////////////////      // Объекты @@ -203,13 +280,16 @@ int main (int argc, const char * argv[])      // Объект не является полнофункциональным пока обе части не выполнятся.      MyClass *myObject = [[MyClass alloc] init]; -    // В Objective-C можель ООП базируется на передаче сообщений. +    // В Objective-C модель ООП базируется на передаче сообщений.      // В Objective-C Вы не просто вызваете метод; вы посылаете сообщение. -    [myObject instanceMethodWithParameter:@"Steve Jobs"]; +    [myObject instanceMethodWithParameter:@"Стив Джобс"];      // Очищайте память, перед завершением работы программы.      [pool drain]; +    // Конец @autoreleasepool +    } +          // Конец программы.      return 0;  } @@ -222,63 +302,145 @@ int main (int argc, const char * argv[])  // Синтаксис объявления:  // @interface ИмяКласса : ИмяКлассаРодителя <ИмплементируемыеПротоколы>  // { -//    Объявление переменных; +//    тип имя; <= Объявление переменных;  // } +// @property тип имя; <= объявление свойств  // -/+ (тип) Объявление метода(ов).  // @end - - -@interface MyClass : NSObject <MyProtocol> +@interface MyClass : NSObject <MyProtocol> // NSObject - это базовый класс в Objective-C.  { -    int count; -    id data; +    // Объявления экземпляров переменных (может существовать в файлах интерфейса или реализвации) +    int count; // По умолчанию защищенный доступ. +    @private id data; // Приватный доступ (Намного удобнее объявлять в файле реализации)      NSString *name;  } -// При объявлении свойств сразу генерируются геттер и сеттер -@property int count; -@property (copy) NSString *name; // Скопировать объект в ходе присвоения. -@property (readonly) id data;    // Генерация только геттера +// Удобное обозначение для переменных с открытым (public) доступом +// автоматически генерируется сеттер-метод +// По умолчанию название сеттер-метода начинается с 'set' с последующим именем +// переменной из @property +@property int propInt; // Имя сеттер-метода = 'setPropInt' +@property (copy) id copyId; // (copy) => Скопировать объект в ходе присвоения. +// (readonly) => Не позволяет установить значение вне @interface +@property (readonly) NSString *roString; // Используйте @synthesize  +                               // в @implementation, чтобы создать аксессор +// Вы можете настроить геттер и сеттер имена вместо используемого 'set'-имени по умолчанию: +@property (getter=lengthGet, setter=lengthSet:) int length;  // Методы -+/- (return type)methodSignature:(Parameter Type *)parameterName; ++/- (возвращаемый тип)сигнатураМетода:(Параметр типа *)имяПараметра;  // + для методов класса  + (NSString *)classMethod; ++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight; -// - для метода объекта +// - для методов объекта  - (NSString *)instanceMethodWithParameter:(NSString *)string;  - (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number; -@end +// Методы-конструктор с аргументом: +- (id)initWithDistance:(int)defaultDistance; +// В Objective-C имена методов очень описательные. Всегда имена методов соответствуют своим аргументам + +@end // Устанавливает конец интерфейса (interface) + + +// Чтобы обратиться к открытым (public) переменным из файла реализации, @property генерирует сеттер-метод +// автоматически. Название метода - это 'set' с последующим именем переменной из @property: +MyClass *myClass = [[MyClass alloc] init]; // создает экземпляр объекта класса MyClass +[myClass setCount:10];  +NSLog(@"%d", [myClass count]); // напечатает => 10 +// Или используйте свой геттер и сеттер методы, которые определены в @interface: +[myClass lengthSet:32]; +NSLog(@"%i", [myClass lengthGet]); // напечатает => 32 +// Для удобства вы можете использовать точечную нотацию, +// чтобы установить и получить доступ к переменным объекта: +myClass.count = 45; +NSLog(@"%i", myClass.count); // напечатает => 45 + +// Вызов методов класса: +NSString *classMethodString = [MyClass classMethod]; +MyClass *classFromName = [MyClass myClassFromName:@"Привет"]; + +// Вызов методов экземпляра: +MyClass *myClass = [[MyClass alloc] init]; // Создает экземпляр объекта MyClass +NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Привет"]; + +// Селекторы +// Это способ динамически представить методы. Используйте для вызова методов класса, передайте методы +// через функции, чтобы сказать другим классам, что они должны вызвать их и сохранить методы +// как переменные +// SEL - это тип данных. @selector() вернет селектор из предоставленного имени метода +// methodAParameterAsString:andAParameterAsNumber: - это название метода в MyClass +SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:);  +if ([myClass respondsToSelector:selectorVar]) { // Проверяет содержит ли класс метод +    // Необходимо установить все аргументы метода в один объект, что отправить его в performSelector-функцию +    NSArray *arguments = [NSArray arrayWithObjects:@"Привет", @4, nil]; +    [myClass performSelector:selectorVar withObject:arguments]; // Вызывает метод +} else { +    // NSStringFromSelector() вернет NSString название метода полученного селектором +    NSLog(@"MyClass не содержит метод: %@", NSStringFromSelector(selectedVar)); +} + +// Имплементируйте методы в файле MyClass.m: +@implementation MyClass { +    long distance; // Переменная экземпляра с закрытым (private) доступом +    NSNumber height; +} -// Имплементируйте методы в файле МойКласс.m: +// Для доступа к public переменной, объявленной в интерфейсе, используйте '_' перед названием переменной: +_count = 5; // Ссылается на "int count" из интерфейса MyClass +// Получение доступа к переменной, объявленной в реализации происходит следующим образом: +distance = 18; // Ссылается на "long distance" из реализации MyClass +// Для использования в иплементации переменной, объявленной в интерфейсе с помощью @property, +// следует использовать @synthesize для создания переменной аксессора: +@synthesize roString = _roString; // Теперь _roString доступна в @implementation (реализации интерфейса) -@implementation MyClass +// Вызывается в первую очередь, перед вызовом других медотов класса или инициализации других объектов ++ (void)initialize  +{ +    if (self == [MyClass class]) { +        distance = 0; +    } +}  // Вызывается при высвобождении памяти под объектом  - (void)dealloc  { +    [height release]; // Если не используется ARC, убедитесь в освобождении переменных объекта класса +    [super dealloc];  // and call parent class dealloc  } -// Конструкторы – это способ  осздания объектов класса. -// Это обычный конструктор вызываемый при создании объекта клсааа. +// Конструкторы – это способ создания объектов класса. +// Это конструктор по умолчанию, который вызывается, когда объект инициализируется.  - (id)init  { -    if ((self = [super init])) +    if ((self = [super init])) // 'super' используется для того, чтобы обратиться к методам родительского класса      { -        self.count = 1; +        self.count = 1; // 'self' используется для вызова самого себя      }      return self;  } +// Можно создать конструкторы, которые содержат аргументы: +- (id)initWithDistance:(int)defaultDistance  +{ +    distance = defaultDistance; +    return self; +}  + (NSString *)classMethod  {      return [[self alloc] init];  } ++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight  +{ +    height = defaultHeight; +    return [[self alloc] init]; +} +  - (NSString *)instanceMethodWithParameter:(NSString *)string  { -    return @"New string"; +    return @"Новая строка";  }  - (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number @@ -286,23 +448,364 @@ int main (int argc, const char * argv[])      return @42;  } +// Objective-C не содержит объявление приватных методов, но вы можете имитировать их. +// Чтобы сымитировать приватный метод, создайте метод в @implementation, но не в @interface. +- (NSNumber *)secretPrivateMethod { +    return @72; +} +[self secretPrivateMethod]; // Вызывает приватный метод +  // Методы объявленные в МyProtocol (см. далее)  - (void)myProtocolMethod  { -    // имплементация  +    // операторы  } +@end // Устанавливает конец реализации (implementation) + +/////////////////////////////////////// +// Категории +/////////////////////////////////////// +// Категория - это группа методов предназначенные для того, чтобы расширить класс. Они позволяют вам добавить новые методы +// к существующему классу для организационных целей. Это не стоит путать с подклассами. +// Подклассы предназначены для ИЗМЕНЕНИЯ функциональности объекта пока как категории ДОБАВЛЯЮТ +// функциональность в объект. +// Категории позволяют вам: +// -- Добавлять методы в существующий класс для организационных целей. +// -- Допускает вам расширять объекты Objective-C классов (напр.: NSString) добавить ваши собственные методы. +// -- Добавляет возможность создать защищенные и закрытые методы классов.  +// ПРИМЕЧАНИЕ: Не переопределяйте методы базового класса в категории даже если у вас есть возможность это сделать +// to. Переопределение методов может привести к ошибкам компиляции позднее между различными категориями и это  +// нарушает цель категорий, чтобы добавлять только функциональность. Вместо этого подклассы переопределяют методы. + +// Здесь простой базовый класс Car. +@interface Car : NSObject + +@property NSString *make; +@property NSString *color; + +- (void)turnOn; +- (void)accelerate; +  @end -/* - * Протокол объявляет методы которые должны быть имплементированы - * Протокол не является классом. Он просто определяет интерфейс, - * который должен быть имплементирован. - */ +// И реализация базового класса Car: +#import "Car.h" + +@implementation Car + +@synthesize make = _make; +@synthesize color = _color; + +- (void)turnOn { +    NSLog(@"Машина заведена."); +} +- (void)accelerate { +    NSLog(@"Ускорение."); +} -@protocol MyProtocol -    - (void)myProtocolMethod;  @end + +// Теперь, если мы хотим создать объект Truck - грузовик, мы должны создать подкласс класса Car, что +// изменит функционал Car и позволит вести себя подобно грузовику. Но что, если мы хотим только добавить +// определенный функционал в уже существующий класс Car? Например - чистка автомобиля. Мы просто создадим +// категорию, которая добавит несколько методов для чистки автомобиля в класс Car: +// @interface ИмяФайла: Car+Clean.h (ИмяБазовогоКласса+ИмяКатегории.h) +#import "Car.h" // Убедитесь в том, что базовый класс импортирован для расширения. + +@interface Car (Clean) // Имя категории внутри (), следующие после имени базового класса. + +- (void)washWindows; // Названия новых методов, которые мы добавляем в наш объект Car. +- (void)wax; + +@end + +// @implementation имя файла: Car+Clean.m (ИмяБазовогоКласса+ИмяКатегории.m) +#import "Car+Clean.h" // Импортируйте Очистку файл @interface категории. + +@implementation Car (Clean) + +- (void)washWindows { +    NSLog(@"Окна промыли."); +} +- (void)wax { +    NSLog(@"Воском натерли."); +} + +@end  + +// Любой экземпляр объекта Car имеет возможность воспользоваться категорией. Все, что нужно сделать, это импортировать ее: +#import "Car+Clean.h" // Импортировать как множество различных категорий, как вы хотите использовать. +#import "Car.h" // Кроме того, необходимо импортировать базовый класс для использования его оригинальные функциональные возможности. + +int main (int argc, const char * argv[]) { +    @autoreleasepool { +        Car *mustang = [[Car alloc] init]; +        mustang.color = @"Красный"; +        mustang.make = @"Форд"; + +        [mustang turnOn]; // Используйте методы из базового класса Car. +        [mustang washWindows]; // Используйте методы категории Clean из класса Car. +    } +    return 0;  +} + +// Objective-C не поддерживает объявление защищенных методов, но вы можете имитировать их. +// Создайте категорию, содержащую все защищенные методы, затем импортируйте ее только в +// @implementation-файле класса, относящегося к классу Car: +@interface Car (Protected) // Наименование категории с помощью 'Protected' +// дает знать, что методы защищенные. + +- (void)lockCar; // Здесь перечисляются методы, которые должны быть созданы +// только с помощью объектов класса Car. + +@end +// Чтобы воспользоваться защищенными методами, импортируйте категорию, затем реализуйте методы: +#import "Car+Protected.h" // Запомните, делайте импорт только в файле с @implementation. + +@implementation Car  + +- (void)lockCar { +    NSLog(@"Машина закрыта."); // Экземпляры класса Car не могут использовать +// метод lockCar, потому что он объявлен не в @interface. +} + +@end + +/////////////////////////////////////// +// Расширения +/////////////////////////////////////// +// Расширения позволяют вам переопределять атрибуты свойств и методов +// с открытым доступом в @interface. +// @interface имя файла: Shape.h +@interface Shape : NSObject // Расширение базового класса Shape переопределяет +                                        // свои поля ниже. + +@property (readonly) NSNumber *numOfSides; + +- (int)getNumOfSides; + +@end +// Вы можете переопределить numOfSides-переменную или getNumOfSides-метод +// Внесение изменений с помощью расширения делается следующим образом: +// @implementation имя файла: Shape.m +#import "Shape.h" +// Расширения "живут" в том же файле, где и @implementation класса. +@interface Shape () // После имени базового класса скобки () объявляют расширение. + +@property (copy) NSNumber *numOfSides; // Делает numOfSides-свойство +             // копирующим (copy) вместо свойства только для чтения (readonly). +-(NSNumber)getNumOfSides; // Изменяет метод getNumOfSides так, +                         // чтобы он возвращал объект NSNumber вместо типа int. +-(void)privateMethod; // Вы также можете создать новый закрытый метод +                              // внутри расширения. + +@end +// Главный @implementation: +@implementation Shape + +@synthesize numOfSides = _numOfSides; + +-(NSNumber)getNumOfSides { // Все операторы внутри расширения +                                         // должны быть в @implementation. +    return _numOfSides; +} +-(void)privateMethod { +    NSLog(@"Закрытый метод созданный с помощью расширения."); +    NSLog(@"Экземпляр Shape не может вызвать этот метод."); +} + +@end + +/////////////////////////////////////// +// Протоколы +/////////////////////////////////////// +// Протокол объявляет методы, которые могут быть реализованы с помощью +// любого класса. Протоколы сами по себе не являются классами. Они просто +// определяют интерфейс, который должен быть реализован другими объектами. +// @protocol имя файла: "CarUtilities.h" +@protocol CarUtilities <NSObject> // <NSObject> => Имя другого протокола, +// который включен в этот протокол. +    @property BOOL engineOn; // Адаптирующий класс должен определить +// все @synthesize для @property и +    - (void)turnOnEngine; // определить все методы. +@end +// Ниже пример класса, реализующий протокол. +#import "CarUtilities.h" // Импорт файла с @protocol. + +@interface Car : NSObject <CarUtilities> // Внутри <> имя протокола +// Здесь вам не нужно указывать @property или имена методов для CarUtilities. +// Они нужны только для @implementation. +- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // Вы также можете +// указать тип протоколов. +@end +// В @implementation нужно реализовать все @property и методы для протокола. +@implementation Car : NSObject <CarUtilities> + +@synthesize engineOn = _engineOn; // Создайте @synthesize-оператор +// для "@property engineOn". + +- (void)turnOnEngine { // Реализуйте turnOnEngine как вам угодно. Протоколы +// не определят, +    _engineOn = YES; // как вам реализовать метод, он только требует, +// чтобы вы реализовали его. +} +// Вы можете использовать протокол как данные, если вы знаете, что он реализует +// методы и переменные. +- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind {  +    [objectOfSomeKind engineOn]; // У вас есть доступ к переменным объекта +    [objectOfSomeKind turnOnEngine]; // и методам. +    [objectOfSomeKind engineOn]; // Может или не может быть значение YES. Класс +// реализует как нужно. +} + +@end +// Экземпляры класса Car сейчас имеют доступ к протоколу. +Car *carInstance = [[Car alloc] init]; +[carInstance setEngineOn:NO]; +[carInstance turnOnEngine]; +if ([carInstance engineOn]) { +    NSLog(@"Двигатель запущен."); // напечатает => "Двигатель запущен." +} +// Убедитись в том, что объект типа 'id' реализует протокол перед вызовом методов протокола: +if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { +    NSLog(@"Не работает, т.к. класс MyClass не реализует протокол CarUtilities."); +} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) { +    NSLog(@"Работает как класс Car, который реализует протокол CarUtilities."); +} +// Категории тоже могут реализовать протоколы: +// @interface Car (CarCategory) <CarUtilities> +// Вы можете реализовать много протоколов: +// @interface Car : NSObject <CarUtilities, CarCleaning> +// ЗАМЕЧАНИЕ: Если два или более протоколов полагаются друг на друга, +// убедитесь, что они ранее объявлены: +#import "Brother.h" + +@protocol Brother; // Оператор раннего объявления. Без него компилятор +// выдаст ошибку. + +@protocol Sister <NSObject> + +- (void)beNiceToBrother:(id <Brother>)brother; + +@end + +// Рассмотрите проблему, где протокол Sister полагается на протокол Brother, +// а Brother полагается на Sister. +#import "Sister.h" + +@protocol Sister; // Эти строки предотвращают рекурсию, решая этим проблему. + +@protocol Brother <NSObject> +  +- (void)beNiceToSister:(id <Sister>)sister; + +@end + + +/////////////////////////////////////// +// Блоки +/////////////////////////////////////// +// Блоки - это операторы кода, наподобие функции, которую возможно использовать +// как данные. +// Ниже простой блок с целочисленным аргументом, и возвращает аргумент плюс 4. +int (^addUp)(int n); // Объявите переменную, чтобы сохранить блок. +void (^noParameterBlockVar)(void); // Пример объявления блока-переменной +// без аргументов. +// Блоки имею доступ к переменным в той же области видимости. Но переменные +// будут только для чтения, и значения переданных в блок станут значением +// переменной, когда блок создастся. +int outsideVar = 17; // Если мы редактируем outsideVar после объявления addUp, +// outsideVar остается равным 17. +__block long mutableVar = 3; // __block делают переменные перезаписываемыми +// в блоках, в отличие от outsideVar. +addUp = ^(int n) { // Удалите (int n) в блоке, чтобы не принимать +// какие-либо параметры. +    NSLog(@"Вы можете иметь столько строк в блоке, сколько вы хотели."); +    NSSet *blockSet; // Также вы можете объявить локальные переменные. +    mutableVar = 32; // Присвоить новое значение к __block-переменной. +    return n + outsideVar; // Необязательный оператор возврата. +} +int addUp = add(10 + 16); // Вызывает блок кода с аргументами. +// Блоки часто используются как аргументы функции, чтобы позже их вызвать, или +// как функции обратного вызова (callbacks). +@implementation BlockExample : NSObject  +  +- (void)runBlock:(void (^)(NSString))block { +    NSLog(@"В аргументе блок ничего не возвращает и принимает NSString-объект."); +    block(@"Аргумент передан блоку на исполнение."); // Вызов блока. +} + +@end +  +  +/////////////////////////////////////// +// Управление памятью +/////////////////////////////////////// +/*  +Для каждого объекта, используемого в приложении, должна быть выделена память +для таких объектов. Когда приложение прекращает использование объекта, память +должна быть освобождена, чтобы гарантировать эффективность приложения. +Objective-C не использует сборщик мусора, а вместо этого применяет подсчет ссылок. +Пока существует по крайней мере одна ссылка на объект (также называется +"владение" объектом), то объект будет доступен к использованию (еще известно +как "право владения"). + +Когда экземпляр владеет объектом, его ссылка увеличивается на один. Когда +объекта освобождается, счетчик ссылки уменьшается на один. Когда счетчик ссылки +равен нулю, объект удаляется из памяти. + +Над всеми объектами взаимодействуют, следуя паттерну: +(1) создание объекта, (2) использование объекта, (3) затем освобождение объекта из памяти. +*/ + +MyClass *classVar = [MyClass alloc]; // 'alloc' устанавливает счетчик ссылки +// объекта classVar на 1 и возвращает указатель на объект. +[classVar release]; // Уменьшает счетчик ссылки объекта classVar +// 'retain' заявляет право собственности на существующий экземпляр объекта +// и увеличивает счетчик ссылки. Затем вернет указатель на объект. +MyClass *newVar = [classVar retain]; // Если classVar освободится, объект +// останется в памяти, потому что newVar - владелец +[classVar autorelease]; // Удалит право на владение объектом +// в конце @autoreleasepool блока. Вернет указатель на объект. + +// @property может использовать 'retain' и 'assign' тоже для маленького +// удобного определения +@property (retain) MyClass *instance; // Освободит старое значение и сохранит +// одно новое (строгая ссылка) +@property (assign) NSSet *set; // Укажет на новое значение +// без сохранения/освобождения старого значения (слабая ссылка) + +// Автоматический подсчет ссылок (ARC) +// Управление памятью может быть трудным, поэтому в Xcode 4.2 и iOS 4 введен +// автоматический подсчет ссылок (ARC). +// ARC - это особенность компилятора, который помещает "retain", "release" +// и "autorelease" автоматически за вас тогда, когда используется ARC, +// вам не нужно больше обращаться к "retain", "relase" или "autorelease" +MyClass *arcMyClass = [[MyClass alloc] init]; +// ... код, использующий объект arcMyClass +// Без ARC, вам нужно было бы вызвать: [arcMyClass release] после того, как вы +// завершите работу с объектом arcMyClass. Но с ARC, +// теперь этого не нужно делать. Он будет помещать release-вызов за вас + +// Что касается 'assign' и 'retain' @property атрибутов, в ARC вы должны +// использовать 'weak' и 'strong' +@property (weak) MyClass *weakVar; // 'weak' не принимает право на владение +// объектом. Если исходный счетчик ссылки экземпляра обнуляется, +// weakVar-свойство автоматически примет значение nil, +// во избежание падения приложения +@property (strong) MyClass *strongVar; // 'strong' принимает право на владение +// объектом. Гарантирует, что объект останется в памяти для использования + +// Для обычных переменных (не объявленных с помощью @property), используйте +// следующий способ: +__strong NSString *strongString; // По умолчанию. Переменная сохраняется в памяти, +// пока она не покинет область видимости +__weak NSSet *weakSet; // Слабая ссылка на существующий объект. Когда существующий +// объект освобождается, weakSet принимает nil +__unsafe_unretained NSArray *unsafeArray; // Похож на __weak, но unsafeArray +// не принимает nil, когда существующий объект освобождается +  ```  ## На почитать diff --git a/ru-ru/perl-ru.html.markdown b/ru-ru/perl-ru.html.markdown new file mode 100644 index 00000000..a907ba41 --- /dev/null +++ b/ru-ru/perl-ru.html.markdown @@ -0,0 +1,195 @@ +--- +category: language +language: perl +filename: learnperl-ru.pl +contributors: +    - ["Korjavin Ivan", "http://github.com/korjavin"] +translators: +    - ["Elena Bolshakova", "http://github.com/liruoko"] +lang: ru-ru +--- + +Perl 5 -- высокоуровневый мощный язык с 25-летней историей.  +Особенно хорош для обработки разнообразных текстовых данных.  + +Perl 5 работает более чем на 100 платформах, от портативных устройств +до мейнфреймов, и подходит как для быстрого прототипирования,  +так и для крупных проектов.  + +```perl +# Комментарии начинаются с символа решетки. + + +#### Типы переменных в Perl + +#  Скалярные переменные начинаются с знака доллара $. +#  Имя переменной состоит из букв, цифр и знаков подчеркивания,  +#  начиная с буквы или подчеркивания.  + +### В Perl три основных типа переменных: скаляры, массивы, хеши. + +## Скаляры +#  Скаляр хранит отдельное значение: +my $animal = "camel"; +my $answer = 42; + +# Скаляры могут быть строками, целыми и вещественными числами. +# Когда требуется, Perl автоматически выполняет преобразования к нужному типу. + +## Массивы +#  Массив хранит список значений: +my @animals = ("camel", "llama", "owl"); +my @numbers = (23, 42, 69); +my @mixed   = ("camel", 42, 1.23); + + +## Хеши +#   Хеш хранит набор пар ключ/значение: + +my %fruit_color = ("apple", "red", "banana", "yellow"); + +#  Можно использовать оператор "=>" для большей наглядности: + +my %fruit_color = ( +        apple  => "red", +        banana => "yellow", +        ); + +# Важно: вставка и поиск в хеше выполняются за константное время,  +# независимо от его размера. + +# Скаляры, массивы и хеши подробно описаны в разделе perldata +# (perldoc perldata). + +# Более сложные структуры данных можно получить, если использовать ссылки. +# С помощью ссылок можно получить массив массивов хешей, в которых хранятся другие хеши. + +#### Условные операторы и циклы + +# В Perl есть большинсво привычных условных и циклических конструкций. + +if ( $var ) { +    ... +} elsif ( $var eq 'bar' ) { +    ... +} else { +    ... +} + +unless ( condition ) { +                   ... +               } +# Это более читаемый вариант для "if (!condition)" + +# Специфические Perl-овые пост-условия:  +print "Yow!" if $zippy; +print "We have no bananas" unless $bananas; + +#  while +  while ( condition ) { +                   ... +               } + + +# for, foreach +for ($i = 0; $i <= $max; $i++) { +                   ... +               } + +foreach (@array) { +                   print "This element is $_\n"; +               } + +for my $el (@array) { +                   print "This element is $el\n"; +               } + +#### Регулярные выражения + +# Регулярные выражения занимают важное место в Perl-е, +# и подробно описаны в разделах документации perlrequick, perlretut и других. +# Вкратце: + +# Сопоставление с образцом +if (/foo/)       { ... }  # выполняется, если $_ содержит "foo" +if ($a =~ /foo/) { ... }  # выполняется, если $a содержит "foo" + +# Простые замены + +$a =~ s/foo/bar/;         # заменяет foo на bar в строке $a +$a =~ s/foo/bar/g;        # заменяет ВСЕ ВХОЖДЕНИЯ foo на bar в строке $a + + +#### Файлы и ввод-вывод + +# Открыть файл на чтение или запись можно с помощью функции "open()". + +open(my $in,  "<",  "input.txt")  or die "Can't open input.txt: $!"; +open(my $out, ">",  "output.txt") or die "Can't open output.txt: $!"; +open(my $log, ">>", "my.log")     or die "Can't open my.log: $!"; + +# Читать из файлового дескриптора можно с помощью оператора "<>".   +# В скалярном контексте он читает одну строку из файла, в списковом --  +# читает сразу весь файл, сохраняя по одной строке в элементе массива: + +my $line  = <$in>; +my @lines = <$in>; + +#### Подпрограммы (функции) + +# Объявить функцию просто: + +sub logger { +    my $logmessage = shift; +    open my $logfile, ">>", "my.log" or die "Could not open my.log: $!"; +    print $logfile $logmessage; +} + +# Теперь можно использовать эту функцию так же, как и встроенные: + +logger("We have a logger subroutine!"); +``` + +#### Perl-модули + +Perl-овые модули предоставляют широкий набор функциональности,  +так что вы можете не изобретать заново велосипеды, а просто скачать  +нужный модуль с CPAN (http://www.cpan.org/).  +Некоторое количество самых полезных модулей включено в стандартную  +поставку Perl. + +Раздел документации perlfaq содержит вопросы и ответы о многих частых  +задачах, и часто предлагает подходящие CPAN-модули. + + +#### Unicode + +Вам наверняка понадобится работать с не-ASCII текстами. +Добавьте эти прагмы в начало скрипта: + +```perl +use utf8; +use open ':std' => ':utf8'; +``` + +Подробнее читайте в perldoc, разделы perlunicode и open. + + +#### strict, warnings + +Прагмы strict и warnings включают полезные проверки во время компиляции: + +```perl +use strict; +use warnings; +``` + +Подробнее смотрите perldoc strict и perldoc warnings. + + +#### Смотрите также + + - [perl-tutorial](http://perl-tutorial.org/) + - [обучающий раздел на www.perl.com](http://www.perl.org/learn.html) + - [perldoc в вебе](http://perldoc.perl.org/) + - встроенная справка : `perldoc perlintro` diff --git a/ru-ru/php-ru.html.markdown b/ru-ru/php-ru.html.markdown index 53b2f916..37b6a86e 100644 --- a/ru-ru/php-ru.html.markdown +++ b/ru-ru/php-ru.html.markdown @@ -5,6 +5,7 @@ contributors:      - ["Trismegiste", "https://github.com/Trismegiste"]  translators:      - ["SlaF", "https://github.com/SlaF"] +    - ["Corpsee", "https://github.com/corpsee"]  lang: ru-ru  filename: learnphp-ru.php  --- @@ -14,8 +15,8 @@ filename: learnphp-ru.php  ```php  <?php // PHP код должен быть заключен в теги <?php -// Если ваш файл содержит только PHP код, то можно -// пропустить закрывающийся ?> +// Если ваш файл содержит только PHP-код, то можно +пропустить закрывающий ?>  // А так начинаются комментарии @@ -30,10 +31,10 @@ filename: learnphp-ru.php  print('Hello '); // Напечатать "Hello " без перевода строки  // () необязательно применять для print и echo -echo "World\n"; // Печатать "World" и перейти на новую строку. +echo "World\n"; // Напечатать "World" и перейти на новую строку.  // (все утверждения должны заканчиваться ;) -// Любые символы за пределами закрывающегося тега выводятся автоматически: +// Любые символы за пределами закрывающего тега выводятся автоматически:  ?>  Hello World Again!  <?php @@ -46,7 +47,7 @@ Hello World Again!  // Переменные начинаются с символа $.  // Правильное имя переменной начинается с буквы или знака подчеркивания,  // и может содержать любые цифры, буквы, или знаки подчеркивания. -// Не рекомендуется использовать кирилические символы в именах (прим. пер.) +// Не рекомендуется использовать кириллические символы в именах (прим. пер.)  // Логические значения нечувствительны к регистру  $boolean = true;  // или TRUE или True @@ -56,7 +57,7 @@ $boolean = false; // или FALSE или False  $int1 = 12;   // => 12  $int2 = -12;  // => -12-  $int3 = 012;  // => 10 (ведущий 0 обозначает восьмеричное число) -$int4 = 0x0F; // => 15 (ведущие символы 0x означает шестнадцатеричное число) +$int4 = 0x0F; // => 15 (ведущие символы 0x означают шестнадцатеричное число)  // Дробные числа  $float = 1.234; @@ -126,7 +127,7 @@ echo 'This outputs '.FOO;  // Все массивы в PHP - это ассоциативные массивы или хеши, -// Ассоциативные массивы, известные в других языках как хеш-карты. +// Ассоциативные массивы, известные в других языках как HashMap.  // Работает во всех версиях РHP  $associative = array('One' => 1, 'Two' => 2, 'Three' => 3); @@ -199,13 +200,13 @@ assert($c > $b); // больше  assert($a <= $b); // меньше или равно  assert($c >= $d); // больше или равно -// Следующие утверждения истинны если переменные имеют одинаковый тип. +// Следующие утверждения истинны, если переменные имеют одинаковый тип.  assert($c === $d);  assert($a !== $d);  assert(1 == '1');  assert(1 !== '1'); -// Переменные могут изменять тип, в зависимости от их использования. +// Переменные могут изменять тип в зависимости от их использования.  $integer = 1;  echo $integer + $integer; // => 2 @@ -235,7 +236,7 @@ $var = null; // Null  $integer = 10;  $boolen = settype($integer, "string") // теперь $integer имеет строковый тип -// settype возвращает true - если преобразование удалось и false в противном случае +// settype возвращает true, если преобразование удалось и false в противном случае  /********************************   * Управляющие структуры @@ -311,7 +312,7 @@ echo "\n";  for ($x = 0; $x < 10; $x++) {      echo $x; -} // Prints "0123456789" +} // Напечатает "0123456789"  echo "\n"; @@ -320,7 +321,7 @@ $wheels = ['bicycle' => 2, 'car' => 4];  // Циклы foreach могут обходить массивы  foreach ($wheels as $wheel_count) {      echo $wheel_count; -} // Prints "24" +} // Напечатает "24"  echo "\n"; @@ -337,14 +338,14 @@ while ($i < 5) {          break; // Exit out of the while loop      }      echo $i++; -} // Prints "012" +} // Напечатает "012"  for ($i = 0; $i < 5; $i++) {      if ($i === 3) {          continue; // Skip this iteration of the loop      }      echo $i; -} // Prints "0124" +} // Напечатает "0124"  /******************************** @@ -369,7 +370,7 @@ function add ($x, $y = 1) { // $y по умолчанию равно 1  echo add(4); // => 5  echo add(4, 2); // => 6 -// $result недоступна за пределами функции +// $result недоступен за пределами функции  // print $result; // Выдает предупреждение  // Начиная с PHP 5.3 вы можете объявлять анонимные функции: @@ -402,27 +403,25 @@ echo $function_name(1, 2); // => 3  /******************************** - * Includes + * Включения   */  <?php  // PHP код внутри включаемого файла должен начинаться с тега PHP.  include 'my-file.php'; -// Код в файле my-file.php теперь доступен в текущем в текущем пространстве имен. -// Если файл не удалось включить, будет выдано предупреждение. +// Код в файле my-file.php теперь доступен в текущем пространстве имен. +// Если файл не удалось подключить, то будет выдано предупреждение.  include_once 'my-file.php'; -// Если код в файле my-file.php уже был включен, он не будет включен повторно. -// Это предотвращает ошибку повторного включения файла. +// Если код в файле my-file.php уже был подключен, он не будет подключен повторно. +// Это предотвращает ошибку повторного подключения файла.  require 'my-file.php';  require_once 'my-file.php'; -// Same as include(), except require() will cause a fatal error if the -// file cannot be included.  // Действует также как и include(), но если файл не удалось подключить, -// функция выдает неисправимую ошибку +// функция выдает фатальную ошибку  // Содержимое файла my-include.php:  <?php @@ -452,19 +451,19 @@ class MyClass      static $staticVar   = 'static'; -    // Properties must declare their visibility +    // Свойства объявляются с указанием их видимости      public $property    = 'public';      public $instanceProp; -    protected $prot = 'protected'; // Accessible from the class and subclasses -    private $priv   = 'private';   // Accessible within the class only +    protected $prot = 'protected'; // Свойство доступно только потомкам и самому классу +    private $priv   = 'private';   // Свойство доступно только самому классу -    // Create a constructor with __construct +    // Конструктор описывается с помощью __construct      public function __construct($instanceProp) { -        // Access instance variables with $this +        // Доступ к эземпляру класса с помощью $this          $this->instanceProp = $instanceProp;      } -    // Methods are declared as functions inside a class +    // Методы объявляются как функции принадлежащие классу      public function myMethod()      {          print 'MyClass'; @@ -484,7 +483,7 @@ echo MyClass::MY_CONST;    // Выведет 'value';  echo MyClass::$staticVar;  // Выведет 'static';  MyClass::myStaticMethod(); // Выведет 'I am static'; -// Новый экземпляр класса используя new +// Создание нового экземпляра класса используя new  $my_class = new MyClass('An instance property');  // Если аргументы отсутствуют, можно не ставить круглые скобки @@ -502,7 +501,7 @@ class MyOtherClass extends MyClass          echo $this->prot;      } -    // Override a method +    // Переопределение родительского метода      function myMethod()      {          parent::myMethod(); @@ -595,7 +594,7 @@ class SomeOtherClass implements InterfaceOne, InterfaceTwo   * Трейты   */ -// Трейты появились в PHP 5.4.0 и объявляются при помощи ключевого слова trait +// Трейты появились в PHP 5.4 и объявляются при помощи ключевого слова trait  trait MyTrait  { @@ -611,7 +610,7 @@ class MyTraitfulClass  }  $cls = new MyTraitfulClass(); -$cls->myTraitMethod(); // Prints "I have MyTrait" +$cls->myTraitMethod(); // Напечатает "I have MyTrait"  /******************************** diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown index a0e2b474..43142eff 100644 --- a/ru-ru/python-ru.html.markdown +++ b/ru-ru/python-ru.html.markdown @@ -167,6 +167,10 @@ li = []  # Можно сразу начать с заполненного списка  other_li = [4, 5, 6] +# строка разделена в список +a="adambard" +list(a) #=> ['a','d','a','m','b','a','r','d'] +  # Объекты добавляются в конец списка методом append  li.append(1)    # [1]  li.append(2)    # [1, 2] @@ -238,7 +242,6 @@ d, e, f = 4, 5, 6  # Обратите внимание, как легко поменять местами значения двух переменных  e, d = d, e     # теперь d == 5, а e == 4 -  #  Словари содержат ассоциативные массивы  empty_dict = {}  # Вот так описывается предзаполненный словарь @@ -277,7 +280,7 @@ filled_dict.get("four", 4) #=> 4  # Присваивайте значение ключам так же, как и в списках  filled_dict["four"] = 4  # теперь filled_dict["four"] => 4 -# Метод setdefault вставляет() пару ключ-значение, только если такого ключа нет +# Метод setdefault() вставляет пару ключ-значение, только если такого ключа нет  filled_dict.setdefault("five", 5) #filled_dict["five"] возвращает 5  filled_dict.setdefault("five", 6) #filled_dict["five"] по-прежнему возвращает 5 diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/python3-ru.html.markdown index 2a7b3f7b..2b6b59a7 100644 --- a/ru-ru/python3-ru.html.markdown +++ b/ru-ru/python3-ru.html.markdown @@ -549,7 +549,7 @@ Human.grunt() #=> "*grunt*"  # Вы можете импортировать модули  import math -print(math.sqrt(16)) #=> 4 +print(math.sqrt(16)) #=> 4.0  # Вы можете импортировать отдельные функции модуля  from math import ceil, floor diff --git a/ru-ru/ruby-ru.html.markdown b/ru-ru/ruby-ru.html.markdown index 318e0e09..69b5fb46 100644 --- a/ru-ru/ruby-ru.html.markdown +++ b/ru-ru/ruby-ru.html.markdown @@ -158,6 +158,7 @@ array << 6 #=> [1, 2, 3, 4, 5, 6]  hash = {'color' => 'green', 'number' => 5}  hash.keys #=> ['color', 'number'] +hash.values #=> ['green', 5]  # Значение в хэше легко может быть найдено по ключу:  hash['color'] #=> 'green' | 
