├── .gitignore ├── README.md └── book ├── appassign.md ├── appbin.md ├── appdatetime.md ├── appencode.md ├── appfile.md ├── appformat.md ├── appio.md ├── apppack.md ├── appregexp.md ├── args.md ├── array.md ├── author.md ├── book.tex ├── complex.md ├── conclusion.md ├── datatype.md ├── datetime.md ├── dir.md ├── encode.md ├── enumerable.md ├── enumerate.tex ├── enumerator.md ├── exception.md ├── execution.md ├── expression.md ├── file.md ├── filestat.md ├── float.md ├── hash.md ├── identificate.md ├── integer.md ├── intro.md ├── io.tex ├── library.md ├── math.md ├── number.tex ├── numeric.md ├── object.md ├── oop.md ├── random.md ├── range.md ├── rational.md ├── regexp.md ├── security.md ├── standart.md ├── stream.md ├── string.md ├── subroutine.md ├── test.md ├── text.tex └── thread.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | *.aux 3 | *.toc 4 | *.log 5 | *.out 6 | *.fls 7 | *.tex 8 | *.fdb_latexmk 9 | !book.tex 10 | !io.tex 11 | !number.tex 12 | !text.tex 13 | !enumerate.tex 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Внимание! 2 | 3 | Эта книга была написана начинающим разработчиком в то время, когда доступной информации было гораздо меньше чем сейчас. Она устарела, содержит много ошибок и не рекомендуется в качестве достоверного источника (в особенности тем, кто только начинает знакомиться с программированием). Репозиторий сохранен для истории. 4 | 5 | ------------------------- 6 | 7 | # От автора 8 | 9 | Текст книги в формате PDF доступен по адресу: 10 | 11 | 12 | ###### Сборка: 13 | 14 | 1. Установить Ruby. 15 | 2. Установить необходимые пакеты - `gem install redcarpet`. 16 | 3. Скачать скрипт для преобразования Markdown в LaTeX 17 | . 18 | 4. Установить XeLaTeX. 19 | 5. Скачать стиль - . 20 | 6. Собрать pdf - `xelatex book.tex` (по умолчанию используются шрифты семейства Liberation). 21 | 22 | ###### Контакты: 23 | 24 | + Исходники: 25 | + Автор: 26 | -------------------------------------------------------------------------------- /book/appassign.md: -------------------------------------------------------------------------------- 1 | # Присваивание 2 | [](appassign) 3 | 4 | Синтаксис выражения: 5 | 6 | + Для одного идентификатора и одного объекта выполняется стандартное присваивание. Возвращается ссылка на объект. 7 | `x = ?R # -> "R"` 8 | 9 | + Для нескольких идентификаторов и одного объекта, сначала вызывается метод `object.to_ary`, а затем в присваивании участвуют все полученные элементы. Возвращается ссылка на массив. 10 | 11 | ~~~~~ ruby 12 | x, y = [ 1, 2 ] # -> [ 1, 2 ] 13 | x # -> 1 14 | y # -> 2 15 | ~~~~~ 16 | 17 | + Для одного идентификатора и нескольких объектов выполняется присваивание массива, содержащего все объекты. Возвращается ссылка на массив. 18 | 19 | ~~~~~ ruby 20 | x = ?Y, ?N # -> [ "Y", "N" ] 21 | x # -> "Y" 22 | ~~~~~ 23 | 24 | + Для одинакового количества идентификаторов и объектов выполняется параллельное присваивание. Возвращается ссылка на массив из всех использованных объектов. 25 | 26 | ~~~~~ ruby 27 | x, y = ?Y, ?N # -> [ "Y", "N" ]; 28 | x # -> "Y" 29 | y# -> "N" 30 | 31 | x, y = y, x # -> [ "N", "Y" ] 32 | x # -> "N" 33 | y # -> "Y" 34 | ~~~~~ 35 | 36 | + Если за идентификатором следует запятая, то интерпретатор считает, что после нее указан еще один идентификатор. Этот идентификатор участвует в присваивании, даже если фактически не присутствует. 37 | 38 | ~~~~~ ruby 39 | x, = ?Y, ?N # -> [ "Y", "N" ] 40 | x# -> "Y" 41 | ~~~~~ 42 | 43 | + Когда идентификаторов больше, чем объектов, выполняется параллельное присваивание. Лишние идентификаторы объявляются, но не инициализируются. Возвращается ссылка на массив из всех использованных объектов. 44 | 45 | ~~~~~ ruby 46 | x, y, z = ?Y, ?N # -> [ "Y", "N" ] 47 | x # -> "Y" 48 | y # -> "N" 49 | z # -> nil 50 | ~~~~~ 51 | 52 | + Когда идентификаторов меньше, чем объектов, выполняется параллельное присваивание только тех идентификаторов, для которых хватило объектов. Возвращается ссылка на массив из всех использованных объектов. 53 | 54 | ~~~~~ ruby 55 | x, y = ?Y, ?N, ?Q # -> [ "Y", "N", "Q" ] 56 | x # -> "Y" 57 | y # -> "N" 58 | ~~~~~ 59 | 60 | + Если перед объектом стоит символ звездочки (*), то объект обрабатывается как составной. Интерпретатор использует для присваивания все элементы объекта (с помощью метода `object.to_splat`). Возвращается ссылка на массив из всех использованных объектов. 61 | 62 | Запись двух символов звездочки подряд считается исключением. При извлечении элементов вложенных массивов символ звездочки необходимо записывать перед каждым вложенным массивом. 63 | 64 | ~~~~~ ruby 65 | x, y = *(1..3) # -> [ 1, 2, 3 ] 66 | x # -> 1 67 | y # -> 2 68 | ~~~~~ 69 | 70 | + Если перед идентификатором стоит символ звездочки (*), то интерпретатор использует для присваивания массив из всех лишних объектов. Возвращается ссылка на массив из всех использованных объектов. 71 | 72 | ~~~~~ ruby 73 | *x, y = ?Y, ?N # -> [ "Y", "N" ] 74 | x # -> [ "Y" ] 75 | y # -> "N" 76 | 77 | *x, y = ?Y, ?N, ?Q # -> [ "Y", "N", "Q" ] 78 | x # -> [ "Y", "N" ] 79 | y # ->"Q" 80 | 81 | x, *y, z = ?Y, ?N, ?Q, ?R # -> [ "Y", "N", "Q", "R" ] 82 | x # ->"Y" 83 | y # ->[ "N", "Q" ] 84 | z # ->"R" 85 | ~~~~~ 86 | 87 | + Для идентификаторов, ограниченных круглыми скобками одновременно выполняется несколько выражений присваивания: 88 | 1. Группа обрабатывается как одна логическая единица; 89 | 2. Интерпретатор извлекает идентификаторы из группы. 90 | 91 | Возвращается ссылка на массив из всех использованных объектов. 92 | 93 | ~~~~~ ruby 94 | x, (y, z) = ?Y, ?N # -> [ "Y", "N" ] 95 | x = ?Y 96 | (y, z) = ?N 97 | y, z = ?N 98 | y = ?N 99 | z = nil 100 | ~~~~~ -------------------------------------------------------------------------------- /book/appbin.md: -------------------------------------------------------------------------------- 1 | # Запуск программы 2 | [](appbin) 3 | 4 | ##### Ключи: 5 | 6 | `--copyright` - отображение сведений о копирайте; 7 | 8 | `--version` - отображение версии интерпретатора; 9 | 10 | `-(-h)elp` - отображение справочной информации; 11 | 12 | `-0 [codepoint]` - изменение символа перевода строки, использующегося при чтении из потока (`$/`). Кодовая позиция задается в восьмеричной системе счисления. 13 | 14 | + Если кодовая позиция не указана, то строки разделятся не будут; 15 | + Если указана позиция -00, то в качестве разделителя будут использоваться два символа перевода строки подряд; 16 | + Если указана позиция -0777, то файлы буду обрабатываться как одна большая строка. 17 | 18 | `-C (-X) ` - изменение базового каталога; 19 | 20 | `--encoding (-E) [:internal]` - изменение внешней и внутренней кодировок; 21 | 22 | `-F ` - изменение разделителя частей текста (`$;`), использующегося при вызове метода `.split`. В качестве образца передаются произвольные символы или тело регулярного выражения; 23 | 24 | `-I ` - добавление дополнительных каталогов. Данные каталоги будут добавлены в начало `$LOAD_PATH ($:)` и использованы для поиска необходимых библиотек. Каталоги разделяются двоеточием (Linux) или точкой с запятой (Windows); 25 | 26 | `-K ` - изменение внешней и внутренней кодировок. 27 | 28 | + _e_ - EUC-JP; 29 | _s_ - Windows-31J (CP932); 30 | _u_ - UTF-8; 31 | _n_ - ASCII-8BIT (BINARY). 32 | 33 | `-S` - поиск программы с помощью переменной окружения PATH; 34 | 35 | `-T [security]` - изменение уровня безопасности для программы (по умолчанию 1); 36 | 37 | `-U` - использование UTF-8 в качестве внутренней кодировки; 38 | 39 | `-W [verbose]` - изменение степени подробности отладочной информации: 40 | 41 | + _0_ - без предупреждений, `$VERBOSE` ссылается на nil; 42 | _1_ - средний уровень, `$VERBOSE` ссылается на false; 43 | _2_ (по умолчанию) - выводятся все предупреждения, `$VERBOSE` ссылается на true. 44 | 45 | `-a` - автоматическое разделение кода на строки при использовании ключей `-n` или `-p`. В начале каждой итерации цикла выполняется код: `$F = $_.split!`; 46 | 47 | `-c` - проверка синтаксиса. Если ошибок не найдено, то в стандартный поток для вывода передается `"Syntax OK"`; 48 | 49 | `-(-d)ebug` - запуск в режиме отладки (`$DEBUG` ссылается на true). 50 | 51 | Наличие ключа позволяет писать код для отладки программы, который будет выполняться только если `$DEBUG` ссылается на true; 52 | `{verbatim} if $DEBUG` 53 | 54 | `-e ` - выполнение произвольного кода; 55 | 56 | `-i [ext]` - запуск в режиме редактирования, позволяющий записывать данные с помощью ARGF. Расширение используется для создания резервных копий файлов; 57 | 58 | `-l` - автоматическое изменение кода. При этом, во-первых, `$\` копирует `$/`, и, во-вторых, для каждой строки вызывается метод `.chop!`; 59 | 60 | `-n` - выполнение программы в теле цикла (каждая строка программы выполняется отдельно): 61 | 62 | ~~~~~ ruby 63 | while gets 64 | # code 65 | end 66 | ~~~~~ 67 | 68 | `-p` - выполнение программы в теле цикла (каждая строка кода выполняется отдельно, результат передается в стандартный поток для вывода): 69 | 70 | ~~~~~ ruby 71 | while gets 72 | # code 73 | end 74 | print 75 | ~~~~~ 76 | 77 | `-r ` - загрузка дополнительной библиотеки перед выполнением с помощью `.require`; 78 | 79 | `-s` - предварительная обработка аргументов, начинающихся с дефиса. Обработка выполняется до любого обычного аргумента или символов `--`. Обработанные аргументы будут удалены из ARGV. 80 | 81 | + Для аргументов вида `-x=y`, `$x` в теле программы будет ссылаться на y; 82 | + Для аргументов вида `-x`, `$x` в теле программы будет ссылаться на true. 83 | 84 | `-(-v)erbose` - запуск программы с ключом -w. Если имя программы не указано, то отображается версия интерпретатора. 85 | 86 | Наличие ключа позволяет писать код для отладки программы, который будет выполняться только если `$VERBOSE` ссылается на true; 87 | `{verbatim} if $VERBOSE` 88 | 89 | `-w` - отображение всех возможных предупреждений (`$VERBOSE` ссылается на true); 90 | 91 | `-x [dir]` - отображение кода программы со строки, начинающейся с `!#` и содержащей `ruby`. Конец программы должен быть указан с помощью EOF (обозначение конца файла), `^D` (control-D), `^Z` (control-Z), или `__END__`. Переданный каталог используется вместо базового; 92 | 93 | `-(-y)ydebug` - используется для отладки интерпретатора; 94 | 95 | `--disable-... (--enable-...)` - включение или отключение указанной опции: 96 | 97 | + _gems_ - поиск библиотек в пакетах (отключение этой опции может ускорить запуск программы); 98 | _rubyopt_ - использование переменной окружения RUBYOPT; 99 | _all_ - выполнение двух перечисленных действий. 100 | 101 | `--dump ` - используется для отладки интерпретатора. 102 | 103 | ***** 104 | 105 | ##### Переменные окружения: 106 | 107 | `RUBYLIB` - список каталогов, используемых для поиска библиотек; 108 | 109 | `RUBYOPT` - список ключей, используемых для запуска программ. Могут быть добавлены только ключи -d, -E, -I, -K, -r, -T, -U, -v, -w, -W, `--debug, --disable-...` и `--enable-...`; 110 | 111 | `RUBYPATH` - список каталогов, в которых выполняется поиск программы; 112 | 113 | `RUBYSHELL` - путь к оболочке ОС. Переменная действительна только для mswin32, mingw32, и OS/2; 114 | 115 | `PATH` - путь к интерпретатору. 116 | 117 | ***** 118 | 119 | Доступ к перемнным окружения может быть получен с помощью ENV - объекта, подобный ассоциативному массиву. Для объекта определен метод `.to_hash`, преобразующий его в настоящий ассоциативный массив. 120 | 121 | ##### Глобальные переменные: 122 | 123 | `$F` - результат последнего выполнения выражения `$_.split`. Переменная определена, если программа запущена с ключами -a, -n или -p; 124 | 125 | `$-W` - степень подробности предупреждений; 126 | 127 | `$-i` - расширение, используемое для резервных копий; 128 | 129 | `$-d # -> bool`; 130 | 131 | `$-l # -> bool`; 132 | 133 | `$-v # -> bool`; 134 | 135 | `$-p # -> bool`; 136 | 137 | `$-a # -> bool`; 138 | 139 | `$*` - массив аргументов, переданных при запуске программы; 140 | 141 | `$>` - поток для записи по умолчанию; 142 | 143 | `$; ($-F)` - используется при вызове метода `string.split`. Разделитель частей текста (по умолчанию nil); 144 | 145 | `$/ ($-0)` - используется `kernel.gets`. Символ перевода строки (по умолчанию - `"\n"`). Если ссылается на nil, то вызов метода вернет весь текст; 146 | 147 | `$\\` - разделитель, добавляемый при передаче объектов в поток (по умолчанию nil); 148 | 149 | `$,` - используется при вызове методов `array.join` и `kernel.printf` Разделитель элементов (по умолчанию nil); 150 | 151 | `$~` - экземпляр класса MatchData для последнего поиска совпадений; 152 | 153 | `$&` - текст последнего найденного совпадения; 154 | 155 | ``$` `` - текст, предшествующий последнему найденным совпадением; 156 | 157 | `$'` - текст, следующий за последним найденным совпадением; 158 | 159 | `$+` - текст последнего совпадения с группой; 160 | 161 | `$1, $2, $3, $4, $5, $6, $7, $8, $9` - текст последнего совпадения с группой, имеющей соответствующий индекс; 162 | 163 | `$LOAD_FEAUTURES ($")` - массив всех использованных библиотек (изменение значения элементов запрещено в Ruby 2.0; для объектов не относящихся к String вызывается метод `object.to_path`); 164 | 165 | `$LOAD_PATH ($:, $-I)` - массив каталогов, использующихся для поиска библиотек (изменение значения элементов запрещено в Ruby 2.0; для объектов не относящихся к String вызывается метод `object.to_path`); 166 | 167 | `$.` - позиция последней извлеченной строки из потока; 168 | 169 | `$_` - последняя извлеченная строка из потока; 170 | 171 | `$!` - последнее полученное исключение; 172 | 173 | `$@` - местоположение в коде последнего полученного исключения; 174 | 175 | `$DEBUG` - true, если программа запущена с ключом `-(-d)ebug`; 176 | 177 | `$VERBOSE ($-v, $-w)` 178 | 179 | + _nil_, если программа запущена с ключом `-W0`; 180 | _true_, если программа запущена с ключами `-w` или `-(-v)erbose`; 181 | _false_ в остальных случаях. 182 | 183 | `$$` - идентификатор текущего процесса; 184 | 185 | `$?` - статус последнего выполненного процесса; 186 | 187 | `$FILENAME` - относительный путь к текущему файлу в ARGF. При взаимодействии с стандартным потоком для ввода возвращается `"-"`; 188 | 189 | `$SAFE` - текущий уровень безопасности. 190 | 191 | ***** -------------------------------------------------------------------------------- /book/appdatetime.md: -------------------------------------------------------------------------------- 1 | # Форматирование времени 2 | [](appdatetime) 3 | 4 | Форматная строка состоит из групп символов вида: 5 | `%[модификатор][размер][спецсимвол]`. 6 | 7 | Любой текст, не относящийся к спецсимволам или модификаторам переносится в результат без изменений. 8 | 9 | Размер влияет на количество символов в результате. Если размер меньше, чем необходимое количество символов, то он игнорируется интерпретатором. 10 | 11 | ##### Модификаторы: 12 | 13 | `-` - ограничение размера игнорируется; 14 | 15 | `_` - для выделения используются пробелы; 16 | 17 | `0` - для выделения используются нули (по умолчанию); 18 | 19 | `^` - результат в верхнем регистре; 20 | 21 | `#` - изменяется регистр символов. 22 | 23 | ***** 24 | 25 | ##### Год: 26 | 27 | `%Y` - номер года с веком; 28 | 29 | ~~~~~ ruby 30 | Time.local( 1990, 3, 31 ).strftime "Год: %Y" # -> "Год: 1990" 31 | Time.local( 1990, 3, 31 ).strftime "Год: %7Y" # -> "Год: 0001990" 32 | Time.local( 1990, 3, 31 ).strftime "Год: %-7Y" # -> "Год: 1990" 33 | Time.local( 1990, 3, 31 ).strftime "Год: %_7Y" # -> "Год: 1990" 34 | Time.local( 1990, 3, 31 ).strftime "Год: %07Y" # -> "Год: 0001990" 35 | ~~~~~ 36 | 37 | `%G` - номер года с веком, считая от первого понедельника; 38 | `Time.local( 1990, 3, 31 ).strftime "Год: %G" # -> "Год: 1990"` 39 | 40 | `%y` - остаток от деления номера года на 100 (от 00 до 99); 41 | `Time.local( 1990, 3, 31 ).strftime "Год: %y" # -> "Год: 90"` 42 | 43 | `%g` - остаток от деления номера года на 100 (от 00 до 99), считая от первого понедельника; 44 | `Time.local( 1990, 3, 31 ).strftime "Год: %g" # -> "Год: 90"` 45 | 46 | `%C` - номер года, разделенный на 100 (20 в 2011); 47 | `Time.local( 1990, 3, 31 ).strftime "Век: %C" # -> "Век: 19"` 48 | 49 | ***** 50 | 51 | ##### Месяц: 52 | 53 | `%b (%h)` - аббревиатура названия месяца (три первые английские буквы); 54 | `Time.local( 1990, 3, 31 ).strftime "Месяц: %b" -> "Месяц: Mar"` 55 | 56 | `%B` - полное названию месяца; 57 | 58 | ~~~~~ ruby 59 | Time.local(1990, 3, 31).strftime "Месяц: %B" # -> "Месяц: March" 60 | Time.local(1990, 3, 31).strftime "Месяц: %^B" # -> "Месяц: MARCH" 61 | Time.local(1990, 3, 31).strftime "Месяц: %#B" # -> "Месяц: MARCH" 62 | ~~~~~ 63 | 64 | `%m` - номер месяца (от 01 до 12); 65 | `Time.local( 1990, 3, 31 ).strftime "Месяц: %m" -> "Месяц: 03"` 66 | 67 | ***** 68 | 69 | ##### Неделя: 70 | 71 | `%U` - номер недели (от 00 до 53), считая от первого воскресенья в году; 72 | `Time.local( 1990, 3, 31 ).strftime "Неделя: %U" -> "Неделя: 12"` 73 | 74 | `%W` - номер недели (от 00 до 53), считая от первого понедельника в году; 75 | `Time.local( 1990, 3, 31 ).strftime "Неделя: %W" -> "Неделя: 13"` 76 | 77 | `%V` - номер недели (номер недели в формате ISO 8601 - от 01 до 53); 78 | `Time.local( 1990, 3, 31 ).strftime "Неделя: %V" -> "Неделя: 13"` 79 | 80 | ***** 81 | 82 | ##### День: 83 | 84 | `%j` - номер дня в году (от 001 до 366); 85 | `Time.local( 1990, 3, 31 ).strftime "День: %j" # -> "День: 090"` 86 | 87 | `%d` - номер дня в месяце; 88 | `Time.local( 1990, 3, 3 ).strftime "День: %d" # -> "День: 03"` 89 | 90 | `%e` - номер дня в месяце; 91 | `Time.local( 1990, 3, 3 ).strftime "День: %e" # -> "День: 3"` 92 | 93 | `%a` - аббревиатура дня недели (три первые английские буквы); 94 | `Time.local( 1990, 3, 31 ).strftime "День: %a" # -> "День: Sat"` 95 | 96 | `%A` - полное название дня недели; 97 | `Time.local( 1990, 3, 31 ).strftime "День: %A" # -> "День: Saturday"` 98 | 99 | `%u` - номер дня недели (от 1 до 7, понедельник - 1); 100 | `Time.local( 1990, 3, 31 ).strftime "День: %u" # -> "День: 6"` 101 | 102 | `%w` - номер дня недели (от 0 до 6, воскресенье - 0); 103 | `Time.local( 1990, 3, 31 ).strftime "День: %w" # -> "День: 6"` 104 | 105 | ***** 106 | 107 | ##### Час: 108 | 109 | `%H` - час дня в 24 часовом формате (от 00 до 23); 110 | `Time.local( 1990, 3, 31 ).strftime "Час: %H" # -> "Час: 00"` 111 | 112 | `%k` - час дня в 24 часовом формате (от 0 до 23); 113 | `Time.local( 1990, 3, 31 ).strftime "Час: %k" # -> "Час: 0"` 114 | 115 | `%I` - час дня в 12 часовом формате (от 01 до 12); 116 | `Time.local( 1990, 3, 31 ).strftime "Час: %I" # -> "Час: 12"` 117 | 118 | `%l` - час дня в 12 часовом формате, с приставкой-пробелом (от 0 до 12); 119 | `Time.local( 1990, 3, 31 ).strftime "Час: %l" # -> "Час: 12"` 120 | 121 | `%p` - индикатор меридиана ("AM" или "PM"); 122 | `Time.local( 1990, 3, 31 ).strftime "%I %p" # -> "12 AM"` 123 | 124 | `%P` - индикатор меридиана ("am" или "pm"); 125 | `Time.local( 1990, 3, 31 ).strftime "%I %P" # -> "12 am"` 126 | 127 | ***** 128 | 129 | ##### Минуты и секунды: 130 | 131 | `%M` - количество минут (от 00 до 59); 132 | `Time.local( 1990, 3, 31 ).strftime "мин: %M" # -> "мин: 00"` 133 | 134 | `%S` - количество секунд (от 00 до 60); 135 | `Time.local( 1990, 3, 31 ).strftime "сек: %S" # -> "сек: 00"` 136 | 137 | `%N` - дробная часть секунд. 138 | 139 | + _%3N_ - миллисекунды; 140 | _%6N_ - микросекунды; 141 | _%9N_ - наносекунды (по умолчанию); 142 | _%12N_ - пикосекунды. 143 | 144 | `%L` - количество миллисекунд (от 000 до 999); 145 | `Time.local( 1990, 3, 31 ).strftime "мс: %L" # -> "мс: 000"` 146 | 147 | `%s` - количество секунд, прошедших начиная с 1970-01-01 00:00:00 UTC; 148 | `Time.local( 1990, 3, 31 ).strftime "%s" # -> "638827200"` 149 | 150 | ***** 151 | 152 | ##### Форматы: 153 | 154 | `%D` - форматная строка `"%m/%d/%y"`; 155 | 156 | ~~~~~ ruby 157 | Time.local( 1990, 3, 31 ).strftime "Дата: %D" 158 | # -> "Дата: 03/31/90" 159 | ~~~~~ 160 | 161 | `%F` - форматная строка `"%Y-%m-%d"` (время в формате ISO 8601); 162 | 163 | ~~~~~ ruby 164 | Time.local( 1990, 3, 31 ).strftime "Дата: %F" 165 | # -> "Дата: 1990-03-31" 166 | ~~~~~ 167 | 168 | `%v` - форматная строка `"%e-%b-%Y"` (время в формате VMS); 169 | 170 | ~~~~~ ruby 171 | Time.local( 1990, 3, 31 ).strftime "Дата: %v" 172 | # -> "Дата: 31-MAR-1990" 173 | ~~~~~ 174 | 175 | `%c` - формат системы; 176 | 177 | ~~~~~ ruby 178 | Time.local( 1990, 3, 31 ).strftime "Система: %c" 179 | # -> "Система: Sat Mar 31 00:00:00 1990" 180 | ~~~~~ 181 | 182 | `%r` - форматная строка `"%I:%M:%S %p"`; 183 | `Time.local( 1990, 3, 31 ).strftime "%r" # -> "12:00:00 AM"` 184 | 185 | `%R` - форматная строка `"%H:%M"`; 186 | `Time.local( 1990, 3, 31 ).strftime "%R" # -> "00:00"` 187 | 188 | `%T` - форматная строка `"%H:%M:%S"`; 189 | `Time.local( 1990, 3, 31 ).strftime "%T" # -> "00:00:00"` 190 | 191 | ***** 192 | 193 | ##### Форматирование: 194 | 195 | `%n` - перевод строки; 196 | 197 | ~~~~~ ruby 198 | Time.local( 1990, 3, 31 ).strftime "%D %n %F %n %c" 199 | # -> "03/31/90 \n 1990-03-31 \n Sat Mar 31 00:00:00 1990" 200 | ~~~~~ 201 | 202 | `%t` - отступ; 203 | 204 | ~~~~~ ruby 205 | Time.local( 1990, 3, 31 ).strftime "%D %t %F %t %c" 206 | # -> "03/31/90 \t 1990-03-31 \t Sat Mar 31 00:00:00 1990" 207 | ~~~~~ 208 | 209 | ***** 210 | 211 | ##### Остальное: 212 | 213 | `%x` - только дата; 214 | `Time.local( 1990, 3, 31 ).strftime "%x" # -> "03/31/90"` 215 | 216 | `%X` - только время; 217 | `Time.local( 1990, 3, 31 ).strftime "%X" # -> "00:00:00"` 218 | 219 | `%z` - смещение часового пояса относительно UTC; 220 | `Time.local( 1990, 3, 31 ).strftime "%z" # -> "+0400"` 221 | 222 | + _%:z_ - часы и минуты разделяются с помощью двоеточия; 223 | `Time.local( 1990, 3, 31 ).strftime "%:z" # -> "+04:00"` 224 | 225 | _%::z_ - часы, минуты и секунды разделяются с помощью двоеточия; 226 | `Time.local( 1990, 3, 31 ).strftime "%::z" # -> "+04:00:00"` 227 | 228 | `%Z` - название временной зоны; 229 | `Time.local( 1990, 3, 31 ).strftime "%Z" # -> "MSD"` 230 | 231 | `%%` - знак процента. 232 | 233 | ***** -------------------------------------------------------------------------------- /book/appencode.md: -------------------------------------------------------------------------------- 1 | # Преобразование кодировок 2 | [](appencode) 3 | 4 | ##### Принимаемые элементы: 5 | 6 | `replace:` текст, использующийся для замены символов. По умолчанию используется `uFFFD` для символов Unicode и `?` для других символов; 7 | 8 | `:invalid => :replace` - замена ошибочных байтов; 9 | 10 | `:undef => :replace` - замена отсутствующих символов; 11 | 12 | `:fallback => encoding` - изменение кодировки отсутствующих символов; 13 | 14 | `:xml => :text` - экранирование символов из XML CharData. Результат может быть использован в HTML 4.0: 15 | 16 | + & на `&`; 17 | + < на `<`; 18 | + > на `>`; 19 | + замена отсутствующих символов на байты вида `&x` (где x - цифра в шестнадцатеричной системе счисления). 20 | 21 | `:xml => :attr` - экранирование символов из XML AttrValue. Результат выделяется двойными кавычками и может быть использован для значений свойств в HTML 4.0: 22 | 23 | + & на `&`; 24 | + < на `<`; 25 | + > на `>`; 26 | + `"` на `"`; 27 | + замена отсутствующих символов на байты вида `&x` (где x - цифра в шестнадцатеричной системе счисления). 28 | 29 | `cr_newline:` true - символы LF (\n) заменяются на CR (\r); 30 | 31 | `crlf_newline:` true - символы LF (\n) заменяются на CRLF (\r\n); 32 | 33 | `universal_newline:` true - символы CR (\r) и CRLF (\r\n) заменяются на LF (\n). 34 | 35 | ***** -------------------------------------------------------------------------------- /book/appfile.md: -------------------------------------------------------------------------------- 1 | # Файловая система Linux 2 | [](appfile) 3 | 4 | Файл - это фундаментальная абстракция в Linux (практически любая сущность считается файлом). Операции с файлами осуществляются с помощью файловых дескрипторов (цифровых идентификаторов). 5 | 6 | ## Типы файлов 7 | 8 | + _Обычный файл_ - файл, позволяющий вводить или выводить данные, а также перемещаться по ним с помощью буферизации (сохранения данных в буфер); 9 | 10 | + _Жесткая ссылка_ - файл, ссылающийся на другой файл. 11 | 12 | Жесткие ссылки необходимы, чтобы использовать нескольких имен для одного файла. При этом все жесткие ссылки равноправны - файл будет удален только в том случае, если удалены все жесткие ссылки на него. 13 | 14 | Изменение любой жесткой ссылки повлияет на связанный с ней файл. 15 | 16 | Создание жестких ссылок возможно только на одном физическом носителе информации (жестком диске, карте памяти и т.д.); 17 | 18 | + _Символьная ссылка (ярлык)_ - файл, ссылающийся на другой файл. 19 | 20 | Ярлыки необходимы, чтобы использовать нескольких имен для одного файла. При этом существует одно основное имя - файл будет удален только в том случае, если удален основной файл. 21 | 1. Изменение любой символьной ссылки повлияет только на саму ссылку. 22 | 2. Изменение основного файла повлияет на все связанные с ним ссылки; 23 | 24 | + _Блочное устройство_ - файл, обеспечивающий интерфейс доступа к какому-либо устройству. 25 | 26 | Ввод и вывод данных в блочные устройства выполняется в виде блоков, размер которых устанавливается блочным устройством. При этом существует возможность перемещаться по данным в пределах блочного устройства. Жесткий диск - это один из примеров блочных устройств; 27 | 28 | + _Символьное устройство_ - файл, обеспечивающий интерфейс доступа к какому-либо устройству. 29 | 30 | Ввод и вывод данных в символьное устройство выполняется в виде отдельных байтов. Обычно ввод и вывод данных не буферизуется и не существует возможности перемещаться по данным в пределах символьного устройства. Терминалы или модемы - это примеры символьных устройств. 31 | 32 | + _Сокет_ - файл, обеспечивающий коммуникацию между различными процессами, которые могут выполняться на разных компьютерах. 33 | 34 | ## Поиск файлов 35 | 36 | Поиск файлов выполняется с помощью путей. 37 | 38 | + Путь в Ruby - это текст или любой другой объект, отвечающий на вызов метода `object.to_path`. 39 | + Путь в файловой системе - это полный список имен каталогов, (заканчивающийся именем самого файла), по которому может быть найден файл. 40 | 41 | ###### Виды путей: 42 | 43 | + _Абсолютный путь_ - путь к файлу, начинающийся от корневого каталога или буквы диска; 44 | _Относительный путь_ - путь к файлу, относительно текущего каталога. 45 | 46 | 47 | ##### Спецсимволы: 48 | 49 | + Для перемещения на один каталог вверх, используется `..`; 50 | + Для обозначения текущего каталога используется `.`; 51 | + Для обозначения домашнего каталога используется `~`; 52 | + Для разделения каталогов в Windows используется символ обратной косой черты (`\`), а в Linux - символ косой черты (/); 53 | + Расширение файла отделяется точкой от его имени. 54 | 55 | `*` - соответствует любому файлу или любой группе символов в имени файла; 56 | 57 | `**` - соответствует любому каталогу в имени файла (включая символ разделителя); 58 | 59 | `?` - соответствует любому одиночному символу в имени файла; 60 | 61 | `[...]` - соответствует любому одному символу в имени файла из указанных в квадратных скобках; 62 | 63 | `[^...]` - соответствует любому одному символу в имени файла, кроме указанных в квадратных скобках; 64 | 65 | `{ }` - логическое или между символами, разделенными запятыми (Ruby 2.0). 66 | 67 | ***** 68 | 69 | Также существует набор констант, влияющих на поиск. 70 | 71 | ##### Константы: 72 | 73 | `File::FNM_SYSCASE` - чувствительность к регистру зависит от ОС (действует по умолчанию); 74 | 75 | `File::FNM_CASEFOLD` - игнорирование регистра; 76 | 77 | `File::FNM_PATHNAME` - спецсимвол ?, не будет соответствовать косой черте (символу разделителя); 78 | 79 | `File::FNM_NOESCAPE` - обратная косая черта будет соответствовать самой себе, а не экранировать следующий символ; 80 | 81 | `File::FNM_DOTMATCH` - знак точки в имени файла будет считаться частью имени, а не разделителем для расширения (используется для поиска скрытых файлов в Linux); 82 | 83 | `File::FNM_EXTGLOB` - фигурные скобки в имени файла будут содержать выражение логического ИЛИ (Ruby 2.0). 84 | 85 | ***** 86 | 87 | ~~~~~ note 88 | Использовать несколько констант можно с помощью выражения побитового ИЛИ. Тем, кто хочет разобраться почему это работает, следует изучить двоичную арифметику. 89 | ~~~~~ 90 | 91 | ## Доступ к файлам 92 | 93 | В некоторых файловых системах предусмотрена возможность ограничения доступа пользователей к содержимому файла. При этом обычно выделяют три типа прав: право на чтение, право на запись и право на выполнение. 94 | 95 | Права доступа устанавливаются с помощью четырех целых чисел. Каждая цифра соответствует двоичному биту, добавляемому к файлу. Права доступа устанавливаются для определенного пользователя, определенной группы и для всех пользователей (идентификаторы пользователя и группы устанавливаются отдельно). 96 | 97 | + Первая цифра считается дополнительной и определяет либо различные способы запуска файла, либо дополнительное условие для каталогов; 98 | + Оставшиеся три цифры объявляют права доступа для пользователя, для группы и всех остальных пользователей соответственно. 99 | 100 | Данные цифровые коды могут быть применены и в Windows. При этом допускается ограничивать доступ только для чтения и записи информации. 101 | 102 | ##### Основные права (permission): 103 | 104 | `700` - пользователь имеет право на чтение, запись и выполнение; 105 | 106 | `400` - пользователь имеет право на чтение; 107 | 108 | `200` - пользователь имеет право на запись; 109 | 110 | `100` - пользователь имеет право на выполнение (или право на просмотр каталога); 111 | 112 | `70` - группа имеет право на чтение, запись и выполнение; 113 | 114 | `40` - группа имеет право на чтение; 115 | 116 | `20` - группа имеет право на запись; 117 | 118 | `10` - группа имеет право на выполнение (или право на просмотр каталога); 119 | 120 | `7` - все остальные пользователи имеют право на чтение, запись и выполнение; 121 | 122 | `4` - все остальные пользователи имеют право на чтение; 123 | 124 | `2` - все остальные пользователи имеют право на запись; 125 | 126 | `1` - все остальные пользователи имеют право на выполнение файла (или право на просмотр каталога). 127 | 128 | ***** 129 | 130 | По умолчанию файл выполняется от имени того пользователя, которым файл был запущен. 131 | 132 | ##### Дополнительные права: 133 | 134 | `4000` - файл запускается от имени владельца; 135 | 136 | `2000` - файл запускается от имени установленной группы пользователей; 137 | 138 | `1000` - из каталога можно удалить только те файлы, владельцем которых является пользователь. 139 | 140 | ***** 141 | 142 | Права доступа определяются после сложения чисел, объявляющих доступ для отдельных категорий пользователей. 143 | 144 | _0444_ - любой пользователь имеет право только на чтение информации из файла. 145 | 146 | Привилегии пользователей определяются с помощью цифровых идентификаторов. Каждый пользователь имеет четыре вида идентификаторов; 147 | 148 | + _UID_ - реальный идентификатор пользователя, запустившего файл; 149 | _EUID_ - действующий идентификатор пользователя, с которым файл выполняется; 150 | _GUID_ - реальный идентификатор группы, к которой относится пользователь, запустивший файл; 151 | _EGUID_ - действующий идентификатор группы пользователей, с которым файл выполняется; 152 | 153 | Для проверки привилегий пользователя обычно используется действующий идентификатор. 154 | 155 | Доступ к файлу также может быть ограничен с помощью набора констант, передаваемых при открытии файла. 156 | 157 | ## Открытие файла 158 | 159 | ##### Константы: 160 | 161 | `File::RDONLY` - файл открывается только для чтения; 162 | 163 | `File::WRONLY` - файл открывается только для записи; 164 | 165 | `File::RDWR` - файл открывается как для чтения, так и для записи; 166 | 167 | `File::APPEND` - запись данных в конец файла (разрешение на запись необходимо устанавливать отдельно); 168 | 169 | `File::CREAT` - создание нового файла. Определение владельца выполняется по действующему идентификатору. Определение группы выполняется по идентификатору группы для программы или для базового каталога; 170 | 171 | `File::DIRECT` - ограничение кэширования содержимого файла; 172 | 173 | `File::EXCL` - ограничение возможности создания ярлыков; 174 | 175 | `File::NONBLOCK` - если система не готова выполнить запрос к файлу немедленно, то процесс выполнения не блокируется, а получает сигнал от системы; 176 | 177 | `File::TRUNC` - новые данные сохраняются вместо существующих (разрешение на запись необходимо устанавливать отдельно); 178 | 179 | `File::NOCTTY` - терминал открывается, но управление программой не передается; 180 | 181 | `File::BINARY` - двоичный режим; 182 | 183 | `File::SYNC, File::DSYNC, File::RSYNC` - cинхронное открытие файла. При записи в поток, он будет блокировать процесс выполнения до тех пор, пока информация не будет реально записана на устройство; 184 | 185 | `File::NOFOLLOW` - открываются сами ярлыки, а не связанные с ними файлы; 186 | 187 | `File::NOATIME` - время последнего доступа не обновляется. 188 | 189 | ***** -------------------------------------------------------------------------------- /book/appformat.md: -------------------------------------------------------------------------------- 1 | # Форматные строки 2 | [](appformat) 3 | 4 | Форматная строка - это текст, в котором обычные символы перемешаны с специальными синтаксическими конструкциями. Обычные символы переносятся в результат без изменений, а специальные влияют на форматирование объектов. 5 | 6 | Спецсимволы классифицируются по их влиянию на форматирование. Из них только устанавливающие тип форматирования являются обязательными. 7 | 8 | Синтаксис спецсимволов (пробелы между ними не используются, а добавлены только для наглядности): 9 | `%[модификатор][размер][.точность]<тип форматирования>` 10 | 11 | Размер влияет на количество символов в результате. По умолчанию в начало текста добавляются дополнительные пробелы. 12 | `"%5d"%2 # -> " 2"` 13 | 14 | Точность влияет на количество цифр после десятичной точки (по умолчанию - 6). 15 | 16 | ##### Типы форматирования: 17 | 18 | ###### Для целых чисел: 19 | 20 | `b` - преобразует число в десятичную систему счисления. Для отрицательных чисел будет использоваться необходимое дополнение до 2 с символами .. в качестве приставки. 21 | 22 | ~~~~~ ruby 23 | "%b" % 2 # -> "10" 24 | "%b" % -2 # -> "..10" 25 | ~~~~~ 26 | 27 | `B` - аналогично предыдущему, но с приставкой 0B в альтернативной нотации. 28 | 29 | `d (или i или u)` - преобразует число из двоичной системы счисления в десятичную. 30 | `"%d" % 0x01 # -> "1"` 31 | 32 | `o` - преобразует число в восьмеричную систему счисления. Для отрицательных чисел будет использоваться необходимое дополнение до 2 с символами .. в качестве приставки. 33 | 34 | ~~~~~ ruby 35 | "%o" % 2 # -> "2" 36 | "%o" % -2 # -> "..76" 37 | ~~~~~ 38 | 39 | `x` - преобразует число в шестнадцатеричную систему счисления. Для отрицательных чисел будет использоваться необходимое дополнение до 2 с символами .. в качестве приставки. 40 | 41 | ~~~~~ ruby 42 | "%x" % 2 # -> "2" 43 | "%x" % -2 # -> "..fe" 44 | ~~~~~ 45 | 46 | `X` - аналогично предыдущему, но с приставкой 0X, в альтернативной нотации. 47 | 48 | ###### Для десятичных дробей: 49 | 50 | `e` - преобразует число в экспоненциальную нотацию. 51 | `"%e" % 1.2 # -> "1.200000e+00"` 52 | 53 | `E` - аналогично предыдущему, но с использованием символа экспоненты E. 54 | 55 | `f` - округление числа. 56 | `"%.3f" % 1.2 # -> "1.200"` 57 | 58 | `g` - преобразует число в экспоненциальную нотацию, если показатель степени будет меньше -4 или больше либо равен точности. В других случаях точность определяет количество значащих цифр. 59 | 60 | ~~~~~ ruby 61 | "%.1g" % 1.2 # -> "1" 62 | "%g" % 123.4 # -> "1e+02" 63 | ~~~~~ 64 | 65 | `G` - аналогично предыдущему, но с использованием символа экспоненты E. 66 | 67 | `a` - преобразование числа в формат: знак числа, число в шестнадцатеричной системе счисления с приставкой 0x, символ p, знак показателя степени и показатель степени в десятичной системе счисления. 68 | `"%.3a" % 1.2 # -> "0x1.333p+0"` 69 | 70 | `A` - аналогично предыдущему, но с использованием приставки 0X и символа P. 71 | 72 | ###### Для других объектов: 73 | 74 | `c` - результат будет содержать один символ. 75 | `"%с" % ?h # -> "h"` 76 | 77 | `p` - вызов метода `object.inspect` для объекта. 78 | `"%p" % ?h # -> "\"h\""` 79 | 80 | `s` - преобразование текста. Точность определяет количество символов. 81 | `"%.3s" % "Ruby" # -> "Rub"` 82 | 83 | ***** 84 | 85 | ##### Модификаторы: 86 | 87 | `-` - пробелы будут добавляться не в начало, а в конец. 88 | `4b" % 2 # -> "10 "` 89 | 90 | `0 (для чисел)` - вместо пробелов добавляются нули. 91 | `"%04b" % 2 # -> "0010"` 92 | 93 | `+ (для чисел)` - результат будет содержать знак плюса для положительных чисел. Для oxXbB используется обычная запись отрицательных чисел. 94 | `"%+b" % -2 # -> "-10"` 95 | 96 | `# (для эмблем bBoxXaAeEfgG)` - использование альтернативной нотации. 97 | 98 | + Для o повышается точность результата до тех пор пока первая цифра не будет нулем, если не используется дополнительное форматирование. 99 | `"%#o" % 2 # -> "02"` 100 | 101 | + Для xXbB используются соответствующие приставки. 102 | `"%#X" % 2 # -> "0X2"` 103 | 104 | + Для aAeEfgG используется десятичная точка даже если в этом нет необходимости. 105 | `"%#.0E" % 2 # -> "2.E+00"` 106 | 107 | + Для gG используются конечные нули. 108 | `"%#G" % 1.2 # -> "1.20000"` 109 | 110 | `*` - соответствующий спецсимволу объект используется для определения размера. Для отрицательных чисел пробелы добавляются в конце результата. 111 | `"%*d" % [ -2, 1 ] # -> "1 "` 112 | 113 | ***** 114 | 115 | Если форматная строка содержит несколько спецсимволов, то они будут последовательно использоваться для форматируемых объектов, которые должны храниться в индексном или ассоциативном массивах. 116 | 117 | Для индексных массивов модификатор `цифра$` изменяет форматирование элемента с соответствующей позицией (начиная с 1). При этом модификатор должен быть указан для каждого спецсимвола. 118 | `"%3$d, %1$d, %1$d" % [ 1, 2, 3 ] # -> "3, 1, 1"` 119 | 120 | Для ассоциативных массивов модификатор `<идентификатор>` после приставки применяет форматирование для элемента с соответствующим ключом. 121 | `"%d, %d" % { one: 1, two: 2, three: 3 } # -> "2, 1"` -------------------------------------------------------------------------------- /book/appio.md: -------------------------------------------------------------------------------- 1 | # Создание потоков 2 | [](appio) 3 | 4 | Вид потока (mode) устанавливается с помощью группы модификаторов. 5 | 6 | ##### Модификаторы: 7 | 8 | `r` - только для чтения; 9 | 10 | `r+` - как для чтения, так и для записи (новые данные вместо старых); 11 | 12 | `w` - только для записи (новые данные вместо старых). При необходимости создается новый файл; 13 | 14 | `w+` - как для чтения, так и для записи (новые данные вместо старых). При необходимости создается новый файл; 15 | 16 | `a` - только для записи (новые данные добавляются к старым). При необходимости создается новый файл; 17 | 18 | `a+` - как для чтения, так и для записи (новые данные добавляются к старым). При необходимости создается новый файл; 19 | 20 | `b` - двоичный режим (может использоваться с другими модификаторами). Чтение из файла выполняется в ASCII кодировке. Используется только для чтения двоичных файлов в Windows; 21 | 22 | `t` - текстовый режим (может использоваться с другими модификаторами). 23 | 24 | ***** 25 | 26 | При чтении или записи данных используются две кодировки: внутренняя и внешняя. 27 | 28 | + Внешняя кодировка - это кодировка текста внутри потока. По умолчанию она совпадает с кодировкой ОС. 29 | + Внутренняя кодировка - это кодировка для работы с полученными данными внутри программы. По умолчанию она совпадает с внешней кодировкой. 30 | 31 | Если внутренняя и внешняя кодировка отличаются, то при чтении данных выполняется автоматическое преобразование из внешней кодировки во внутреннюю, а при записи данных - из внутренней во внешнюю. 32 | 33 | После модификатора могут быть указаны внешняя и внутренняя кодировки, разделенные двоеточием: `"w+:ascii:utf-8"`. Если внутренняя кодировка не указана, то по умолчанию используется внешняя кодировка. 34 | 35 | Вид потока также может быть изменен с помощью дополнительного аргумента - массива опций или набора констант из модуля File::Constants. 36 | 37 | ##### Опции: 38 | 39 | `mode:` вид создаваемого потока; 40 | 41 | `textmode:` true, текстовый режим; 42 | 43 | `binmode:` true, двоичный режим; 44 | 45 | `autoclose:` true, закрытие файла, после закрытия потока; 46 | 47 | `external_encoding:` внешняя кодировка; 48 | 49 | `internal_encoding:` внутренняя кодировка. Если внутренняя кодировка не указана, то по умолчанию используется внешняя кодировка; 50 | 51 | `encoding:` внешняя и внутренняя кодировки в формате `external:internal`. 52 | 53 | ***** 54 | 55 | Также принимаются элементы, влияющие на [преобразование кодировок](appencode). -------------------------------------------------------------------------------- /book/apppack.md: -------------------------------------------------------------------------------- 1 | # Упаковка данных 2 | [](apppack) 3 | 4 | Произвольные данные могут быть представлены в виде двоичного текста. Для этого элементы массива (данные) описывают с помощью форматных строк (набора спецсимволов). 5 | 6 | ###### Синтаксис форматных строк: 7 | 8 | + Пробелы в теле форматной строки игнорируются; 9 | 10 | + Цифра после спецсимвола соответствует количеству элементов, на которые распространяется его действие; 11 | 12 | + Символ звездочки (*) после спецсимвола распространяет его на все оставшиеся элементы; 13 | 14 | + Спецсимволы sSiIlL могут начинаться с знака подчеркивания или восклицательного знака, означающих что размер типа данных зависит от операционной системы; 15 | 16 | + Добавление символов > или < позволяет использовать старший или младший порядки байтов соответственно (l_> или L!<). 17 | 18 | ##### Целые числа: 19 | 20 | `C` - 8-битное целое число без знака (unsigned integer или unsigned char); 21 | 22 | `c` - 8-битное целое число со знаком (signed integer или signed char); 23 | 24 | `S` - 16-битное целое число без знака (uint_16t); 25 | 26 | `s` - 16-битное целое число со знаком (int_16t); 27 | 28 | `L` - 32-битное целое число без знака (uint_32t); 29 | 30 | `l` - 32-битное целое число со знаком (int_32t); 31 | 32 | `Q` - 64-битное целое число без знака (uint_64t); 33 | 34 | `S_ (S!)` - целое число без знака минимально возможного размера (unsigned short); 35 | 36 | `s_ (s!)` - целое число со знаком минимально возможного размера (signed short); 37 | 38 | `I (I_ или I!)` - целое число без знака (unsigned integer); 39 | 40 | `i (i_ или i!)` - целое число со знаком (signed integer); 41 | 42 | `L_ (L!)` - целое число без знака максимально возможного размера (unsigned long); 43 | 44 | `l_ (l!)` - целое число со знаком максимально возможного размера (signed long); 45 | 46 | `N` - 32-битное целое число без знака со старшим порядком байтов (для сетей); 47 | 48 | `n` - 16-битное целое число без знака со старшим порядком байтов (для сетей); 49 | 50 | `V` - 32-битное целое число без знака с младшим порядком байтов (VAX); 51 | 52 | `v` - 16-битное целое число без знака с младшим порядком байтов (VAX); 53 | 54 | `U` - кодовая позиция UTF-8 символа; 55 | 56 | `w` - BER-кодированное целое число. 57 | 58 | ***** 59 | 60 | ##### Десятичные дроби: 61 | 62 | `D, d` - число с плавающей точкой двойной точности; 63 | 64 | `F, f` - число с плавающей точкой; 65 | 66 | `E` - число с плавающей точкой двойной точности, с младшим порядком байтов; 67 | 68 | `e` - число с плавающей точкой с младшим порядком байтов; 69 | 70 | `G` - число с плавающей точкой двойной точности, со старшим порядком байтов; 71 | 72 | `g` - число с плавающей точкой со старшим порядком байтов. 73 | 74 | ***** 75 | 76 | ##### Текст: 77 | 78 | `A` - произвольный двоичный текст с удаленными конечными нулями и ASCII пробелами; 79 | 80 | `a` - произвольный двоичный текст; 81 | 82 | `Z` - произвольный двоичный текст заканчивающийся нулем; 83 | 84 | `B` - произвольный двоичный текст (MSB первый); 85 | 86 | `b` - произвольный двоичный текст (LSB первый); 87 | 88 | `H` - шестнадцатеричный текст (hight nibble первый); 89 | 90 | `h` - шестнадцатеричный текст (low nibble первый); 91 | 92 | `u` - UU-кодированный тексту; 93 | 94 | `M` - MIME-кодированный тексту (RFC2045); 95 | 96 | `m` - base64-кодированный текст (RFC2045, если заканчивается 0, то RFC4648); 97 | 98 | `P` - указатель на контейнер (текст фиксированной длины); 99 | 100 | `p` - указатель на текст, заканчивающийся нулем. 101 | 102 | ***** 103 | 104 | ##### Остальное: 105 | 106 | `@` - интерпретатор пропускает указанное целым числом количество байтов; 107 | 108 | `X` - интерпретатор продвигается вперед на один байт; 109 | 110 | `x` - интерпретатор возвращается назад на один байт. 111 | 112 | ***** 113 | -------------------------------------------------------------------------------- /book/appregexp.md: -------------------------------------------------------------------------------- 1 | # Синтаксис регулярных выражений 2 | [](appregexp) 3 | 4 | **Во второй версии Ruby** для обработки регулярных выражений используется библиотека Onigmo: . 5 | 6 | Также более подробное описание синтаксиса существует по адресу 7 | . 8 | 9 | ##### Модификаторы: 10 | 11 | `i` – поиск будет выполняться без учета регистра символов; 12 | 13 | `m` – поиск будет выполняться в многострочном режиме. Точка в теле регулярного выражения будет соответствовать также и символу перевода строки; 14 | 15 | `x` – пробельные символы (пробел, отступ, перевод строки) в теле регулярного выражения будут игнорироваться интерпретатором; 16 | 17 | `o` – интерполяция в теле регулярного выражения будет выполняться только один раз, перед началом поиска; 18 | 19 | `u, e, s, n` – тело регулярного выражения будет обрабатываться в указанной кодировке. Соответственно: u - UTF-8, e - EUC-JP , s - Windows-31J , n - ASCII-8BIT. 20 | 21 | ***** 22 | 23 | ##### ASCII символы: 24 | 25 | `.` - соответствует любому символу в тексте (кроме символа перевода строки в однострочном режиме поиска); 26 | 27 | `\w` - соответствует любой букве, цифре или знаку подчеркивания; 28 | 29 | `\W` - соответствует любому символу, кроме букв, цифр или знаков подчеркивания; 30 | 31 | `\s` - соответствует любому пробельному символу (пробел, отступ, перевод строки); 32 | 33 | `\S` - соответствует любому символу, кроме пробельных; 34 | 35 | `\d` - соответствует любой десятичной цифре; 36 | 37 | `\D` - соответствует любому символу, кроме десятичных цифр; 38 | 39 | `\h` - соответствует любой шестнадцатеричной цифре; 40 | 41 | `\H` - соответствует любому символу, кроме шестнадцатеричных цифр. 42 | 43 | ***** 44 | 45 | ##### Unicode символы: 46 | 47 | `\R` - **во второй версии Ruby** соответствует любому переводу строки, включая вертикальный отступ. Спецсимвол является аббревиатурой к non really. 48 | 49 | Эквивалентно `(?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}])` в Unicode 50 | или `(?>\x0D\x0A|[\x0A-\x0D])` в другом случае. 51 | 52 | ~~~~~ ruby 53 | "\n" =~ /^\R$/ # -> 0 54 | "\r" =~ /^\R$/ # -> 0 55 | "\r\n" =~ /^\R$/ # -> 0 56 | ~~~~~ 57 | 58 | `\X` - **во второй версии Ruby** соответствует любому расширенному графическому символу в Unicode. Спецсимвол является аббревиатурой к eXtended Unicode character. 59 | `"P\u{307}" =~ /^\X$/ # -> 0` 60 | 61 | `[[:класс:]]` - соответствует любому символу, входящему в класс: 62 | 63 | + _alnum_ - буквы и цифры; 64 | _alpha_ - буквы; 65 | _ascii_ - ASCII символы; 66 | _blank_ - пробел и отступ; 67 | _cntrl_ - эмблемы составного текста; 68 | _digit_ - десятичные цифры; 69 | _graph_ - буквы, цифры и знаки препинания; 70 | _lower_ - строчные буквы; 71 | _print_ - буквы, цифры, знаки препинания и пробел; 72 | _punct_ - знаки препинания; 73 | _space_ - пробельные символы (пробел, отступ, перевод строки); 74 | _upper_ - прописные буквы; 75 | _word_ - буквы, цифры и специальные знаки препинания (знак подчеркивания); 76 | _xdigit_ -шестнадцатеричные цифры; 77 | 78 | `\p{класс}` - соответствует любому символу, входящему в класс. 79 | 80 | `\p{^класс}` - соответствует любому символу, кроме входящих в класс. 81 | 82 | + _Alnum_ - буквы и цифры; 83 | _Alpha_ - буквы; 84 | _Any_ - Unicode символы; 85 | _ASCII_ - ASCII символы; 86 | _Assigned_ - свободные цифровые коды; 87 | _Blank_ - пробел и отступ; 88 | _Cntrl_ - эмблемы составного текста; 89 | _Digit_ - десятичные цифры; 90 | _Graph_ - буквы, цифры и знаки препинания; 91 | _Lower_ - строчные буквы; 92 | _Print_ - буквы, цифры, знаки препинания и пробел; 93 | _Punct_ - знаки препинания; 94 | _Space_ - пробельные символы (пробел, отступ, перевод строки); 95 | _Upper_ - прописные буквы; 96 | _Word_ - буквы, цифры и специальные знаки препинания (знак подчеркивания); 97 | _Xdigit_ - шестнадцатеричные цифры. 98 | 99 | ***** 100 | 101 | Unicode-классы символов: 102 | 103 | + C - остальные символы; Cc - спецсимволы; Cf - спецсимволы, влияющие на форматирование; Сn - свободные цифровые коды; Co - логотипы; Cs - символы-заменители; 104 | 105 | + L - буквы; Ll - строчные буквы; Lm - особые символы; Lo - остальные символы; Lt - буквы в начале слова; Lu - прописные буквы; 106 | 107 | + M – символы, использующиеся в связке; Mn - символы, изменяющие другие символы; Mc - специальные модификаторы, занимающие отдельную позицию в тексте; Me - символы, внутри которых могут находиться другие символы; 108 | 109 | + N - цифры; Nd - десятичные цифры; Nl - римские цифры; No - остальные цифры; 110 | 111 | + P - знаки препинания; Pc - специальные знаки препинания; Pd - дефисы и тире; Ps - открывающие скобки; Pe - закрывающие скобки; Pi - открывающие кавычки; Pf - закрывающие кавычки; Po - остальные знаки препинания; 112 | 113 | + S - декоративные символы; Sm - математические символы; Sc - символы денежных единиц; Sk - составные декоративные символы; So - остальные декоративные символы; 114 | 115 | + Z - разделители, не имеющие графического представления; Zs - пробелы; Zl - перевод строки; Zp - перевод параграфа. 116 | 117 | Также можно указать класс, определяющий алфавит. Поддерживаемые алфавиты: Arabic, Armenian, Balinese, Bengali, Bopomofo, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Inherited, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lycian, Lydian, Malayalam, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Ol_Chiki, Old_Italic, Old_Persian, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Saurashtra, Shavian, Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, and Yi. 118 | 119 | ##### Группировка символов: 120 | 121 | `[...]` - соответствует любому символу из ограниченных квадратными скобками. Внутри квадратных скобок могут быть использованы диапазоны символов (a-z); 122 | 123 | `[^...]` - соответствует любому символу, кроме ограниченных квадратными скобками; 124 | 125 | `(?:...)` - символы объединяются в группу и используются как одна логическая единица; 126 | 127 | `(...)` - символы объединяются в группу и используются как одна логическая единица. Группе будет присвоен порядковый номер (от 1 до 9); 128 | 129 | `(?<идентификатор>...)` - символы объединяются в группу и используются как одна логическая единица. Группе будет присвоен указанный идентификатор. 130 | 131 | ***** 132 | 133 | Если лексема регулярного выражения использовалось в качестве левого операнда, тогда, после выполнения выражения, идентификаторы групп ссылаются на текст совпадения, или на nil, если совпадений не найдено. Идентификаторы групп объявляются как локальные переменные. 134 | 135 | Глобальные переменные от $1 до $9 также ссылаются на текст совпадения с группой, имеющей указанный номер. 136 | 137 | ##### Группы символов: 138 | 139 | `\целое_число` - соответствует тексту совпадения с группой, имеющей указанный номер; 140 | 141 | `\K <идентификатор>` - соответствует тексту совпадения с группой, имеющей указанный идентификатор; 142 | 143 | `\g <...>` - соответствует тексту совпадения с группой, имеющей указанный порядковый номер или идентификатор. **Во второй версии Ruby** добавлен расширенный синтаксис (см. документацию для Onigmo). 144 | 145 | ***** 146 | 147 | ##### Повторы: 148 | 149 | `...?` - соответствует от 0 до 1 повторам символа или группы; 150 | 151 | `...*` - соответствует 0 и более повторам символа или группы. Результат поиска содержит максимально возможное совпадение (жадный алгоритм); 152 | 153 | `...*?` - соответствует 0 и более повторам символа или группы. Результат поиска содержит минимально возможное совпадение (не жадный алгоритм); 154 | 155 | `...+` - соответствует 1 и более повторам символа или группы. Результат поиска содержит максимально возможное совпадение (жадный алгоритм); 156 | 157 | `...+?` - соответствует 1 и более повторам символа или группы. Результат поиска содержит минимально возможное совпадение (не жадный алгоритм); 158 | 159 | `...{a, b}` - соответствует от a до b повторам символа или группы. Результат поиска содержит максимально возможное совпадение (жадный алгоритм); 160 | 161 | `...{a, b}?` - соответствует от a до b повторам символа или группы. Результат поиска содержит минимально возможное совпадение (не жадный алгоритм). 162 | 163 | В обоих случаях допускается отсутствие a, b, или запятой. 164 | 165 | ***** 166 | 167 | ##### Положение в тексте: 168 | 169 | `^...` - соответствует символу или группе в начале строки; 170 | 171 | `...$` - соответствует символу или группе в конце строки; 172 | 173 | `\A...` - соответствует символу или группе в начале текста; 174 | 175 | `...\z` - соответствует символу или группе в конце текста; 176 | 177 | `...\Z` - соответствует символу или группе в конце текста или перед последним символом перевода строки, замыкающим текст; 178 | 179 | `...\b` - соответствует символу или группе в конце слова; 180 | 181 | `\b...` - соответствует символу или группе в начале слова; 182 | 183 | `...\B` - соответствует символу или группе в любом месте, кроме конца слова; 184 | 185 | `\B...` - соответствует символу или группе в любом месте, кроме начала слова. 186 | 187 | ***** 188 | 189 | + Использование идиомы `/^...$/` для проверки полного совпадения текста с образцом потенциально может привести к небезопасному коду. Чтобы избежать этого, в данном случае, лучше использовать `/\A...\z/`. 190 | 191 | + Идиома `\b...\b` часто используется для поиска отдельных слов в тексте. 192 | 193 | ##### Логические условия: 194 | 195 | `№1|№2` - объединение множеств; 196 | 197 | `№1&&№2` - пересечение множеств; 198 | 199 | `№1(?=№2)` - соответствует символам №1, если символы №2 встречаются далее по тексту (позитивное заглядывание вперед); 200 | 201 | `№1(?!№2)` - соответствует символам №1, если символы №2 не встречаются далее по тексту (негативное заглядывание вперед); 202 | 203 | `№1(?<=№2)` - соответствует символам №1, если символы №2 встречаются в предыдущей части текста (позитивное заглядывание назад); 204 | 205 | `\K` - **во второй версии Ruby** любой шаблон, находящийся слева от спецсимвола не будет добавлен к тексту совпадения (и соответственно не будет изменяться при замене совпадений). 206 | 207 | Эквивалентно позитивному заглядыванию назад (`/№1 \K №2/` и `/(?<=№1) №2/`). 208 | 209 | Спецсимвол является аббревиатурой к keep. 210 | 211 | `№1(? 0 219 | regexp =~ "foO" # -> nil 220 | regexp =~ "FoO" # -> 0 221 | ~~~~~ 222 | 223 | ***** 224 | 225 | ##### Остальное: 226 | 227 | `(?#...)` - игнорируемый комментарий; 228 | 229 | `(?>...)` - в любом случае соответствует указанным символам; 230 | 231 | `(?№1-№2)` - применяет модификаторы №1 и отменяет модификаторы №2 для дальнейшего поиска; 232 | 233 | `(?№1-№2:...)` - применяет модификаторы №1 и отменяет модификаторы №2 для символов или групп. 234 | 235 | ***** -------------------------------------------------------------------------------- /book/args.md: -------------------------------------------------------------------------------- 1 | # Обработка аргументов 2 | 3 | Аргументы, переданные при запуске программы, сохраняются в массиве ARGV. 4 | 5 | ## Файлы 6 | 7 | Программы, работающие с файлами, могут принимать как по одному файлу, так и несколько сразу. Для работы с одним файлом используется массив ARGV, а для работы с несколькими файлами - поток ARGF. 8 | 9 | ### ARGV 10 | 11 | Для чтения файла, переданного при запуске программы, используются частные методы экземпляров `kernel.gets` и `kernel.readline`. Они аналогичны соответствующим методам для чтения строк из потока. 12 | 13 | ### ARGF 14 | 15 | **Добавленные модули: Enumerable** 16 | 17 | ARGF ($<) - это поток, открываемый для всех файлов, содержащихся в ARGV. При этом подразумевается, что ARGV содержит только пути к файлам. 18 | 19 | Файлы обрабатываются в том порядке, в котором они содержатся в ARGV (порядок, в котором они были переданы при запуске). После обработки путь к файлу удаляется автоматически. 20 | 21 | Файлы обрабатываются последовательно в виде одного виртуального файла. Концом потока считается конец последнего файла, а не конец отдельных элементов. 22 | 23 | Если ARGV ссылается на пустой массив, то ARGF ссылается на стандартный поток для чтения. 24 | 25 | #### Управление потоком 26 | 27 | Для управления потоком используются методы класса. Они аналогичны соответствующим методам для управления потоком. 28 | 29 | + `ARGF::binmode` 30 | + `ARGF::close` (обработка всех файлов считается исключением `IOError`) 31 | + `ARGF::skip` (при отсутствии файлов ничего не выполняется) 32 | + `ARGF::binmode?` 33 | + `ARGF::closed?` 34 | + `ARGF::eof?` (Синонимы: `eof`) 35 | 36 | `::argv # -> ARGV` 37 | 38 | `::filename # -> path` 39 | Синонимы: `path` 40 | 41 | Относительный путь к обрабатываемому файлу. При взаимодействии с стандартным потоком для ввода возвращается `"-"`. Аналогично использованию $FILENAME. 42 | 43 | #### Кодировка 44 | 45 | Для изменения кодировки используются методы класса. Они аналогичны соответствующим методам для изменения кодировки потока. 46 | 47 | + `ARGF::external_encoding` 48 | + `ARGF::internal_encoding` 49 | + `ARGF::set_encoding` 50 | 51 | #### Приведение типов 52 | 53 | `::to_s # -> "ARGF"` 54 | 55 | `::to_io # -> io` 56 | Синонимы: `file` 57 | 58 | Используется для получения потока для обрабатываемого файла (или стандартного потока для ввода). 59 | 60 | `::to_i # -> integer` 61 | Синонимы: `fileno` 62 | 63 | Используется для получения дескриптора обрабатываемого файла. Отсутствие файлов считается исключением `ArgumentError`. 64 | 65 | `::to_a( sep = $/, size = nil ) # -> array` 66 | Синонимы: `readlines` 67 | 68 | Используется для извлечения всех строк и сохранения их в индексном массиве (размер массива может быть ограничен). Переданный разделитель обрабатывается в качестве символа перевода строки (если передается пустой текст, то обрабатывается "\n\n"). 69 | 70 | `::to_write_io # -> io` 71 | 72 | Используется для получения потока, доступного для записи (только если используется режим редактирования файлов - при запуске программы передан ключ `-i`). 73 | 74 | #### Чтение данных 75 | 76 | Для чтения содержимого используются методы класса. Они аналогичны соответствующим методам для чтения содержимого потока. 77 | 78 | Фрагменты: 79 | 80 | + `ARGF::read` 81 | + `ARGF::read_nonblock` 82 | + `ARGF::readpartial` 83 | 84 | Строки: 85 | 86 | + + `ARGF::gets` 87 | + + `ARGF::readline` 88 | + + `ARGF::lineno` 89 | + + `ARGF::lineno=(pos)` 90 | + + `ARGF::seek` 91 | + + `ARGF::rewind` 92 | 93 | Символы: 94 | 95 | + `ARGF::getc` 96 | + `ARGF::readchar` 97 | 98 | Байты: 99 | 100 | + `ARGF::getbyte` 101 | + `ARGF::readbyte` 102 | + `ARGF::pos` (Синонимы: `tell`) 103 | + `ARGF::pos=(pos)` 104 | 105 | Итераторы: 106 | 107 | + `ARGF::each` (Синонимы: `each_line, lines`) 108 | + `ARGF::bytes` (Синонимы: `each_byte`) 109 | + `ARGF::chars` (Синонимы: `each_char`) 110 | + `ARGF::codepoints` (Синонимы: `each_codepoint`, Ruby 2.0) 111 | 112 | #### Запись данных 113 | 114 | Запись данных с помощью ARGF возможна только при запуске программы с ключом `-i`. Запись данных выполняется относительно текущего обрабатываемого файла. Для записи используются методы класса. Они аналогичны соответствующим методам для записи данных в поток. 115 | 116 | `::inplace_mode # -> string` 117 | 118 | Расширение, применяемое при создании резервных копий изменяемых файлов. 119 | 120 | `::inplace_mode=(ext) # -> self` 121 | 122 | Используется для изменения расширения, применяемого при создании резервных копий изменяемых файлов. 123 | 124 | + `ARGF::write` 125 | + `ARGF::print` 126 | + `ARGF::printf` 127 | + `ARGF::putc` 128 | + `ARGF::puts` -------------------------------------------------------------------------------- /book/author.md: -------------------------------------------------------------------------------- 1 | # От автора 2 | 3 | Текст книги в формате PDF доступен по адресу: 4 | 5 | 6 | ###### Сборка: 7 | 8 | 1. Установить Ruby. 9 | 2. Установить необходимые пакеты - `gem install redcarpet`. 10 | 3. Скачать скрипт для преобразования Markdown в LaTeX 11 | . 12 | 4. Установить XeLaTeX. 13 | 5. Скачать стиль - . 14 | 6. Собрать pdf - `xelatex book.tex` (по умолчанию используются шрифты семейства Liberation). 15 | 16 | ###### Контакты: 17 | 18 | + Исходники: 19 | + Автор: 20 | + Благодарности: 21 | + Qiwi: 89212870782 22 | + WebMoney: R349517838989 -------------------------------------------------------------------------------- /book/book.tex: -------------------------------------------------------------------------------- 1 | % Преамбула. 2 | \documentclass[a4paper, 12pt, oneside, openany, book]{ncc} 3 | 4 | \ChapterPrefixStyle{header,toc} 5 | \PnumPrototype{999} 6 | \usepackage[headings]{ncchdr} % Линейка в колонтитуле для стиля headings 7 | 8 | \usepackage{rus_ruby_book} 9 | 10 | % Тело документа. 11 | \begin{document} 12 | 13 | \author{Алекcандр Круглов} 14 | \title{Ruby} 15 | \date{\today} 16 | \bookeditor{Ruby 2.0.0p247} 17 | \maketitle 18 | 19 | \frontmatter 20 | \include{author} 21 | \tableofcontents 22 | 23 | \mainmatter 24 | 25 | \part{Основы} 26 | \include{intro} 27 | \include{standart} 28 | \include{identificate} 29 | \include{expression} 30 | \include{oop} 31 | 32 | \part{Описание классов} 33 | \include{number} 34 | \include{text} 35 | \include{enumerate} 36 | \include{object} 37 | \include{subroutine} 38 | \include{random} 39 | \include{datetime} 40 | \include{datatype} 41 | 42 | \part{Работа программы} 43 | \include{execution} 44 | \include{io} 45 | \include{args} 46 | \include{library} 47 | \include{exception} 48 | \include{test} 49 | \include{thread} 50 | \include{security} 51 | 52 | \appendix 53 | 54 | \addcontentsline{toc}{part}{Приложения} 55 | \part*{Приложения} 56 | \include{appbin} 57 | \include{appregexp} 58 | \include{appformat} 59 | \include{appassign} 60 | \include{appencode} 61 | \include{apppack} 62 | \include{appdatetime} 63 | \include{appio} 64 | \include{appfile} 65 | 66 | \backmatter 67 | \addcontentsline{toc}{part}{Заключение} 68 | \chapter*{Заключение} 69 | \input{conclusion} 70 | 71 | \end{document} 72 | -------------------------------------------------------------------------------- /book/complex.md: -------------------------------------------------------------------------------- 1 | ## Комплексные числа (Complex) 2 | 3 | Комплексные числа - это подвид вещественных чисел в виде суммы `(a+b*i)`, где a и b - вещественные числа, а i - мнимая единица. 4 | 5 | В классе удалены некоторые базовые методы из Numeric (все методы, относящиеся к округлению чисел, оператор `%`, методы `number.div`, `number.divmod`, `number.remainder`, итератор `number.step`). 6 | 7 | ##### Константы: 8 | 9 | `Complex::I` - мнимая единица. 10 | 11 | ***** 12 | 13 | `.Complex( real, imag = 0 ) # -> complex [Kernel]` 14 | 15 | Используется для создания комплексных чисел. 16 | 17 | ~~~~~ ruby 18 | Complex 2, 3 # -> (2+3i) 19 | Complex "2/3" # -> ((2/3)+0i) 20 | Complex 8, 3 # -> (8+3i) 21 | Complex 2.1, 3 # -> (2.1+3i) 22 | Complex ?i # -> (0+1i) 23 | ~~~~~ 24 | 25 | `::polar( magnitude, angle = 0.0 ) # -> complex` 26 | 27 | Используется для создания комплексного числа в полярной системе координат. 28 | `Complex.polar 2, 3 # -> (-1.9799849932008908+0.2822400161197344i)` 29 | 30 | `::rect( real, imag = nil ) # -> complex` 31 | Синонимы: `rectangular` 32 | 33 | Используется для создания комплексного числа в прямоугольной системе координат. 34 | `Complex.rect 2, 3 # -> (2+3i)` 35 | 36 | ### Приведение типов 37 | 38 | `.inspect # -> string` 39 | 40 | Преобразование в текст. 41 | `Complex( 2, 3 ).inspect # -> "(2+3i)"` 42 | 43 | `.to_s # -> string` 44 | 45 | Преобразование тела комплексного числа в текст. 46 | `Complex( 2, 3 ).to_s # -> "2+3i"` 47 | 48 | `.to_f # -> float` 49 | 50 | Преобразование комплексного числа в десятичную дробь, если такое преобразование возможно. 51 | `Complex( 2, 3 ).to_f # -> error!` 52 | 53 | `.to_i # -> integer` 54 | 55 | Преобразование комплексного числа в целое, если такое преобразование возможно. 56 | `Complex( 2, 3 ).to_i # -> error!` 57 | 58 | `.to_r # -> rational` 59 | 60 | Преобразование комплексного числа в рациональную дробь, если такое преобразование возможно. 61 | `Complex( 2, 3 ).to_r # -> error!` 62 | 63 | `.rationalize( number = Flt::EPSILON ) # -> rational` 64 | 65 | Преобразование комплексного числа в рациональную дробь, если такое преобразование возможно. Переданный аргумент игнорируется. 66 | `Complex(3).rationalize true # -> (3/1)` 67 | 68 | ### Операторы 69 | 70 | `.*(number) # -> result` 71 | 72 | Произведение. 73 | `Complex( 2, 3 ) * 2 # -> (4+6i)` 74 | 75 | `./(number) # -> result` 76 | Синонимы: `quo` 77 | 78 | Деление. 79 | `Complex( 2, 3 ) / 2 # -> ((1/1)+(3/2)*i)` 80 | 81 | `.**(number) # -> result` 82 | 83 | Возведение в степень. 84 | `Complex(2, 3)**2 # -> (-5+12i)` 85 | 86 | `.+(number) # -> result` 87 | 88 | Сумма. 89 | `Complex( 2, 3 ) + 2 # -> (4+3i)` 90 | 91 | `.-(number) # -> result` 92 | 93 | Разность. 94 | `Complex( 2, 3 ) - 2 # -> (0+3i)` 95 | 96 | `.- # -> result` 97 | 98 | Унарный минус. 99 | `-Complex( 2, 3 ) # -> (-2-3i)` 100 | 101 | ### Математические функции 102 | 103 | `.abs2 # -> number` 104 | 105 | Квадрат абсолютного значения. 106 | `Complex( 2, 3 ).abs2 # # -> 13` 107 | 108 | `.numerator # -> complex` 109 | 110 | Числитель возможной рациональной дроби. 111 | `Complex( 2, 3 ).numerator # -> (2+3i)` 112 | 113 | `.denominator # -> complex` 114 | 115 | Знаменатель возможной рациональной дроби (наименьшее общее кратное рациональной и мнимой частей). 116 | `Complex( 2, 3 ).denominator # -> 1` 117 | 118 | `.fdiv(number) # -> complex` 119 | 120 | Используется для вычисления частного каждой части в виде десятичной дроби. 121 | `Complex( 2, 3 ).fdiv 2 # -> (1.0+1.5i)` 122 | 123 | `.abs # -> number` 124 | Синонимы: `magnitude` 125 | 126 | Абсолютная часть в полярной системе координат. 127 | `Complex( 2, 3 ).abs # -> 3.605551275463989` 128 | 129 | `.arg # -> float` 130 | Синонимы: `angle, phase` 131 | 132 | Угловое значение в полярной системе координат. 133 | `Complex( 2, 3 ).arg # -> 0.982793723247329` 134 | 135 | `.real # -> number` 136 | 137 | Вещественная часть числа. 138 | `Complex( 2, 3 ).real # -> 2` 139 | 140 | `.imag # -> number` 141 | Синонимы: `imaginary` 142 | 143 | Мнимая часть числа. 144 | `Complex( 2, 3 ).imag # -> 3` 145 | 146 | `.rect # -> float` 147 | Синонимы: `rectangular` 148 | 149 | Вещественная и мнимая части числа в прямоугольной системе координат. 150 | `Complex( 2, 3 ).rect # -> [2, 3]` 151 | 152 | 153 | `.conj # -> complex` 154 | Синонимы: `conjugate` 155 | 156 | Сопряженное комплексное число. 157 | `Complex( 2, 3 ).conj # -> (2-3i)` 158 | 159 | -------------------------------------------------------------------------------- /book/conclusion.md: -------------------------------------------------------------------------------- 1 | > Лучший способ разобраться в чем-то до конца - попробовать научить этому компьютер. 2 | >: Дональд Кнут 3 | 4 | Вот и всё, что я смог найти. Не думайте, что прочитав эту книгу вы сразу станете писать высоко-нагруженные приложения. Максимум чему вы научились - это программирование небольших скриптов, способных немного облегчить вашу повседневную работу. Еще множество необходимых знаний о стиле кода, тестировании и отладке, архитектуре и оптимизации (и т.д.) отделяет вас от гордого звания программиста. Могу лишь надеяться, что удовольствия от работы с Ruby поможет преодолеть все эти препятствия и сообщество получит еще одного единомышленника. 5 | 6 | Как вы могли заметить в этой книге приведено очень мало примеров. И это не случайно. Изучение исходного кода уже работающих и востребованных приложений поможет вам быстрее понять все особенности и возможности Ruby. Сделав свой вклад в развитие какой-либо существующей программы вы не только улучшите свои навыки по написанию кода, но также поможете развитию языка. Любые же примеры, которые могут быть приведены в книге изначально очень сильно ограничены. 7 | 8 | Дополнительную информацию о Ruby, можно найти: 9 | 10 | - здесь есть все что вам необходимо; 11 | 12 | - хранилище пакетов (использующих Ruby и менеджер пакетов RubyGems); 13 | 14 | - удобный каталог, классифицирующий существующие gem-ы (пакеты); 15 | 16 | - сайт для публикации исходного кода. В нем есть раздел и для Ruby-программистов. -------------------------------------------------------------------------------- /book/datatype.md: -------------------------------------------------------------------------------- 1 | # Типы данных 2 | 3 | ## Логические величины 4 | 5 | Классы TrueClass, FalseClass и NilClass - это собственные классы объектов true, false и nil соответственно. Также существуют константы TRUE, FALSE, NIL, которые могут быть переопределены (но зачем?). 6 | 7 | ~~~~~ longtable 8 | { | * {3} { l |}} 9 | NilClass & FalseClass & TrueClass 10 | nil \& obj -> false & false \& obj -> false & true \& bool -> bool 11 | nil ~ bool -> bool & false ~ bool -> bool & true ~ bool -> !bool 12 | nil | bool -> bool & false | bool -> bool & true | object -> true 13 | nil.to_s -> "" & false.to_s -> "false" & true.to_s -> "true" 14 | ~~~~~ 15 | 16 | ~~~~~ ruby 17 | nil.nil? # -> true 18 | nil.inspect # -> "nil" 19 | nil.rationalize # -> (0/1) 20 | nil.to_r # -> (0/1) 21 | nil.to_a # -> [] 22 | nil.to_c # -> (0+0i) 23 | nil.to_f # -> 0.0 24 | nil.to_i # -> 0 25 | nil.to_h # -> {} [Ruby 2.0] 26 | ~~~~~ 27 | 28 | ## Symbol 29 | 30 | **Добавленные модули: Comparable** 31 | 32 | Большинство методов сначала преобразует объект в текст. 33 | 34 | `::all_symbols # -> array` Массив всех существующих экземпляров класса. 35 | 36 | ### Приведение типов 37 | 38 | `.to_sym # -> symbol` Синонимы: `intern` 39 | 40 | `.to_s # -> string` 41 | Синонимы: `id2name` 42 | 43 | Используется для получения текстовое значения. 44 | `:Ruby.to_s # -> "Ruby"` 45 | 46 | `.inspect # -> string` 47 | 48 | Информация об объекте. 49 | `:Ruby.inspect # -> ":Ruby"` 50 | 51 | `.to_proc # -> proc` 52 | 53 | Используется для получения подпрограммы, выполняющей то же, что и метод с аналогичным идентификатором. 54 | 55 | ~~~~~ ruby 56 | 1.next # -> 2 57 | :next.to_proc.call(1) # -> 2 58 | ~~~~~ 59 | 60 | ### Операторы 61 | 62 | ~~~~~ ruby 63 | symbol <=> object # -> symbol.to_s <=> object 64 | symbol =~ object # -> symbol.to_s =~ object 65 | symbol[*object] # -> symbol.to_s[*object] 66 | symbol.slice(*object) # -> symbol.to_s.slice(*object) 67 | ~~~~~ 68 | 69 | ### Изменение регистра 70 | 71 | `.capitalize # -> symbol` Выполняемое выражение: `self.to_s.capitalize.to_sym`. 72 | 73 | `.swapcase # -> symbol` Выполняемое выражение: `self.to_s.swapcase.to_sym`. 74 | 75 | `.upcase # -> symbol` Выполняемое выражение: `self.to_s.upcase.to_sym`. 76 | 77 | `.downcase # -> symbol` Выполняемое выражение: `self.to_s.downcase.to_sym`. 78 | 79 | ### Остальное 80 | 81 | `.encoding # -> encoding` 82 | 83 | Кодировка. 84 | `:Ruby.encoding # -> #` 85 | 86 | `.empty? # -> bool` Выполняемое выражение: `self.to_s.empty?`. 87 | 88 | `.length # -> integer` 89 | Синонимы: `size` 90 | 91 | Выполняемое выражение: `self.to_s.length` или `self.to_s.size`. 92 | 93 | `.casecmp(object)` Выполняемое выражение: `self.to_s.casecmp(object)`. 94 | 95 | `.next # -> symbol` 96 | Синонимы: `succ` 97 | 98 | Выполняемое выражение: `self.to_s.next.to_sym` или `self.to_s.succ.to_sym` 99 | 100 | ## Структуры 101 | 102 | **Добавленные модули: Enumerable** 103 | 104 | Структура данных - это объект, имеющий только свойства. Иногда структуры также используют при необходимости передавать несколько аргументов. 105 | 106 | Для создания структур используется класс Struct. 107 | 108 | `::new( name = nil, *attribute ) # -> class` 109 | 110 | Используется для создания в теле Struct нового класса структур и объявления переданных свойств (ссылающихся на nil). Если название класса не передано, то создается анонимный класс. Анонимный класс получит идентификатор, только если будет присвоен константе. 111 | 112 | Для нового класса определяется конструктор, принимающий значения для объявленных свойств. 113 | 114 | ~~~~~ ruby 115 | Struct.new "Kлюч", :объект # -> Struct::Kлюч 116 | # только для примера. Никогда так больше не делайте :) 117 | Struct::Kлюч.new [1, 2, 3] 118 | # -> # 119 | ~~~~~ 120 | 121 | ### Приведение типов 122 | 123 | `.to_s # -> string` 124 | Синонимы: `inspect` 125 | 126 | Информация об объекте. 127 | 128 | ~~~~~ ruby 129 | Struct::Kлюч.new( [1, 2, 3] ).to_s 130 | # -> "#" 131 | ~~~~~ 132 | 133 | `.to_a # -> array` 134 | Синонимы: `values` 135 | 136 | Массив значений свойств. 137 | `Struct::Kлюч.new( [1, 2, 3] ).to_a # -> [ [1, 2, 3] ]` 138 | 139 | `.to_h # -> hash [Ruby 2.0]` 140 | 141 | Массив свойств и их значений. 142 | 143 | ~~~~~ ruby 144 | Customer = Struct.new :name, :address, :zip 145 | joe = Customer.new "Joe Smith", "123 Maple, Anytown NC", 12345 146 | joe.to_h[:address] # -> "123 Maple, Anytown NC" 147 | ~~~~~ 148 | 149 | ### Элементы 150 | 151 | Элементами структур считаются свойства. Для доступа к свойствам определены операторы `[]` и `[]=`. Они принимают идентификаторы или индексы свойств. Индексация свойств начинается с 0 и соответствует порядку, использовавшемуся при создании структуры. Индекс может быть отрицательным (индексация, начинается с -1). 152 | 153 | Использование несуществующего свойства считается исключением. 154 | 155 | `.[attr] # -> object` 156 | 157 | Используется для получения значения свойства. 158 | 159 | ~~~~~ ruby 160 | Struct::Kлюч.new( [1, 2, 3] )["объект"] # -> [1, 2, 3] 161 | Struct::Kлюч.new( [1, 2, 3] )[0] # -> [1, 2, 3] 162 | Struct::Kлюч.new( [1, 2, 3] )[-1] # -> [1, 2, 3] 163 | ~~~~~ 164 | 165 | `.[attr]=(object) # -> object` 166 | 167 | Используется для изменения свойства. 168 | 169 | ~~~~~ ruby 170 | Struct::Kлюч.new( [1, 2, 3] )["объект"] = :array # -> :array 171 | Struct::Kлюч.new( [1, 2, 3] )[0] = :array # -> :array 172 | Struct::Kлюч.new( [1, 2, 3] )[-1] = :array # -> :array 173 | ~~~~~ 174 | 175 | `.values_at(*integer) # -> array` 176 | 177 | Используется для получения массива значений свойств с переданными индексами. При вызове без аргументов возвращается пустой массив. 178 | 179 | ~~~~~ ruby 180 | Struct::Kлюч.new( [1, 2, 3] ).values_at 0, -1 181 | # -> [ [1, 2, 3], [1, 2, 3] ] 182 | ~~~~~ 183 | 184 | ### Итераторы 185 | 186 | `.each { |object| } # -> self` 187 | 188 | Перебор значений свойств. 189 | 190 | `.each_pair { | name, object | } # -> self` 191 | 192 | Перебор идентификаторов свойств вместе с значениями. 193 | 194 | ### Остальное 195 | 196 | `.hash # -> integer` 197 | 198 | Цифровой код объекта. 199 | `Struct::Kлюч.new( [1, 2, 3] ).hash # -> -764829164` 200 | 201 | `.size # -> integer` 202 | Синонимы: `length` 203 | 204 | Количество свойств. 205 | `Struct::Kлюч.new( [1, 2, 3] ).size # -> 1` 206 | 207 | `.members # -> array` 208 | 209 | Массив идентификаторов свойств. 210 | `Struct::Kлюч.new( [1, 2, 3] ).members # -> [:объект]` -------------------------------------------------------------------------------- /book/datetime.md: -------------------------------------------------------------------------------- 1 | # Дата и время 2 | 3 | ## Время (Time) 4 | 5 | **Добавленные модули: Comparable** 6 | 7 | Экземпляры класса Time - это абстрактные объекты, содержащие информацию о времени. Время хранится в секундах, начиная с 01.01.1970 00:00 UTC. Системы отсчета времени GMT (время по Гринвичу) и UTC (универсальное время) трактуются как эквивалентные. 8 | 9 | При сравнении разных объектов необходимо помнить, что различные пояса могут иметь смещения по времени от UTC. 10 | 11 | ##### Аргументы: 12 | 13 | `year` - год; 14 | 15 | `month` - месяц: либо целое число от 1 до 12, либо текст, содержащий первые три буквы английского названия месяца (аббревиатуру); 16 | 17 | `day` - номер дня в месяце: целое число от 1 до 31; 18 | 19 | `wday` - номер дня в неделе: целое число от 0 до 6, начиная с воскресенья; 20 | 21 | `yday` - номер дня в году: целое число от 1 до 366; 22 | 23 | `isdst` - летнее время: логическая величина; 24 | 25 | `zone` - временная зона: текст; 26 | 27 | `hour` - час: целое число от 0 до 23; 28 | 29 | `min` - минуты: целое число от 0 до 59; 30 | 31 | `sec` - секунды: целое число или десятичная дробь от 0 до 60; 32 | 33 | `usec` - микросекунды: целое число или десятичная дробь от 0 до 999. 34 | 35 | ***** 36 | 37 | ### Создание объекта 38 | 39 | `::new # -> time` 40 | 41 | `(year, month = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0, zone)` 42 | `# -> time` 43 | 44 | Используется для создания объекта. При вызове без аргументов возвращается текущее системное время. Последним аргументом передается смещение относительно UTC в виде текста "+00:00" или количества секунд. По умолчанию берется системное смещение часового пояса. 45 | 46 | ~~~~~ ruby 47 | Time.new 1990, 3, 31, nil, nil, nil, "+04:00" 48 | # -> 1990-03-31 00:00:00 +0400 49 | ~~~~~ 50 | 51 | `::now # -> time` 52 | 53 | Используется для получения текущего системного времени. 54 | `Time.now -> 2011-09-17 10:36:26 +0400` 55 | 56 | `::at(time) # -> time` 57 | 58 | `( sec, usec = nil ) # -> time` 59 | 60 | Используется для создания объекта. Принимаются секунды и микросекунды, прошедшие с начала точки отсчета UTC. Время вычисляется с учетом смещения часового пояса. 61 | `Time.at 1 -> 1970-01-01 03:00:01 +0300` 62 | 63 | `::utc( year, month = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0)` 64 | 65 | `( sec, min, hour, day, month, year, wday, yday, isdst ) # -> time` 66 | Синонимы: `gm` 67 | 68 | Используется для создания объекта. 69 | `Time.utc 1990, 3, 31 -> 1990-03-31 00:00:00 UTC` 70 | 71 | `::local( year, month = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0, zone )` 72 | 73 | `(sec, min, hour, day, month, year, wday, yday, isdst, zone) # -> time` 74 | Синонимы: `time` 75 | 76 | Используется для создания объекта, с учетом смещения часового пояса. 77 | `Time.local 1990, 3, 31 -> 1990-03-31 00:00:00 +0400` 78 | 79 | ### Приведение типов 80 | 81 | `.to_s # -> string` 82 | Синонимы: `inspect` 83 | 84 | Преобразование в текст. 85 | `Time.local( 1990, 3, 31 ).to_s -> "1990-03-31 00:00:00 +0400"` 86 | 87 | `.to_a # -> array` 88 | 89 | Индексный массив вида: 90 | 91 | ~~~~~ ruby 92 | [ self.sec, self.min, self.hour, 93 | self.day, self.month, self.year, 94 | self.wday, self.yday, 95 | self.isdst, self.zone ] 96 | ~~~~~ 97 | 98 | ~~~~~ ruby 99 | Time.local( 1990, 3, 31 ).to_a 100 | # -> [ 0, 0, 0, 31, 3, 1990, 6, 90, true, "MSD" ] 101 | ~~~~~ 102 | 103 | `.to_i # -> integer` 104 | Синонимы: `tv_sec` 105 | 106 | Количество секунд прошедших начиная с 1970-01-01 00:00:00 UTC. 107 | `Time.local( 1990, 3, 31 ).to_i # -> 638827200` 108 | 109 | `.to_r # -> rational` 110 | 111 | Количество секунд прошедших начиная с 1970-01-01 00:00:00 UTC в виде рациональной дроби. 112 | 113 | `Time.local( 1990, 3, 31 ).to_r # -> (638827200/1)` 114 | 115 | `.to_f # -> float` 116 | 117 | Количество секунд прошедших начиная с 1970-01-01 00:00:00 UTC в виде десятичной дроби. 118 | `Time.local( 1990, 3, 31 ).to_f # -> 638827200.0` 119 | 120 | ### Операторы 121 | 122 | `.+(number) # -> time` 123 | 124 | Используется для прибавления секунд. 125 | `Time.local( 1990, 3, 31 ) + 3600 # -> 1990-03-31 01:00:00 +0400` 126 | 127 | `.-(time) # -> float` 128 | 129 | Разница в секундах. 130 | `Time.local( 1990, 3, 31 ) - Time.new( 1990, 3, 31 ) -> 0.0` 131 | 132 | `.-(number) # -> time` 133 | 134 | Используется для уменьшения секунд. 135 | `Time.local( 1990, 3, 31 ) - 3600 -> 1990-03-30 23:00:00 +0400` 136 | 137 | `.<=>(time)` 138 | 139 | Сравнение. 140 | `Time.local( 1990, 3, 31 ) <=> Time.new( 1990, 3, 31 ) -> 0` 141 | 142 | ### Форматирование 143 | 144 | `.strftime(format) # -> string` 145 | 146 | Используется для форматирования времени на основе переданной [форматной строки](appdatetime). 147 | 148 | ### Системы остчета 149 | 150 | `.getutc # -> time` 151 | Синонимы: `getgm` 152 | 153 | Время относительно UTC (без смещения часовых поясов). 154 | `Time.local( 1990, 3, 31 ).getutc # -> 1990-03-30 20:00:00 UTC` 155 | 156 | `.utc # -> self` 157 | Синонимы: `gmtime` 158 | 159 | Версия предыдущего метода, изменяющая значение объекта. 160 | 161 | `.getlocal( zone = nil ) # -> time` 162 | 163 | Время с смещением часового пояса. Смещение может быть явно передано методу (по умолчанию используется системное смещение). 164 | `Time.local(1990, 3, 31).getutc.getlocal # -> 1990-03-31 00:00:00 +0400` 165 | 166 | `.localtime( zone = nil ) # -> self` 167 | 168 | Версия предыдущего метода, изменяющая значение объекта. 169 | 170 | ### Статистика 171 | 172 | `.asctime # -> string` 173 | Синонимы: `ctime` 174 | 175 | Время в виде текста. 176 | `Time.local( 1990, 3, 31 ).asctime # -> "Sat Mar 31 00:00:00 1990"` 177 | 178 | `.utc_offset # -> integer` 179 | Синонимы: `gmt_offset, gmtoff` 180 | 181 | Смещение часового пояса относительно UTC в секундах. 182 | `Time.local( 1990, 3, 31 ).utc_offset # -> 14400` 183 | 184 | `.zone # -> string` 185 | 186 | Название временной зоны. 187 | `verb!Time.local( 1990, 3, 31 ).zone # -> "MSD"` 188 | 189 | `.year # -> integer` 190 | 191 | Номер года. 192 | `Time.local( 1990, 3, 31 ).year # -> 1990` 193 | 194 | `.month # -> integer` 195 | Синонимы: `mon` 196 | 197 | Номер месяца. 198 | `verb!Time.local( 1990, 3, 31 ).month # -> 3` 199 | 200 | `.yday # -> integer` 201 | 202 | Номер дня в году от 1 до 366. 203 | `Time.local( 1990, 3, 31 ).yday # -> 90` 204 | 205 | `.day # -> integer` 206 | Синонимы: `mday` 207 | 208 | Номер дня в месяце. 209 | `Time.local( 1990, 3, 31 ).day # -> 31` 210 | 211 | `.wday # -> integer` 212 | 213 | Номер дня недели (от 0 до 6, начиная с воскресенья). 214 | `Time.local( 1990, 3, 31 ).wday # -> 6` 215 | 216 | `.hour # -> integer` 217 | 218 | Час дня (число от 0 до 23). 219 | `Time.local( 1990, 3, 31 ).hour # -> 0` 220 | 221 | `.min # -> integer` 222 | 223 | Количество минут (число от 0 до 59). 224 | `Time.local( 1990, 3, 31 ).min # -> 0` 225 | 226 | `.sec # -> integer` 227 | 228 | Количество секунд (число от 0 до 60). 229 | `Time.local( 1990, 3, 31 ).sec # -> 0` 230 | 231 | `.subsec # -> integer` 232 | 233 | Дробная часть секунд. 234 | `Time.local( 1990, 3, 31 ).subsec # -> 0` 235 | 236 | `.usec # -> integer` 237 | Синонимы: `tv_usec` 238 | 239 | Количество микросекунд. 240 | `Time.local( 1990, 3, 31 ).usec # -> 0` 241 | 242 | `.nsec # -> integer` 243 | Синонимы: `tv_nsec` 244 | 245 | Количество наносекунд. 246 | `Time.local( 1990, 3, 31 ).nsec # -> 0` 247 | 248 | ### Предикаты 249 | 250 | `.monday? # -> bool` 251 | 252 | Проверка является ли понедельник днем недели. 253 | `Time.local( 1990, 3, 31 ).monday? # -> false` 254 | 255 | `.tuesday? # -> bool` 256 | 257 | Проверка является ли вторник днем недели. 258 | `Time.local( 1990, 3, 31 ).tuesday? # -> false` 259 | 260 | `.wednesday? # -> bool` 261 | 262 | Проверка является ли среда днем недели. 263 | `Time.local( 1990, 3, 31 ).wednesday? # -> false` 264 | 265 | `.thursday? # -> bool` 266 | 267 | Проверка является ли четверг днем недели. 268 | `Time.local( 1990, 3, 31 ).saturday? # -> false` 269 | 270 | `.friday? # -> bool` 271 | 272 | Проверка является ли пятница днем недели. 273 | `Time.local( 1990, 3, 31 ).friday? # -> false` 274 | 275 | `.saturday? # -> bool` 276 | 277 | Проверка является ли суббота днем недели. 278 | `Time.local( 1990, 3, 31 ).saturday? # -> true` 279 | 280 | `.sunday? # -> bool` 281 | 282 | Проверка является ли воскресенье днем недели. 283 | `Time.local( 1990, 3, 31 ).saturday? # -> false` 284 | 285 | `.utc? # -> bool` 286 | Синонимы: `gmt?` 287 | 288 | Проверка используется ли время относительно UTC. 289 | `Time.local( 1990, 3, 31 ).utc? # -> false` 290 | 291 | `.dst? # -> bool` 292 | Синонимы: `isdst` 293 | 294 | Проверка используется ли переход на летнее время. 295 | `Time.local( 1990, 3, 31 ).dst? # -> true` 296 | 297 | ### Остальное 298 | 299 | `.hash # -> integer` 300 | 301 | Цифровой код объекта. 302 | `Time.local( 1990, 3, 31 ).hash # -> -494674000` 303 | 304 | `.round( precise = 0 ) # -> time` 305 | 306 | Используется для округления секунд с заданной точностью. Точность определяет размер дробной части. 307 | `Time.local( 1990, 3, 31 ).round 2 # -> 1990-03-31 00:00:00 +0400` -------------------------------------------------------------------------------- /book/dir.md: -------------------------------------------------------------------------------- 1 | ## Dir (каталоги) 2 | 3 | **Добавленные модули: Enumerable** 4 | 5 | Каталог - это файл, содержащий информацию о расположении какой-либо группы файлов. 6 | 7 | + _Базовый каталог_ - каталог, в котором находится файл; 8 | _Рабочий каталог_ - каталог, относительно которого выполняется программа. Поиск файлов выполняется относительно рабочего каталога; 9 | _Домашний каталог_ - персональный каталог пользователя, зарегистрированного в системе. 10 | 11 | `::new(path) # -> dir` 12 | 13 | Используется для создания нового объекта. 14 | 15 | `::open(path) # -> dir` 16 | 17 | `(path) { |dir| } # -> dir` 18 | 19 | Версия предыдущего метода, позволяющая передавать объект в блок. После выполнения блока каталог закрывается. 20 | 21 | `.close # -> nil` 22 | 23 | Используется для закрытия каталога. Любая попытка использования объекта считается исключением. 24 | 25 | ### Работа с файловой системой 26 | 27 | `::mkdir( name, *perm ) # -> 0` 28 | 29 | Используется для создания каталога. Невозможность выполнения операции считается исключением. 30 | 31 | `::delete(path) # -> 0` 32 | Синонимы: `rmdir, unlink` 33 | 34 | Ипсользуется для удаления каталога. Удаление каталога, содержащего файлы, считается исключением. 35 | 36 | `::chdir( path = Dir.home ) # -> 0` 37 | 38 | `( path = Dir.home ) { |path| } # -> object` 39 | 40 | Используется для изменения рабочего каталога либо для всей программы, либо только во время выполнения блока. 41 | 42 | `::chroot(path) # -> 0` 43 | 44 | Используется для изменения корневого каталога в Unix-подобных системах. Программа, запущенная с изменённым корневым каталогом, будет иметь доступ только к файлам, содержащимся в данном каталоге. Только пользователь с правами администратора может изменить корневой каталог программы. 45 | 46 | ### Содержимое каталога 47 | 48 | `::entries(path) # -> array` 49 | 50 | Имена всех файлов, содержащихся в каталоге. 51 | 52 | `::glob( pattern, constants = nil ) # -> array` 53 | 54 | `( pattern, constants = nil ) { |name| } # -> nil` 55 | 56 | Используется для поиска файлов (синтаксис шаблонов описан в приложении). Чувствительность к регистру зависит от ОС. Найденные совпадения могут передаваться в блок. Дополнительно могут быть переданы константы, влияющие на поиск. 57 | 58 | `::[pattern] # -> array` 59 | 60 | Аналогично выполнению `Dir.glob pattern, 0`. 61 | 62 | `.read # -> name` 63 | 64 | Имя следующего файла. При достижении конца каталога возвращается nil. 65 | 66 | `.pos # -> integer` 67 | Синонимы: `tell` 68 | 69 | Текущая позиция в каталоге. 70 | 71 | `.seek(pos) # -> self` 72 | 73 | Используется для изменения позиции поиска. 74 | 75 | `.pos=(pos) # -> integer` 76 | 77 | Используется для изменения позиции поиска. 78 | 79 | `.rewind # -> self` 80 | 81 | Используется для сброса текущей позиции поиска. 82 | 83 | ### Итераторы 84 | 85 | `.each { |name| } # -> self` 86 | 87 | Перебор имен файлов. 88 | 89 | `::foreach(path) { |name| } # -> nil` 90 | 91 | Перебор имен файлов. 92 | 93 | ### Остальное 94 | 95 | `::directory?(path)` 96 | Синонимы: `exist?, exists?` 97 | 98 | Проверка относится ли файл к каталогам или к ярлыкам, ссылающимся на каталог. 99 | 100 | `::getwd # -> path` 101 | Синонимы: `pwd` 102 | 103 | Путь к рабочему каталогу программы. 104 | 105 | `::home( user = nil ) # -> path` 106 | 107 | Путь к домашнему каталогу текущего пользователя или пользователя с переданным идентификатором. 108 | 109 | `.inspect # -> string` 110 | 111 | Информация об объекте. 112 | 113 | `.path # -> path` 114 | 115 | Путь к каталогу (переданный при создании объекта). -------------------------------------------------------------------------------- /book/encode.md: -------------------------------------------------------------------------------- 1 | ## Кодировка 2 | 3 | ### Кодировка текста (Encoding) 4 | 5 | В классе определены константы для каждой поддерживаемой кодировки. Вместо них также могут использоваться заранее определенные синонимы. 6 | `Encoding::UTF_8 # -> #` 7 | 8 | #### Поддерживаемые кодировки 9 | 10 | `::default_external # -> encoding` 11 | 12 | Внешняя кодировку, используемая по умолчанию. 13 | 14 | 15 | `::default_external=(encoding) # -> encoding` 16 | 17 | Используется для изменения внешней кодировки, используемой по умолчанию. 18 | 19 | `::default_internal # -> encoding` 20 | 21 | Внутренняя кодировкf, используемая по умолчанию. 22 | 23 | 24 | `::default_internal=(encoding) # -> encoding` 25 | 26 | Используется для изменения внутренней кодировки, используемой по умолчанию. Для удаления кодировки передается nil. 27 | 28 | `::locale_charmap # -> string` 29 | 30 | Системная кодировка. 31 | 32 | `::list # -> array` 33 | 34 | Массив всех поддерживаемых кодировок. 35 | 36 | `::name_list # -> array` 37 | 38 | Массив всех синонимов. 39 | 40 | `::aliases # -> hash` 41 | 42 | Массив синонимов, ассоциируемых с экземплярами класса. 43 | 44 | `::find(aliases) # -> encoding` 45 | 46 | Используется для поиска кодировки, взаимосвязанной с переданным синонимом. Отсутствие синонима считается исключением (для внутренней кодировки может возвращаться nil). 47 | 48 | ###### Синонимы: 49 | 50 | + _"external"_ - внешняя кодировка; 51 | _"internal"_ - внутренняя кодировка; 52 | _"locale"_ - локальная кодировка пользователя; 53 | _"filesystem"_ - кодировка файловой системы. 54 | 55 | `::compatible?( first_string, second_string ) # -> encoding` 56 | 57 | Используется для проверки совместимости кодировок в текстах. Когда они совместимы, возвращается кодировка, поддерживаемая обоими. В другом случае возвращается nil. 58 | `Encoding.compatible? "асции", "utf-8" # -> #` 59 | 60 | #### Экземпляры 61 | 62 | `.inspect # -> string` 63 | 64 | Информация об объекте. 65 | `Encoding::UTF_8.inspect # -> "#"` 66 | 67 | `.name # -> string` 68 | Синонимы: `to_s` 69 | 70 | Информация о кодировке. 71 | `Encoding::UTF_8.name # -> "UTF-8"` 72 | 73 | `.names # -> array` 74 | 75 | Массив всех доступных синонимов. 76 | 77 | ~~~~~ ruby 78 | Encoding::UTF_8.names 79 | # -> ["UTF-8", "CP65001", "locale", "external", "filesystem"] 80 | ~~~~~ 81 | 82 | `.ascii_compatible? # -> bool` 83 | 84 | Проверка совместимости с ASCII. 85 | `Encoding::UTF_8.ascii_compatible? # -> true` 86 | 87 | `.dummy? # -> ruby` 88 | 89 | Проверка относится ли кодировка к фиктивным. Для фиктивных кодировок обработка символов не реализована должным образом. Метод используется для динамичных кодировок. 90 | `Encoding::UTF_8.dummy? # -> false` 91 | 92 | `.replicate(name) # -> encoding` 93 | 94 | Используется для копирования кодировки. Использование уже существующего имени считается исключением. 95 | `Encoding::UTF_8.replicate "утф8" # -> #` 96 | 97 | ### Преобразование кодировок (Encoding::Converter) 98 | 99 | ##### Константы: 100 | 101 | `::INVALID_MASK` - некоректные байты считаются исключением; 102 | 103 | `::INVALID_REPLACE` - некорректные байты заменяются; 104 | 105 | `::UNDEF_MASK` - неопределенные символы считаются исключением; 106 | 107 | `::UNDEF_REPLACE` - неопределенные символы заменяются; 108 | 109 | `::UNDEF_HEX_CHARREF` - неопределенные символы заменяются на байты `&xHH`; 110 | 111 | `::UNIVERSAL_NEWLINE_DECORATOR` - замена CR (`\r`) и CRLF (`\r\n`) на LF (`\n`); 112 | 113 | `::CRLF_NEWLINE_DECORATOR` - замена LF (`\n`) на CRLF (`\r\n`); 114 | 115 | `::CR_NEWLINE_DECORATOR` - замена LF (`\n`) на CR (`\r`); 116 | 117 | `::XML_TEXT_DECORATOR` 118 | 119 | `::XML_ATTR_CONTENT_DECORATOR` 120 | 121 | `::XML_ATTR_QUOTE_DECORATOR` 122 | 123 | `::PARTIAL_INPUT` - обработка исходного текста как части другого объекта; 124 | 125 | `::AFTER_OUTPUT` - цикличное преобразование исходного текста. 126 | 127 | ***** 128 | 129 | `::new( source_enc, dest_enc, options = nil ) # -> converter` 130 | 131 | `(conv_path) # -> converter` 132 | 133 | Используется для создания преобразователя. Принимаются исходная кодировка и требуемая. Дополнительные опции описаны в [приложении](appencode). 134 | 135 | Массив считается путем преобразования и должен содержать двухэлементные подмассивы для каждого отдельного преобразования. Дополнительными элементами могут влиять на преобразование. 136 | 137 | #### Поиск необходимых кодировок 138 | 139 | `::asciicompat_encoding(encoding) # -> encoding` 140 | 141 | Используется для получения кодировки, совместимой с переданной и с ASCII. Если это переданная кодировка, то возвращается nil. 142 | 143 | ~~~~~ ruby 144 | Encoding::Converter.asciicompat_encoding "utf-8" # -> nil 145 | Encoding::Converter.asciicompat_encoding "utf-16le" 146 | # -> # 147 | ~~~~~ 148 | 149 | `::search_convpath( source_enc, dest_enc, options = nil ) # -> array` 150 | 151 | Путь преобразования. 152 | 153 | ~~~~~ ruby 154 | Encoding::Converter.search_convpath "ISO-8859-1", "EUC-JP", 155 | universal_newline: true 156 | # -> [ [ #, # ], 157 | # [ #, # ], 158 | # "universal_newline" ] 159 | ~~~~~ 160 | 161 | #### Статистика 162 | 163 | `.inspect # -> string` 164 | 165 | Информация об объекте. 166 | 167 | ~~~~~ ruby 168 | Encoding::Converter.new( "ISO-8859-1", "EUC-JP" ).inspect 169 | # -> "#" 170 | ~~~~~ 171 | 172 | `.convpath # -> array` 173 | 174 | Путь преобразования. 175 | 176 | ~~~~~ ruby 177 | Encoding::Converter.new( "ISO-8859-1", "EUC-JP" ).convpath 178 | # -> [ [ #, # ], 179 | # [ #, # ] ] 180 | ~~~~~ 181 | 182 | `.source_encoding # -> encoding` 183 | 184 | Исходная кодировка. 185 | 186 | ~~~~~ ruby 187 | Encoding::Converter.new("ISO-8859-1", 188 | "EUC-JP").source_encoding 189 | # -> # 190 | ~~~~~ 191 | 192 | `.destination_encoding # -> encoding` 193 | 194 | Требуемая кодировка. 195 | 196 | ~~~~~ ruby 197 | Encoding::Converter.new("ISO-8859-1", 198 | "EUC-JP").destination_encoding 199 | # -> # 200 | ~~~~~ 201 | 202 | `.replacement # -> string` 203 | 204 | Текст для замены некорректных байтов или неопределенных символов. 205 | 206 | ~~~~~ ruby 207 | Encoding::Converter.new( "ISO-8859-1", "EUC-JP" ).replacement 208 | # -> "?" 209 | ~~~~~ 210 | 211 | `.replacement=(string) # -> string` 212 | 213 | Используется для изменения текста, заменяющего некорректные байты или неопределенные символы. 214 | 215 | `.last_error # -> error` 216 | 217 | Последнее полученное исключение. 218 | 219 | #### Преобразование 220 | 221 | `.convert(text) # -> string` 222 | 223 | Используется для преобразования кодировки. Некорректные байты или неопределенные символы считаются исключением в любом случае. 224 | 225 | `.primitive_convert( text, result, start = nil, bytesize = nil, options = nil )# -> symbol` 226 | 227 | Используется для преобразования кодировок без изменения значения объекта. Позволяется ограничивать фрагмент, в который сохраняется результат (по умолчанию в конец текста). 228 | 229 | ##### Опции: 230 | 231 | `partial_input: true`, исходный текст может быть частью другого объекта; 232 | 233 | `after_output: true`, после получения результата, ожидается новый исходный текст. 234 | 235 | ***** 236 | 237 | Преобразование завершается при выполнении одного из следующих условий (в скобках указан возвращаемый результат): 238 | 239 | + Исходный текст содержит некорректные байты (`:invalid_byte_sequence`); 240 | 241 | + Неожиданный конец исходного текста. 242 | 243 | Это возможно, если `:partial_input` не задан (`:incomplete_input`); 244 | 245 | + Исходный текст содержит неопределенные символы (`:undefined_conversion`); 246 | 247 | + Данные выводятся до их записи. 248 | 249 | Это возможно, если ключ `:after_output` не задан (`:after_output`); 250 | 251 | + Буфер назначенного объекта полон. 252 | 253 | Это возможно, если bytesize не ссылается nil (`:destination_buffer_full`); 254 | 255 | + Исходный текст пуст. 256 | 257 | Это возможно, если `:partial_input` не задан (`:source_buffer_empty`); 258 | 259 | + Преобразование завершено (`:finished`). 260 | 261 | `.primitive_errinfo # -> array` 262 | 263 | Информация о последней ошибке преобразования в виде: 264 | 265 | `[ symbol, source_enc, dest_enc, ivalid_byte, undef_char ]`, 266 | 267 | где symbol - результат последнего вызова метода `.primitive_convert`. 268 | 269 | Другие элементы имеют смысл только для `:invalid_byte_sequence`, 270 | `:incomplete_input` или `:undefined_conversion`. 271 | 272 | `.putback # -> string` 273 | 274 | Фрагмент текста, который будет преобразован при следующем вызове `.primitive_convert`. 275 | 276 | `.insert_output(string) # -> nil` 277 | 278 | Используется для добавления текста, необходимого к преобразованию. Когда требуемая кодировка сохраняет свое состояние, текст будет преобразован в соответствии с состоянием, которое будет обновлено после преобразования. Этот метод необходимо использовать только если при преобразовании получено исключение. 279 | 280 | `.finish # -> string` 281 | 282 | Используется для завершения преобразования. -------------------------------------------------------------------------------- /book/enumerable.md: -------------------------------------------------------------------------------- 1 | ## Enumerable 2 | 3 | Модуль содержит методы для работы с составными объектами, реализующими перебор своих элементов с помощью метода `.each`. 4 | 5 | Также для некоторых методов может понадобиться определение оператора `<=>`. 6 | 7 | Ассоциативные массивы преобразуются в индексные с помощью метода `.to_a`. 8 | 9 | ### Приведение типов 10 | 11 | `.to_a # -> array` 12 | Синонимы: `entry` 13 | 14 | Преобразование в индексный массив. 15 | 16 | ### Элементы 17 | 18 | `.first( size = nil ) # -> object` 19 | 20 | Используется для получения первого элемента или начального фрагмента. Если методу передается ноль, то возвращается пустой массив. 21 | `[1, 2, 3].first 2 # -> [1, 2]` 22 | 23 | `.take(size) # -> array` 24 | 25 | Используется для получения фрагмента заданного размера. Если методу передается ноль, то возвращается пустой массив. 26 | `[1, 2, 3].take 2 # -> [1, 2]` 27 | 28 | `.drop(size) # -> array` 29 | 30 | Используется для удаления фрагмента заданного размера. 31 | `[1, 2, 3].drop 2 # -> [3]` 32 | 33 | ### Сортировка и группировка 34 | 35 | `.sort # -> array` 36 | 37 | `{ |first, second| } # -> array` 38 | 39 | Используется для сортировки элементов либо с помощью оператора `<=>`, либо на основе результатов итерации. 40 | `{ a: 1, b: 2, c: 3 }.sort # -> [ [:a, 1], [:b, 2], [:c, 3] ]` 41 | 42 | `.sort_by { |first, second| } # -> array` 43 | 44 | Используется для сортировки в восходящем порядке на основе результатов итерации. 45 | 46 | ~~~~~ ruby 47 | { a: 1, b: 2, c: 3 }.sort_by { |array| -array[1] } 48 | # -> [ [:c, 3], [:b, 2], [:a, 1] ] 49 | ~~~~~ 50 | 51 | `.group_by { |object| } # -> hash` 52 | 53 | Используется для группировки элементов на основе результата итерации. 54 | `[1, 2].group_by { |elem| elem > 4 } # -> { false => [1, 2] }` 55 | 56 | `.zip(*object) # -> array` 57 | 58 | `(*object) { |array| } # -> nil` 59 | 60 | Используется для группировки элементов с одинаковыми индексами. Группы могут передаваться в необязательный блок. 61 | 62 | Количество групп равно размеру объекта, для которого метод был вызван. Остальные объекты при необходимости дополняются элементами, ссылающимися на nil. 63 | 64 | ~~~~~ ruby 65 | { a: 1, b: 2 }.zip [1, 2], [1] 66 | # -> [ [ [:a, 1], 1, 1 ], [ [:b, 2], 2, nil ] ] 67 | ~~~~~ 68 | 69 | `.chunk { |object| } # -> enum` 70 | 71 | `(buffer) { |object, buffer| } # -> enum` 72 | 73 | Используется для группировки элементов на основе результатов итерации. 74 | 75 | Результат выполнения блока для дальнейшего использования может быть сохранен с помощью дополнительного аргумента. 76 | 77 | Блок может возвращать специальные объекты: 78 | 79 | + *nil* или *:_* - игнорировать элемент; 80 | *:_alone* - элемент будет единственным в группе. 81 | 82 | `.slice_before(object) # -> enum` 83 | 84 | `{ |object| } # -> enum` 85 | 86 | `(buffer { |object, buffer| } # -> enum` 87 | 88 | Используется для группировки элементов. Новая группа начинается с элемента равного переданному аргументу (сравнение выполняется с помощью оператора `===`), или с положительным результатом итерации. 89 | 90 | Первый элемент игнорируется. 91 | 92 | В перечне каждая группа объектов сохраняется в виде индексного массива. 93 | 94 | ### Поиск элементов 95 | 96 | `.count( object = nil ) # -> integer` 97 | 98 | `{ |object| } # -> integer` 99 | 100 | Используется для получения количества элементов, либо равных переданному аргументу, либо с положительным результатом итерации. При вызове без аргументов возвращает количество элементов. 101 | `[ 1, 2, 3 ].count { |elem| elem < 4 } # -> 3` 102 | 103 | `.grep(object) # -> array` 104 | 105 | `(object) { |object| } # -> array` 106 | 107 | Используется для получения всех элементов, равных переданному аргументу (сравнение выполняется с помощью оператора `===`). 108 | 109 | При получении блока вместо элементов возвращается результат их итерации. 110 | `[ 1, 2, 3 ].grep(2) { |elem| elem > 4 } # -> [false]` 111 | 112 | `.find_all { |object| } # -> array` 113 | Синонимы: `select` 114 | 115 | Используется для получения всех элементов с положительным результатом итерации. 116 | `[1, 2, 3].find_all { |elem| elem > 4 } # -> [ ]` 117 | 118 | `.reject { |object| } # -> array` 119 | 120 | Используется для удаления всех элементов с положительным результатом итерации. 121 | `[1, 2, 3].reject { |elem| elem > 4 } # -> [1, 2, 3]` 122 | 123 | `.partition { |object| } # -> array` 124 | 125 | Используется для получения фрагментов с различными логическими результатами итерации. 126 | `[1, 2, 3].partition { |elem| elem > 2 } # -> [ [3], [1, 2] ]` 127 | 128 | `.detect( default = nil ) { |elem| } # -> object` 129 | Синонимы: `find` 130 | 131 | Используется для поиска первого элемента с положительным результатом итерации. Если искомый элемент не найден, то возвращается либо nil, либо значение по умолчанию. 132 | `[1, 2, 3].detect { |elem| elem > 4 } # -> nil` 133 | 134 | `.find_index( object = nil ) # -> index` 135 | 136 | `{ |object| } # -> index` 137 | 138 | Используется для поиска индекса первого элемента, либо равного переданному аргументу, либо с положительным результатом итерации. Если элемент не найден, то возвращается nil. 139 | `[1, 2, 3].find_index { |elem| elem > 4 } # -> nil` 140 | 141 | ### Сравнение элементов 142 | 143 | Сравнение выполняется с помощью оператора `<=>`. 144 | 145 | `.min # -> object` 146 | 147 | Наименьший элемент. 148 | `[1, 2, 3].min # -> 1` 149 | 150 | `.max # -> object` 151 | 152 | Наибольший элемент. 153 | `[1, 2, 3].max # -> 3` 154 | 155 | `.minmax # -> array` 156 | 157 | Наименьший и наибольший элементы. 158 | `[1, 2, 3].minmax # -> [1, 3]` 159 | 160 | `.min_by { |object| } # -> object` 161 | 162 | Элемент с наименьшим результатом итерации. 163 | `[1, 2, 3].min_by { |elem| -elem } # -> 3` 164 | 165 | `.max_by { |object| } # -> object` 166 | 167 | Элемент с наибольшим результатом итерации. 168 | `[1, 2, 3].max_by { |elem| -elem } # -> 1` 169 | 170 | `.minmax_by { |object| } # -> array` 171 | 172 | Элементы с наименьшим и наибольшим результатами итерации. 173 | `[1, 2, 3].minmax_by { |elem| -elem } # -> [3, 1]` 174 | 175 | ### Предикаты 176 | 177 | `.include?(object)` 178 | Синонимы: `member?` 179 | 180 | Проверка наличия элемента, равного переданному аргументу (сравнение выполняется с помощью оператора `==`). 181 | `[1, 2, 3].include? 4 # -> false` 182 | 183 | `.all? { |object| }` 184 | 185 | Проверка отсутствия элементов с отрицательным результатом итерации. При отсутствии блока проверяется каждый элемент. 186 | `[1, 2, 3].all? { |elem| elem < 4 } # -> true` 187 | 188 | `.any? { |object| }` 189 | 190 | Проверка наличия хотя бы одного элемента с положительным результатом итерации. При отсутствии блока проверяется каждый элемент. 191 | `[1, 2, 3].any? { |elem| elem < 4 } # -> true` 192 | 193 | `.one? { |object| }` 194 | 195 | Проверка наличия только одного элемента с положительным результатом итерации. При отсутствии блока проверяется каждый элемент. 196 | `[1, 2, 3].one? { |elem| elem < 4 } # -> false` 197 | 198 | `.none? { |object| }` 199 | 200 | Проверка отсутствия элементов с положительным результатом итерации. При отсутствии блока проверяется каждый элемент. 201 | `[1, 2, 3].none? { |elem| elem < 4 } # -> false` 202 | 203 | ### Итераторы 204 | 205 | `.collect { |object| } # -> array` 206 | Синонимы: `map, collect_concat, flat_map` 207 | 208 | Перебор элементов с сохранением результатов итерации. 209 | 210 | ~~~~~ ruby 211 | [1, 2, 3].collect { |elem| elem < 4 } # -> [true, true, true] 212 | (1..3).collect(&:next) * ?| # -> "2|3|4" 213 | ~~~~~ 214 | 215 | `.reverse_each( *arg ) { |object| } # -> self` 216 | 217 | Перебор элементов в обратном порядке. 218 | 219 | `.each_with_index { |object, index| } # -> self` 220 | 221 | Перебор элементов вместе с индексами. 222 | 223 | `.each_with_object(object) { |elem, object| } # -> object` 224 | 225 | Перебор элементов вместе с переданным объектом. 226 | 227 | `.each_slice(size) { |array| } # -> nil` 228 | 229 | Перебор фрагментов заданного размера. 230 | 231 | `.each_cons(size) { |array| } # -> nil` 232 | 233 | Перебор фрагментов заданного размера. После каждой итерации из начала фрагмента будет удаляется элемент, а в конец будет добавлен следующий элемент составного объекта. 234 | 235 | `.each_entry { |object| } # -> nil` 236 | 237 | Перебор элементов. Несколько объектов, переданных инструкции yield в теле метода `.each`, сохраняются в индексном массиве. 238 | 239 | ### Циклы 240 | 241 | `.drop_while { |object| } # -> array` 242 | 243 | Выполнение блока для всех элементов кроме первого вплоть до получения отрицательного результата итерации. Возвращаются элементы, итерация которых не выполнялась. Иными словами элементы удаляются пока результат итерации положителен. 244 | `[1, 2, 3].drop_while { |elem| elem < 4 } # -> [ ]` 245 | 246 | `.take_while { |object| } # -> array` 247 | 248 | Выполнение блока для всех элементов кроме первого вплоть до получения отрицательного результата итерации. Возвращаются элементы, итерация которых выполнялась. Иными словами элементы сохраняются пока результат итерации положителен. 249 | `[1, 2, 3].take_while { |elem| elem < 4 } # -> [1, 2, 3]` 250 | 251 | `.cycle( step = nil ) { |object| } # -> nil` 252 | 253 | Выполнение блока для всех элементов в бесконечном цикле. Выполнение может быть остановлено с помощью инструкций или ограничения количества циклов. Если методу передано отрицательное число, то вызов метода завершается до выполнения. 254 | 255 | ### Остальное 256 | 257 | `.lazy # -> a_lazy_enumerator [Ruby 2.0]` 258 | 259 | Используется для создания перечня, позволяющего выполнять [отложенные вычисления](lazy). 260 | 261 | `.inject(method) # -> object` 262 | 263 | `(first, method) # -> object` 264 | 265 | `(first = nil) { |buffer, first| } # -> buffer` 266 | Синонимы: `reduce` 267 | 268 | Используется для объединения элементов либо с помощью указанного метода, либо передавая результат каждой итерации первому параметру блока. Выполнение начинается с первого элемента или с дополнительно переданного аргумента. 269 | 270 | Часто используется в функциональном стиле программирования и известно как "свертка". 271 | `[1, 2, 3].inject( 100, :+ ) # -> 106` -------------------------------------------------------------------------------- /book/enumerate.tex: -------------------------------------------------------------------------------- 1 | \chapter{Составные объекты} 2 | 3 | \textbf{Добавленные модули: Enumerable} 4 | 5 | \input{array.tex} 6 | \input{hash.tex} 7 | \input{range.tex} 8 | \input{enumerator.tex} 9 | \input{enumerable.tex} 10 | -------------------------------------------------------------------------------- /book/enumerator.md: -------------------------------------------------------------------------------- 1 | ## Enumerator (перечни) 2 | 3 | Перечни - это составные объекты, содержащие группу элементов и о методе, вызов которого привел к их группировке. Индексация элементов начинается с нуля. 4 | 5 | Перечень всех элементов может быть получен с помощью итераторов, которым не был передан блок. 6 | 7 | `::new( object, method, *arg ) # -> enum` 8 | 9 | `{ |enum| } # -> enum` 10 | 11 | Используется для создания перечня. Результат также может быть передан в блок. В теле блока предоставляется возможность добавлять элементы в перечень с помощью выражения `enum << object` (как синоним для yield). Тело блока будет выполняться в момент использования перечня. 12 | 13 | ~~~~~ ruby 14 | Enumerator.new( [1, 2, ?R], :delete_at, 2 ) 15 | # -> # 16 | 17 | Enumerator.new { |enum| enum << 3 } 18 | # -> #:each> 19 | ~~~~~ 20 | 21 | `.enum_for( method = :each, *arg ) # -> enum` 22 | Синонимы: `to_enum` 23 | 24 | Используется для создания перечня элементов текущего составного объекта. 25 | `[1, 2, ?R].enum_for # -> #` 26 | 27 | **Во второй версии Ruby** метод принимает блок, с помощью которого может быть вычислен размер перечня (без вычисления его элементов). 28 | 29 | ~~~~~ ruby 30 | module Enumerable 31 | # Дублирование элементов составного объекта. 32 | def repeat(n) 33 | raise ArgumentError, "#{n} is negative!" if n < 0 34 | if block_given? 35 | each { |*val| n.times { yield *val } } 36 | else 37 | # __method__ == :repeat 38 | enum_for( __method__, n ) { size * n if size } 39 | end 40 | end 41 | end 42 | 43 | enum = (1..14).repeat(3) 44 | enum.first(4) # -> [1, 1, 1, 2] 45 | enum.size # -> 42 46 | ~~~~~ 47 | 48 | ### Приведение типов 49 | 50 | `.inspect # -> string` 51 | 52 | Используется для получения информации об объекте. 53 | 54 | ~~~~~ ruby 55 | Enumerate.new( [1, 2, ?R], :delete_at, 2 ).inspect 56 | # -> "#" 57 | ~~~~~ 58 | 59 | ### Элементы перечня 60 | 61 | `.next # -> object` 62 | 63 | Используется для последовательного доступа к элементам перечня. Достижение конца перечня считается исключением `StopIteration`. 64 | 65 | `.next_values # -> array` 66 | 67 | Версия предыдущего метода, возвращающая элементы в индексном массиве. Этот метод может быть использован для различия между инструкциями yield и yield nil. 68 | 69 | `.peek # -> object` 70 | 71 | Используется для получения следующего элемента перечня. Достижение конца перечня считается исключением `StopIteration`. 72 | 73 | `.peek_values # -> array` 74 | 75 | Версия предыдущего метода, возвращающая элементы в индексном массиве. Этот метод может быть использован для различия между инструкциями yield и yield nil. 76 | 77 | `.rewind # -> enum` 78 | 79 | Используется для обнуления позиции последнего извлеченного элемента. 80 | 81 | ### Итераторы 82 | 83 | `.each( start = 0 ) { |object| } # -> self` Перебор элементов. 84 | 85 | `.with_index( start = 0 ) { |object, index| } # -> self` 86 | 87 | Перебор элементов с их индексами. 88 | 89 | `.with_object(object) { |object2, object| } # -> object` 90 | 91 | Перебор элементов вместе с дополнительным объектом. 92 | 93 | ### Остальное 94 | 95 | `.feed( object = nil ) # -> nil` 96 | 97 | Используется для изменения результата следующей итерации перечня. При вызове без аргументов, использование инструкции yield возвращает nil. 98 | 99 | `.size # -> integer [Ruby 2.0]` 100 | 101 | Используется для получения размера перечня без вычисления его элементов. Если вычисление невозможно, то возвращается nil. 102 | 103 | ~~~~~ ruby 104 | (1..100).to_a.permutation(4).size # -> 94109400 105 | loop.size # -> Float::INFINITY 106 | (1..100).drop_while.size # -> nil 107 | ~~~~ 108 | 109 | [](lazy) 110 | ### Отложенные вычисления (Enumerator::Lazy) 111 | 112 | Класс расширяет понятие перечня (наследует Enemerator). 113 | 114 | **Во второй версии Ruby** добавлена возможность откладывать итерацию элементов составного объекта (возможно бесконечного) до того момента как они потребуются. 115 | 116 | К сожалению отложенные вычисления обычно медленнее чем обычные, поэтому их применение должно быть оправдано. 117 | 118 | `::new( enum, size = nil ) { | yielder, *values | } # -> a_lazy_enum` 119 | 120 | Используется для создания объекта. Когда будет вычисляться содержимое перечня, элементы составного объекта будут переданы в блок и смогут быть возвращены в перечень с помощью первого параметра блока. 121 | 122 | ~~~~~ ruby 123 | # Принудительное вычисление. 124 | module Enumerable 125 | def filter_map(&block) 126 | map(&block).compact 127 | end 128 | end 129 | 130 | # Отложенное вычисление. 131 | class Enumerator::Lazy 132 | def filter_map 133 | Lazy.new(self) do | yielder, *values | 134 | result = yield *values 135 | yielder << result if result 136 | end 137 | end 138 | end 139 | 140 | (1..Float::INFINITY).lazy.filter_map{ |i| i*i if i.even? }.first(5) 141 | # -> [ 4, 16, 36, 64, 100 ] 142 | ~~~~~ 143 | 144 | `.lazy # -> a_lazy_enum` 145 | 146 | Используется для создания перечня, позволяющего выполнять отложенные вычисления. 147 | 148 | ~~~~~ ruby 149 | [1,2,3].lazy # -> # 150 | ~~~~~ 151 | 152 | #### Методы 153 | 154 | `.force # -> array` 155 | Синонимы: `to_a` 156 | 157 | Используется для принудительного вычисления элементов. 158 | 159 | `.collect_concat { |object| } # -> a_lazy_enum` 160 | Синонимы: `flat_map` 161 | 162 | Используется для получения нового перечня, содержащего результаты итерации всех элементов текущего. 163 | 164 | ~~~~~ ruby 165 | [ 'foo', 'bar' ].lazy.flat_map { |i| i.each_char.lazy }.force 166 | # -> [ 'f', 'o', 'o', 'b', 'a', 'r' ] 167 | ~~~~~ 168 | 169 | Результаты итерации будут объединяться в том случае, если они относятся к перечням (отвечают на вызовы методов `.each` и `.force`) или массивам (отвечают на вызов метода `.to_ary`). 170 | 171 | ~~~~~ ruby 172 | [ {a:1}, {b:2} ].lazy.flat_map { |i| i }.force 173 | #=> [ {a:1}, {b:2} ] 174 | ~~~~~ 175 | 176 | `.enum_for( method = :each, *args ) # -> a_lazy_enum` 177 | 178 | `( method = :each, *args ) { |*args| } # -> a_lazy_enum` 179 | Синонимы: `to_enum` 180 | 181 | Аналогично соответствующему методу из модуля Kernel. Используется для того, чтобы методы из модуля Enumerable могли возвращать новый вид перечней, если вызываются для объектов подобного типа. 182 | 183 | ~~~~~ ruby 184 | r = 1..Float::INFINITY 185 | 186 | # Принудительные вычисления. 187 | r.repeat(2).first(5) # -> [ 1, 1, 2, 2, 3 ] 188 | r.repeat(2).class # -> Enumerator 189 | r.repeat(2).map{ |n| n ** 2 }.first(5) # -> бесконечный цикл! 190 | 191 | # Отложенные вычисления. 192 | r.lazy.repeat(2).class # -> Enumerator::Lazy 193 | r.lazy.repeat(2).map{ |n| n ** 2 }.first(5) # -> [ 1, 1, 4, 4, 9 ] 194 | ~~~~~ 195 | 196 | #### Применение 197 | 198 | + Итерация бесконечных объектов; 199 | + Работа с большими файлами. 200 | 201 | ~~~~~ ruby 202 | lines = File.foreach('a_very_large_file') 203 | .lazy # чтение только необходимой части. 204 | .select { |line| line.length < 10 } 205 | .map(&:chomp) 206 | .each_slice(3) 207 | .map { |lines| lines.join(';').downcase } 208 | .take_while { |line| line.length > 20 } 209 | 210 | # Чтение первых трёх строк файла или 211 | # до тех пор пока длина строки не превысит 20 символов. 212 | lines.first(3) 213 | 214 | lines.to_a # или... 215 | lines.force # чтение файла 216 | lines.each { |elem| puts elem } # и запись каждой строки. 217 | ~~~~~ 218 | -------------------------------------------------------------------------------- /book/exception.md: -------------------------------------------------------------------------------- 1 | # Исключения 2 | 3 | Исключение - это допустимая ошибка, возникающая в процессе выполнения программы, прерывающая выполнение до тех пор, пока не ислючение не будет обработано. Если исключение не обрабатывается, то выполнение программы прекращается. 4 | 5 | Каждое исключение относится к классу Exception и его производным. Обычно название каждого подкласса, содержит полную информацию о причине возникновения исключения. 6 | 7 | Для создания новых типов исключений обычно используются классы StandartError и RuntimeError. 8 | 9 | Системные ошибки, имеющие стандартный цифровой код, также относятся к исключениям. Модуль Errno динамически связывает полученные от операционной системы цифровые коды с подклассами Exception. При этом для каждой ошибки создается собственный подкласс `SystemCallError`, на который ссылается константа в модуле Errno. Цифровой код ошибки может быть получен с помощью константы Errno (`Errno::::Errno`). 10 | 11 | ## Иерархия исключений 12 | 13 | + _Exception_ - базовый класс для всех исключений. 14 | 15 | * _NoMemoryError_ - выделение памяти не может быть выполнено; 16 | 17 | _ScriptError_- базовый класс для ошибок интерпретации; 18 | + _LoadError_ - файл не может быть загружен; 19 | _NotImplemenetedError_ - метод не поддерживается системой; 20 | _SyntaxError_ - ошибка в синтаксисе; 21 | 22 | _SecuirityError_ - нарушение требований безопасности; 23 | 24 | _SignalException_ - получение сигнала от системы; 25 | + _Interrupt_ - сигнал прервать процесс выполнения (обычно Ctrl+C); 26 | 27 | _SystemExit_ - завершение выполнения программы системой; 28 | 29 | _SystemStackError_ - переполнение стека; 30 | 31 | _StandardError_ - базовый класс для стандартных ошибок выполнения; 32 | + _Math::DomainError_ - объекты не принадлежат области определения функции; 33 | _ArgumentError_ - ошибка при передаче аргументов; 34 | 35 | _EncodingError_ - базовый класс для ошибок, связанных с кодировкой; 36 | + _Encoding::CompatibilityError_ - исходная кодировка не совместима с требуемой; 37 | _Encoding::ConverterNotFoundError_ - требуемая кодировка не поддерживается; 38 | _Encoding::InvalidByteSequenceError_ - текст содержит некорректные байты; 39 | _Encoding::UndefinedConversionError_ - текст содержит неопределенные символы; 40 | 41 | _FiberError_ - ошибка при работе с управляемыми блоками; 42 | 43 | _IOError_ - возникновение ошибки при работе с потоками; 44 | + _EOFError_ - достигнут конец файла; 45 | 46 | _IndexError_ - индекс не найден; 47 | + _KeyError_ - ключ не найден; 48 | _StopIteration_ - завершение итерации; 49 | 50 | _LocalJumpError_ - блок не может быть выполнен; 51 | 52 | _NameError_ - неизвестный идентификатор; 53 | + _NoMethodError_ - неизвестный метод; 54 | 55 | _RangeError_ - выход за границы диапазона; 56 | + _FloatDomainError_ - попытка преобразования констант для определения специальных чисел (NaN и т.д.); 57 | 58 | _RegexpError_ - ошибка в регулярном выражении; 59 | 60 | _RuntimeError_ - универсальный класс для ошибок выполнения; 61 | 62 | _SystemCallError_ - базовый класс для системных ошибок; 63 | 64 | _ThreadError_ - ошибка при работе с процессами; 65 | 66 | _TypeError_ - неправильный тип объекта. Данное исключение также возникает при объявлении наследования для существующего класса; 67 | 68 | _ZeroDivisionError_ - деление целого числа на ноль. 69 | 70 | ## Методы 71 | 72 | ### Exception 73 | 74 | `::exception( message = nil ) # -> exception` 75 | 76 | Используется для создания объекта. Для аргумента вызывается метод `object.to_str`. 77 | 78 | `::new( mesage = nil ) # -> exception` 79 | 80 | Используется для создания объекта. 81 | 82 | `.exception( message = nil ) # -> exception` 83 | 84 | Используется для получения нового экземпляра того же класс. Для аргумента вызывается метод `.to_str`. 85 | 86 | `.backtrace # -> array` 87 | 88 | Используется для получения данных о распространении исключения. Каждый элемент имеет вид: 89 | `"имя_файла:номер_строки: in 'идентификатор_метода'"` 90 | или 91 | `"имя_файла:номер_строки"` 92 | 93 | `.set_backtrace(array) # -> array` 94 | 95 | Используется для изменения данных о распространении исключения. 96 | 97 | `.to_s # -> string` 98 | Синонимы: `message` 99 | 100 | Сообщение об ошибке (или идентификатор класса). 101 | 102 | `.inspect # -> string` Идентификатор класса. 103 | 104 | ### LoadError [ruby 2.0] 105 | 106 | `.path # -> string` 107 | 108 | Метод используется для получения пути, по которому не был найден файл. 109 | 110 | ### SignalException 111 | 112 | `::new(sig_name) # -> a_signal_exception` 113 | 114 | `(sig_number, name = nil)` 115 | 116 | Метод используется для создания нового объекта. Название сигнала должно быть известно интерпретатору. 117 | 118 | `.signo # -> number` 119 | 120 | Метод используется для получения номера сигнала. 121 | 122 | ### SystemExit 123 | 124 | `::new( status = 0 ) # -> exception` 125 | 126 | Используется для создания нового объекта. 127 | 128 | `.status # -> integer` Статус завершения программы. 129 | 130 | `.success? # -> bool` 131 | 132 | Проверка удалось ли завершение программы. 133 | 134 | ### Encoding::InvalidByteSequenceError 135 | 136 | `.destination_encoding # -> encoding` Требуемая кодировка 137 | 138 | `.destination_encoding_name # -> string` Название требуемой кодировки. 139 | 140 | `.source_encoding # -> encoding` 141 | 142 | Исходная кодировка. При нескольких преобразованиях исходной будет считаться последняя стабильная кодировка. 143 | 144 | `.source_encoding_name # -> string` 145 | 146 | Название исходной кодировки. При нескольких преобразованиях исходной будет считаться последняя стабильная кодировка. 147 | 148 | `.error_bytes # -> string` 149 | 150 | Байт из-за которого возникло исключение. 151 | 152 | `.incomplete_input? # -> bool` 153 | 154 | Проверка возникновения исключения из-за преждевременного завершения текста. 155 | 156 | `.readagain_bytes # -> string` 157 | 158 | Байт, обрабатываемый в момент возникновения исключения. 159 | 160 | ### Encoding::UndefinedConversionError 161 | 162 | `.destination_encoding # -> encoding` Требуемая кодировка 163 | 164 | `.destination_encoding_name # -> string` Название требуемой кодировки. 165 | 166 | `.source_encoding # -> encoding` 167 | 168 | Исходная кодировка. При нескольких преобразованиях исходной будет считаться последняя стабильная кодировка. 169 | 170 | `.source_encoding_name # -> string` 171 | 172 | Название исходной кодировки. При нескольких преобразованиях исходной будет считаться последняя стабильная кодировка. 173 | 174 | `.error_char # -> string` 175 | 176 | Символ из-за которого возникла ошибка. 177 | 178 | ### StopIteration 179 | 180 | `.result # -> object` 181 | Результат итерации. 182 | 183 | ### LocalJumpError 184 | 185 | `.exit_value # -> object` 186 | 187 | Аргумент, передача которого привела к возникновению исключения. 188 | 189 | `.reason # -> symbol` 190 | 191 | Идентификатор инструкции, выполнение которой привело к возникновению исключения (:break, :redo, :retry, :next, :return, или :noreason). 192 | 193 | ### NameError 194 | 195 | `::new( message, name = nil ) # -> exception` 196 | 197 | Используется для создания нового объекта. 198 | 199 | `.name # -> name` 200 | 201 | Идентификатор, использование которого привело к возникновению исключения. 202 | 203 | ### NoMethodError 204 | 205 | `::new( message, name, *args ) # -> exception` 206 | 207 | Используется для создания нового объекта. 208 | 209 | `.args # -> object` 210 | 211 | Аргументы, переданные отсутствующему методу. 212 | 213 | ### SystemCallError 214 | 215 | `::new( message, integer ) # -> exception` 216 | 217 | Используется для создания нового экземпляра класса из модуля Errno (если методу передан известный системе цифровой код ошибки) или класса SystemCallError. 218 | 219 | `.errno # -> integer` Цифровой код ошибки. 220 | 221 | ## Возникновение и обработка исключений 222 | 223 | ### Вызов исключения 224 | 225 | Вызов исключения выполняется с помощью частного метода экземпляров из модуля Kernel. 226 | 227 | `.raise( message = nil ) # -> exception` 228 | 229 | `( exc = RuntimeError, message = nil, pos = caller ) # -> exception` 230 | Синонимы: `fail` 231 | 232 | Используется для повторного вызова последнего исключения или создания нового ( RuntimeError), если `$!` ссылается на nil. 233 | 234 | В другом случае методу передаются любой объект, отвечающий на вызов метода `.exception`, сообщение об ошибке и текущая позиция выполнения программы. 235 | 236 | ### Обработка исключений 237 | 238 | Обработка событий выполняется с помощью предложения rescue, которое может использоваться только в теле предложений begin, def, class, или module. 239 | 240 | Исключения обрабатываются в том же порядке, в котором объявляются обработчики. При возникновении исключения интерпретатор останавливает процесс выполнения программы и начинает поиск обработчика, продвигаясь вверх по области вызова. 241 | 242 | Если исключения возникло в результате обработки другого исключения, то поиск обработчиков выполняется заново. 243 | 244 | После обработки исключения выполнение программы не продолжается. 245 | 246 | #### Полный синтаксис 247 | 248 | ~~~~~ ruby 249 | begin 250 | тело_предложения 251 | rescue 252 | тело_обработчика 253 | else 254 | code 255 | ensure 256 | code 257 | end 258 | ~~~~~ 259 | 260 | + Тело обработчика выполняется после возникновения исключения в теле предложения. Переменная `$!` при этом ссылается на конкретный экземпляр исключения. 261 | 262 | Чтобы инициализировать локальную переменную используют инструкцию 263 | `rescue => локальная_переменная`. 264 | 265 | + По умолчанию обрабатываются экземпляры StandardError и его производных. 266 | 267 | Для ограничения типов обрабатываемых исключений используют инструкцию `rescue class` или `rescue class => локальная_переменная`. Несколько классов разделяются запятыми. 268 | 269 | + Инструкция else выполняется если исключений не получено. При этом исключения, возникшие в теле инструкции не обрабатываются. 270 | 271 | + Инструкция ensure выполняется после выполнения всего предложения. Результат ее выполнения не влияет на результат выполнения предложения (кроме случаев использования инструкций return, break и т.д) 272 | 273 | #### Краткий синтаксис: 274 | 275 | `код rescue тело_обработчика` 276 | 277 | Если в коде будет вызвана ошибка, то выполняется тело обработчика. Обрабатываются только экземпляры StandardError и его производных. 278 | 279 | ### Catch и Throw 280 | 281 | В других языках программирования обработка событий обычно выполняется с помощью пары инструкций catch и throw. В Ruby существуют частные методы экземпляров из модуля Kernel, ведущие себя сходным образом. 282 | 283 | `.catch(name = nil) { |name| } # -> object` 284 | 285 | Используется для создания прерываемого фрагмента кода. Выполнение останавливается при вызове метода `object.throw` с тем же идентификатором. При вызове без аргументов новый случайный идентификатор передается блоку. 286 | 287 | `.throw( name, *args )` 288 | 289 | Используется для завершения выполнения блока, переданного методу `object.catch` с тем же идентификатором (иначе возникает исключение). Поиск блока выполняетcя вверх по иерархии области видимости. Дополнительные аргументы возвращаются методом `object.catch`. 290 | -------------------------------------------------------------------------------- /book/execution.md: -------------------------------------------------------------------------------- 1 | # Выполнение программы 2 | 3 | ## Запуск программы 4 | 5 | Запуск программ выполняется из терминала. Общий вид команды: 6 | `ruby [keys] [path] [args]` 7 | 8 | + _keys_ - заранее определенные [спецсимволы или идентификаторы](appbin), влияющие на выполнение программы; 9 | 10 | _path_ - путь к запускаемой программе. Поиск программы выполняется относительно текущего каталога. 11 | 12 | Если имя программы не указано, или передается одиночный дефис, то интерпретатор будет выполнять код, полученный из стандартного потока для чтения информации (обычно связанного с терминалом). 13 | 14 | _args_ - произвольный набор символов, которые будут переданы программе как элементы индексного массива ARGV. 15 | 16 | Файлы, доступные для выполнения (скрипты или исполняемые файлы), могут содержать информацию об интерпретаторе в первом комментарии (shebang) программы: 17 | 18 | `#!/usr/bin/env ruby [keys] [args]` 19 | 20 | В этом случае для запуска программы требуется только ввести в терминале путь к ней. 21 | 22 | Кроме переданных ключей на выполнение программы также могут влиять [переменные окружения и предопределенные глобальные переменные](appbin). 23 | 24 | Переменные окружения - это переменные, установленные операционной системой. В Linux список установленных переменных может быть получен с помощью команды `env`. 25 | 26 | ## Ход выполнения 27 | 28 | Ход выполнения программы - это непосредственное выполнение ее кода. 29 | 30 | Ход выполнения может быть разделен на три этапа: подготовка, выполнение и завершение выполнения. 31 | 32 | BEGIN и END - это предложения, выполняющиеся на стадиях подготовки и завершения выполнения соответственно. Тело каждого предложения определяет собственную локальную область видимости и выполняется строго один раз. 33 | 34 | + _BEGIN { }_ - код выполняется на стадии подготовки выполнения. Если в коде программы используется несколько таких предложений, то они выполняются последовательно в порядке записи; 35 | 36 | _END { }_ - код выполняется на стадии завершения выполнения. Если в коде программы используется несколько таких предложений, то они выполняются последовательно в обратном порядке. Для выполнения этого предложения используется экземпляр File, на который ссылается константа DATA; 37 | 38 | *\_\_END\_\_* - аналогично END; 39 | 40 | *at_exit { }* - аналогично END. 41 | 42 | ## Завершение выполнения 43 | 44 | Для завершения выполнения программы используются частные методы экземпляров из модуля Kernel (методы влияют на любой поток выполнения, в теле которого взываются). 45 | 46 | `.sleep( sec = nil ) # -> sec` 47 | 48 | Используется для временной остановки выполнения (по умолчанию навсегда). В результате возвращается время фактического ожидания. 49 | 50 | `.exit( state = true )` 51 | 52 | Используется для завершения выполнения с помощью исключения `SystemExit`. 53 | 54 | `.exit!( state = false )` 55 | 56 | Используется для немедленного завершения выполнения. 57 | 58 | `.abort( mesage = nil )` 59 | 60 | Используется для немедленного завершения выполнения. Аргумент записывается в стандартный поток для вывода ошибок. Аналогично выполнению `exit false`. 61 | 62 | ## Вызов системных команд 63 | 64 | На Ruby довольно часто создают небольшие скрипты, облегчающие вызов различных системных команд. Для этого используются частные методы экземпляров из модуля Kernel. 65 | 66 | ``.`(code) # -> string`` 67 | 68 | Используется для вызова системной команды. 69 | `ruby --help` 70 | 71 | Тот же эффект достигается при ограничении текста произвольными разделителями с использованием приставки `%x` (`%x[ruby --help]`). 72 | 73 | `.exec( env, command, options )` 74 | 75 | Используется для замены текущего процесса выполнения на выполнение системной команды. Невозможность выполнения команды считается исключением. 76 | 77 | **Во второй версии Ruby** нестандартные файловые дескрипторы закрываются автоматически. 78 | 79 | ##### Аргументы: 80 | 81 | `env (hash):` управление переменными окружения. 82 | 83 | + _name:_ значение для переменной окружения; 84 | _name:_ nil, удаление переменной окружения. 85 | 86 | `command:` системный вызов. 87 | 88 | + _string_ - текст команды для используемой оболочки: по умолчанию в Unix - это `"/bin/sh"`, а в Windows - `ENV["RUBYSHELL"]` или `ENV["COMSPEC"]`; 89 | _string, *arg_ - текст команды и передаваемые аргументы; 90 | _[ string, first_arg ], *arg_ - текст команды, первый аргумент и остальные аргументы. 91 | 92 | `option (hash):` дополнительный аргумент. 93 | 94 | + _unsetenv_others:_ true, удаление всех переменных окружения, кроме переданных методу; 95 | _pgroup:_ группировка процессов: 96 | * true для создания новой группы; 97 | * integer для сохранения процесса в соответствующей группе; 98 | * nil для отмены группировки. 99 | 100 | _chdir:_ путь к текущему рабочему каталогу; 101 | _umask:_ права доступа для создаваемых файлов или каталогов. 102 | 103 | ***** 104 | 105 | `.syscall( number, *args )` 106 | 107 | Используется для выполнения системного вызова с переданным цифровым идентификатором (для Unix систем идентификаторы и функции описаны в файле syscall.h). 108 | 109 | Дополнительно (не более девяти аргументов) методу передаются либо текст, содержащий указатель на последовательность байт, либо размер указателя в битах. 110 | 111 | Невозможность выполнения системного вызова считается исключением `SystemCallEror`. 112 | 113 | Невозможность вызова метода считается исключением `NotImplementedError`. 114 | 115 | Метод непереносим и небезопасен в использовании. -------------------------------------------------------------------------------- /book/filestat.md: -------------------------------------------------------------------------------- 1 | ## Информация о файле 2 | 3 | `.test( type, first_path, second_path = nil )` 4 | 5 | Информация о переданных файлах. 6 | 7 | ##### Тип информации: 8 | 9 | `?A` - время последнего доступа к файлу; 10 | 11 | `?C` - время последнего изменения информации о файле; 12 | 13 | `?M` - время последнего изменения файла; 14 | 15 | `?e` - проверка существования файла; 16 | 17 | `?s` - размер файла. Для фалов нулевого размера возвращается nil; 18 | 19 | `?z` - проверка существования файла нулевого размера; 20 | 21 | `?f` - проверка существования обычного файла; 22 | 23 | `?L` - проверка существования символьной ссылки; 24 | 25 | `?d` - проверка существования каталога; 26 | 27 | `?b` - проверка существования блочного устройства; 28 | 29 | `?c` - проверка существования символьного устройства; 30 | 31 | `?S` - проверка существования сокета; 32 | 33 | `?p` - проверка существования конвейера; 34 | 35 | `?r` - проверка возможности чтения на основе действующих идентификаторов; 36 | 37 | `?R` - проверка возможности чтения на основе реальных идентификаторов; 38 | 39 | `?w` - проверка возможности записи на основе действующих идентификаторов; 40 | 41 | `?W` - проверка возможности записи на основе реальных идентификаторов; 42 | 43 | `?x` - проверка возможности выполнения на основе действующих идентификаторов; 44 | 45 | `?X` - проверка возможности выполнения на основе реальных идентификаторов; 46 | 47 | `?u` - проверка возможности выполнения файла с правами владельца; 48 | 49 | `?g` - проверка возможности выполнения файла с правами группы владельцев; 50 | 51 | `?K` - проверка существования дополнительного свойства (sticky bit) для каталогов; 52 | 53 | `?o` - проверка равенства идентификатора владельца файла и действующего идентификатора (текущий пользователь является владельцем файла); 54 | 55 | `?O` - проверка равенства идентификатора владельца файла и реального идентификатора (текущий пользователь является владельцем файла); 56 | 57 | `?G` - проверка равенства цифрового идентификатора текущей группы и цифрового идентификатора группы владельцев файла (текущий пользователь относится к владельцам файла); 58 | 59 | `?-` - проверка ссылаются ли два пути на один и тот же файл; 60 | 61 | `?=` - проверка равенства времени последнего изменения двух файлов; 62 | 63 | `?<` - используется для сравнения времени последнего изменения двух файлов; 64 | 65 | `?>` - используется для сравнения времени последнего изменения двух файлов. 66 | 67 | ***** 68 | 69 | ### Класс File::Stat 70 | 71 | Экземпляры класса получаются с помощью методов `file.stat` и `file.lstat`. Это позволяет получать полную информацию о файле, обратившись к системе только один раз. 72 | 73 | `::new(path) # -> stat` 74 | 75 | Используется для сбора информации о файле. Отсутствие файла считается исключением. 76 | 77 | #### Приведение типов 78 | 79 | `.inspect # -> string` 80 | 81 | Информация об объекте. 82 | 83 | #### Операторы 84 | 85 | `.<=>(stat)` 86 | 87 | Используется для сравнения времени сбора информации. 88 | 89 | #### Права доступа 90 | 91 | Для проверки прав доступа определены методы, аналогичные методам экземпляров класса File. 92 | 93 | + `.readable?` 94 | `.readable_real?` 95 | `.world_readable?` 96 | `.writable?` 97 | `.writable_real?` 98 | `.world_writable?` 99 | `.executable?` 100 | `.executable_real?` 101 | `.setuid?` 102 | `.setgid?` 103 | `.sticky?` 104 | `.owned?` 105 | `.grpowned?` 106 | 107 | `.uid # -> integer` 108 | 109 | Цифровой идентификатор владельца файла. 110 | 111 | `.gid # -> integer` 112 | 113 | Цифровой идентификатор группы владельцев файла. 114 | 115 | `.mode # -> perm` 116 | 117 | Права доступа. 118 | 119 | #### Статистика 120 | 121 | Для получения прав доступа определены методы, аналогичные методам из класса File. 122 | 123 | + `.atime` 124 | `.ctime` 125 | `.mtime` 126 | `.size` 127 | `.ftype` 128 | 129 | `.blksize # -> integer` 130 | 131 | Системный размер блока, выделенный для файла. Для систем, не поддерживающих эту информацию возвращается nil. 132 | 133 | `.blocks # -> integer` 134 | 135 | Системный номер блока, выделенный для файла. Для систем, не поддерживающих эту информацию возвращается nil. 136 | 137 | `.dev # -> integer` 138 | 139 | Цифровой код устройства, на котором размещена информация о файле. 140 | 141 | `.dev_major # -> integer` 142 | 143 | Основная часть цифрового кода устройства. 144 | 145 | `.dev_minor # -> integer` 146 | 147 | Дополнительная часть цифрового кода устройства. 148 | 149 | `.rdev # -> integer` 150 | 151 | Цифровой код устройства, на котором размещена информация о файле. 152 | 153 | `.rdev_major # -> integer` 154 | 155 | Основная часть цифрового кода устройства. 156 | 157 | `.rdev_minor # -> integer` 158 | 159 | Дополнительная часть цифрового кода устройства. 160 | 161 | `.ino # -> integer` 162 | 163 | Inode код файла. С помощью этого кода получается информация о файле от системы. 164 | 165 | `.nlink # -> integer` 166 | 167 | Цифровой код жесткой ссылки. 168 | 169 | #### Предикаты 170 | 171 | Определены методы, аналогичные методам из класса File. 172 | 173 | + `.zero?` 174 | `.file?` 175 | `.symlink?` 176 | `.directory?` 177 | `.blockdev?` 178 | `.chardev?` 179 | `.pipe?` 180 | `.socket?` 181 | 182 | ### Модуль FileTest 183 | 184 | #### Права доступа 185 | 186 | Для проверки прав доступа определены методы, аналогичные методам из класса File. 187 | 188 | + `FileTest::readable?(path)` 189 | `FileTest::readable_real?(path)` 190 | `FileTest::world_readable?(path)` 191 | `FileTest::writable?(path)` 192 | `FileTest::writable_real?(path)` 193 | `FileTest::world_writable?(path)` 194 | `FileTest::executable?(path)` 195 | `FileTest::executable_real?(path)` 196 | `FileTest::setuid?(path)` 197 | `FileTest::setgid?(path)` 198 | `FileTest::sticky?(path)` 199 | `FileTest::owned?(path)` 200 | `FileTest::grpowned?(path)` 201 | 202 | #### Предикаты 203 | 204 | Определены методы, аналогичные методам из класса File. 205 | 206 | + `FileTest::exist?(path)` (Синонимы: `exists?`) 207 | `FileTest::size?(path) # -> integer` 208 | `FileTest::zero?(path)` 209 | `FileTest::file?(path)` 210 | `FileTest::symlink?(path)` 211 | `FileTest::directory?(path)` 212 | `FileTest::blockdev?(path)` 213 | `FileTest::chardev?(path)` 214 | `FileTest::pipe?(path)` 215 | `FileTest::socket?(path)` 216 | 217 | #### Остальное 218 | 219 | Определены методы, аналогичные методам из класса File. 220 | 221 | + `FileTest::size(path) # -> integer` 222 | `FileTest::identical?( first_path, second_path )` -------------------------------------------------------------------------------- /book/float.md: -------------------------------------------------------------------------------- 1 | ## Десятичные дроби (Float) 2 | 3 | Десятичные дроби реализованы в Ruby как числа с плавающей точкой. 4 | 5 | ##### Константы: 6 | 7 | `Float::ROUNDS` - способ округления чисел по умолчанию; 8 | 9 | `Float::RADIX` - показатель степени для представления порядка числа; 10 | 11 | `Float::MANT_DIG` - количество цифр в мантиссе; 12 | 13 | `Float::DIG` - максимально возможная точность; 14 | 15 | `Float::MIN_EXP` - минимально возможный показатель степени 10; 16 | 17 | `Float::MAX_EXP` - максимально возможный показатель степени; 18 | 19 | `Float::MIN_10_EXP` - минимально возможная экспонента; 20 | 21 | `Float::MAX_10_EXP` - максимально возможная экспонента; 22 | 23 | `Float::MIN` - минимально возможная десятичная дробь; 24 | 25 | `Float::MAX` - максимально возможная десятичная дробь; 26 | 27 | `Float::EPSILON` - минимальное число, при добавлении к которому единицы, в результате не возвращается 1.0; 28 | 29 | `Float::INFINITY` - используется для бесконечности; 30 | 31 | `Float::NAN` - инициализируется в результате выполнения выражения `0.0 / 0.0`. 32 | 33 | ***** 34 | 35 | ### Приведение типов 36 | 37 | `.to_f # -> float` 38 | 39 | `.to_i # -> integer` 40 | 41 | Целая часть десятичной дроби. 42 | `2.1.to_i # -> 2` 43 | 44 | `.to_r # -> rational` 45 | 46 | Преобразование десятичной дроби в рациональную с максимально возможной точностью. 47 | `2.1.to_r # -> ( 4728779608739021 / 2251799813685248 )` 48 | 49 | `.rationalize( number = Flt::EPSILON ) # -> rational` 50 | 51 | Преобразование десятичной дроби в рациональную, так что 52 | `( self – number.abs ) <= rational and rational <= ( self + number.abs )` 53 | `2.1.rationalize # -> (21/10)` 54 | 55 | `.to_s # -> string` 56 | 57 | Преобразование десятичной дроби в текст. Допускается возвращение `"NaN"`, `"+Infinity"` или `"-Infinity"`. 58 | `2.1.to_s # -> "2.1"` 59 | 60 | ### Операторы 61 | 62 | `.*(number) # -> result` Произведение. 63 | 64 | `./(number) # -> result` Деление. 65 | 66 | `.**(number) # -> result` Возведение в степень. 67 | 68 | `.+(number) # -> result` Сумма. 69 | 70 | `.-(number) # -> result` Разность. 71 | 72 | ### Предикаты 73 | 74 | `.finite? # -> bool` 75 | 76 | Проверка относится ли десятичная дробь к конечным дробям. 77 | `2.1.finite? # -> true` 78 | 79 | `.infinite? # -> -1, nil, 1` 80 | 81 | Используется для вычисления направления бесконечности десятичной дроби. Если дробь относится к конечным дробям, то, в результате, возвращается nil. 82 | `2.1.infinite? # -> nil` 83 | 84 | `.nan? # -> bool` 85 | 86 | Проверка ссылается ли десятичная дробь на константу `Float::NAN`. 87 | `2.1.nan? # -> false` 88 | 89 | ### Остальное 90 | 91 | `.hash # -> integer` 92 | 93 | Цифровой код объекта. 94 | `2.1.hash # -> 569222191` -------------------------------------------------------------------------------- /book/hash.md: -------------------------------------------------------------------------------- 1 | ## Hash (ассоциативные массивы) 2 | 3 | `::new( object = nil ) # -> hash` 4 | 5 | `{ |hash, key| } # -> hash` 6 | 7 | Используется для создания массива с переданным значением по умолчанию. 8 | 9 | `::[ key, object ] # -> hash` 10 | 11 | `[ *[key,object] ] # -> hash` 12 | 13 | `[object] # -> hash` 14 | 15 | Используется для создания массива на основе переданных аргументов. 16 | 17 | ~~~~~ ruby 18 | Hash[:Ruby, "languages", :Ivan, "man"] 19 | # -> { Ruby: "languages", Ivan: "man" } 20 | 21 | Hash[ [ [:Ruby, "languages"], [:Ivan, "man"] ] ] 22 | # -> { Ruby: "languages", Ivan: "man" } 23 | 24 | Hash[Ruby: "languages", Ivan: "man"] 25 | # -> { Ruby: "languages", Ivan: "man" } 26 | ~~~~~ 27 | 28 | ### Приведение типов 29 | 30 | `.to_hash # -> hash` 31 | 32 | `.to_h # -> self [Ruby 2.0]` 33 | 34 | Возвращает объект, для которого был вызван. Когда вызывается для производных классов, получатель преобразуется ассоциативный массив. 35 | 36 | `::try_convert(object) # -> hash` 37 | 38 | Преобразование объекта в массив, с помощью метода `object.to_hash`. Если для объекта этот метод не определен, то возвращается nil. 39 | `Hash.try_convert[1] # -> nil` 40 | 41 | `.to_s # -> string` 42 | Синонимы: `inspect` 43 | 44 | Преобразование массива в текст. Спецсимволы экранируются. 45 | `{ a: ?a, "b" => '\n' }.to_s # -> "{:a=>\"a\", \"b\"=>\"\\\\n\"}"` 46 | 47 | `.to_a # -> array` 48 | 49 | Преобразование ассоциативного массива в индексный вида `[ *[key, object] ]`. Спецсимволы экранируются. 50 | `{ a: ?a, "b" => '\n' }.to_a # -> [ [:a, "a"], ["b", "\\n"] ]` 51 | 52 | ### Элементы 53 | 54 | `.[key] # -> object` 55 | 56 | Используется для получения значения ключа. Если ключ не найден, то возвращается значение по умолчанию. 57 | `{ a: ?a, "b" => 1 }[:a] # -> "a"` 58 | 59 | `.values_at(*key) # -> array` 60 | 61 | Используется для получения значений нескольких ключей. 62 | `{ a: ?a, "b" => 1 }.values_at :a, :b, ?b # -> ["a", nil, 1]` 63 | 64 | `.select { |key, object| } # -> hash` 65 | 66 | Используется для получения фрагмента массива, содержащего элементы с положительным результатом итерации. 67 | `{ a: ?a, "b" => 1 }.select { |key| key == ?b } # -> { "b"=>1 }` 68 | 69 | `.key(object) # -> key` 70 | 71 | Используется для получения ключа с переданным значением. Если ключ не найден, то возвращается nil. 72 | `{ a: ?a, "b" => 1 }.key ?a # -> :a` 73 | 74 | `.keys # -> array` 75 | 76 | Массив ключей. 77 | `{ a: ?a, "b" => 1 }.keys # -> [:a, "b"]` 78 | 79 | `.values # -> array` 80 | 81 | Массив значений. 82 | `{ a: ?a, "b" => 1 }.values # -> [ "a", 1 ]` 83 | 84 | `.[key]=(object) # -> object` 85 | Синонимы: `store` 86 | 87 | Используется для изменения содержимого массива. 88 | 89 | ~~~~~ ruby 90 | { a: ?a, "b" => 1 }[:a] = 2 # -> 2 91 | hash # -> { :a => 2, "b" => 1 } 92 | ~~~~~ 93 | 94 | `.fetch( key, default = nil ) # -> object` 95 | 96 | `(key) { |key| } # -> object` 97 | 98 | Используется для получения значения ключа. Отсутствие ключа считается исключением и может привести либо к остановке выполнения, либо к вычислению блока или дополнительного аргумента. 99 | `{ a: ?a, "b" => 1 }.fetch :b, ?a # -> "a"` 100 | 101 | ### Изменение массива 102 | 103 | #### Добавление элементов 104 | 105 | `.merge(hash) # -> hash2` 106 | 107 | `(hash) { |key, self_value, arg_value| } # -> hash2` 108 | 109 | Используется для объединения двух массивов. При совпадении ключей предпочтение отдается аргументу или результату выполнения блока. 110 | `{ a: ?a, "b" => 1 }.merge( { "b" => ?b } ) # -> { a: "a", "b" => "b" }` 111 | 112 | `.merge!(hash) # -> self` 113 | 114 | `(hash) { |key, self_value, arg_value| } # -> self` 115 | Синонимы: `update` 116 | 117 | Версия предыдущего метода, изменяющая значение объекта. 118 | 119 | #### Удаление элементов 120 | 121 | `.clear # -> self` 122 | 123 | Используется для удаления всех элементов (изменяется значение объекта). 124 | `{ a: ?a, "b" => 1 }.clear # -> { }` 125 | 126 | `.shift # -> array` 127 | 128 | Используется для удаления первого элемента (изменяется значение объекта). В результате возвращается индексный массив вида `[key, value]`. 129 | `{ a: ?a, "b" => 1 }.shift # -> [ :a, "a" ]` 130 | 131 | `.delete(key) # -> object` 132 | 133 | `(key) { |key| } # -> object` 134 | 135 | Используется для удаление заданного элемента (изменяется значение объекта). В результате возвращается значение ключа. Если ключ не найден, то возвращается значение по умолчанию или результат выполнения необязательного блока. 136 | 137 | ~~~~~ ruby 138 | { a: ?a, "b" => 1 }.delete :a # -> "a" 139 | hash # -> { "b"=>1 } 140 | ~~~~~ 141 | 142 | `.delete_if { |key, value| } # -> self` 143 | 144 | Используется для удаления всех элементов с положительным результатом итерации (изменяется значение объекта). 145 | `{ a: ?a, "b" => 1 }.delete_if { |key| key == ?b } # -> { a: "a" }` 146 | 147 | `.reject { |key, value| } # -> hash` 148 | 149 | Версия предыдущего метода, не изменяющая значение объекта. 150 | `{ a: ?a, "b" => 1 }.reject { |key| key == ?b } # -> { a: "a" }` 151 | 152 | `.reject! { |key, value| } # -> self || nil` 153 | 154 | Версия предыдущего метода, изменяющая значение объекта. Если ни один объект не был удален, то возвращается nil. 155 | `{ a: ?a, "b" => 1 }.reject! { |key| key == ?c } # -> nil` 156 | 157 | `.keep_if { |key, value| } # -> self` 158 | 159 | Используется для сохранения только элементов с положительным результатом итерации (изменяется значение объекта). 160 | `{ a: ?a, "b" => 1 }.keep_if { |key| key == ?b } # -> { "b"=>1 }` 161 | 162 | `.select! { |key, value| } # -> self` 163 | 164 | Версия предыдущего метода, возвращающая nil, если ни один элемент не был удален. 165 | `{ a: ?a, "b" => 1 }.select! { |key| key == ?b } # -> { "b"=>1 }` 166 | 167 | #### Остальное 168 | 169 | `.replace(hash) # -> self` 170 | Синонимы: `initialize_copy` 171 | 172 | Используется для замены значения объекта. 173 | `{ a: ?a, "b" => 1 }.replace( { } ) # -> { }` 174 | 175 | `.invert # -> hash` 176 | 177 | Используется для смены ключей и их значений местами. 178 | `{ a: ?a, "b" => 1 }.invert # -> { "a" => :a, 1 => "b" }` 179 | 180 | ### Предикаты 181 | 182 | `.has_key?(key)` 183 | Синонимы: `include?, key?, member?` 184 | 185 | Проверка наличия ключа. 186 | `{ a: ?a, "b" => 1 }.has_key? :a # -> true` 187 | 188 | `.has_value?(object)` 189 | Синонимы: `value?` 190 | 191 | Проверка наличия значения. 192 | `{ a: ?a, "b" => 1 }.has_value? :a # -> false` 193 | 194 | `.compare_by_identity? # -> bool` 195 | 196 | Проверка сравниваются ли все ключи по их объектам-идентификаторам. 197 | 198 | `.empty? # -> bool` 199 | 200 | Проверка отсутствия элементов. 201 | `{ a: ?a, "b" => 1 }.empty? # -> false` 202 | 203 | ### Итераторы 204 | 205 | `.each { |key, value| } # -> self` 206 | Синонимы: `each_pair` 207 | 208 | Перебор элементов. 209 | 210 | `.each_key { |key| } # -> self` Перебор ключей. 211 | 212 | `.each_value { |value| } # -> self` Перебор значений. 213 | 214 | ### Индексные массивы 215 | 216 | `.assoc(key) # -> array` 217 | 218 | Используется для получения индексного массива, содержащего найденный элемент. Если ключ не найден, то возвращается nil. Сравнение ключей выполняется с помощью оператора `==`. 219 | `{ a: ?a, "b" => 1 }.assoc :a # -> [:a, "a"]` 220 | 221 | `.rassoc(object) # -> array` 222 | 223 | Версия предыдущего методы, выполняющая поиск элемента по значению. 224 | `{ a: ?a, "b" => 1 }.rassoc ?a # -> [:a, "a"]` 225 | 226 | `.flatten( deep = 0 ) # -> array` 227 | 228 | Используется для получения индексного массива, содержащего элементы ассоциативного. Все вложенные индексные массивы будут извлекаться до заданного уровня. 229 | 230 | ~~~~~ ruby 231 | { 1 => "one", 2 => [ [2], ["two"] ], 3 => "three" }.flatten 3 232 | # -> [1, "one", 2, 2, "two", 3, "three"] 233 | ~~~~~ 234 | 235 | ### Остальное 236 | 237 | `.compare_by_identity # -> self` 238 | 239 | Используется для ограничения доступа к элементам с текстовыми ключами. 240 | 241 | ~~~~~ ruby 242 | { a: ?a, "b" => 1 }.compare_by_identity 243 | # -> { :a => "a", "b" => 1 } 244 | 245 | hash[:a] # -> "a" 246 | hash["b"] # -> nil 247 | hash[:b] # -> nil 248 | hash.key 1 # -> "b" 249 | ~~~~~ 250 | 251 | `.size # -> integer` 252 | Синонимы: `length` 253 | 254 | Количество элементов. 255 | `{ a: ?a, "b" => 1 }.size # -> 2` 256 | 257 | `.default # -> object` Значение по умолчанию. 258 | 259 | `.default_proc # -> proc` 260 | 261 | Подпрограмма, выполняющаяся по умолчанию (или nil). 262 | 263 | `.default=(object) # -> object` 264 | 265 | Используется для изменения значения по умолчанию. 266 | 267 | `.default_proc=(proc) # -> proc` 268 | 269 | Используется для изменения подпрограммы, выполняющейся по умолчанию. Аргумент nil отменяет выполнение подпрограммы (Ruby 2.0). 270 | 271 | `.hash # -> integer` 272 | 273 | Цифровой код объекта. 274 | `{ a: ?a, "b" => 1 }.hash # -> -3034512` 275 | 276 | `.rehash # -> hash` Используется для обновления цифровых кодов ключей. 277 | -------------------------------------------------------------------------------- /book/identificate.md: -------------------------------------------------------------------------------- 1 | # Переменные и константы 2 | 3 | Переменные и константы - это идентификаторы, предназначенные для получения доступа к объектам. Объекты, имеющие идентификатор могут быть использованы повторно. Выражение, связывающее объекты и идентификаторы, называется выражением присваивания. Объект, на который ссылается идентификатор, считается его значением. 4 | 5 | ~~~~~ note 6 | Переменные и константы также позволяют логически разделить используемые данные. Они облегчают понимание кода, позволяя перейти от терминов языка программирования к терминам решаемой задачи (проблемной области). Адекватность переменной (константы) во многом определяется ее названием. Название переменной можно рассматривать как высокоуровневый псевдокод, характеризующий ее содержимое. 7 | ~~~~~ 8 | 9 | Константы от переменных отличаются только областью применения. Константы используются для доступа к единственному постоянному объекту. В отличии от констант переменные подразумевают многократное использование. Переменная может использоваться как для изменения текущего объекта, так и для изменения значения переменной. 10 | 11 | ~~~~~ note 12 | На самом деле, в Ruby, переопределение констант не приведет к завершению процесса выполнения программы. Вместо этого интерпретатор просто выведет обычное предупреждение. 13 | ~~~~~ 14 | 15 | Для использования переменных и констант необходимо объявить интерпретатору об их существовании. Переменные и константы считаются существующими после выполнения первого выражения присваивания с их участием. Это выражение называют инициализацией. Процесс инициализации состоит из объявления (создания) идентификатора и определения (присваивания) объекта. 16 | 17 | Идентификаторы также могут быть объявлены и без выражения присваивания. Встретив подходящую лексему интерпретатор создаст требуемую переменную или константу. В этом случае определение выполняется автоматически (значением становится nil). Автоматическая инициализация предотвращает ошибки, возникающие при использовании переменных, не имеющих значения. Она также позволяет акцентировать внимание на объектах, а не на переменных. 18 | 19 | ~~~~~ note 20 | Идентификатор считается объявленным в любом случае если код содержит ее лексему, даже если фрагмент кода не выполнялся (значением становится nil). Это происходит из-за предварительной обработки кода для виртуальной машины. 21 | ~~~~~ 22 | 23 | ~~~~~ note 24 | Обычно если переменная объявлена, но при этом нигде не используется, то интерпретатор выдаст предупреждение. Чтобы этого избежать в качестве неиспользуемой переменной объявляют `_`. Во второй версии Ruby любая переменная, начинающаяся с подчеркивания будет считаться не используемой и предупреждений не будет. 25 | ~~~~~ 26 | 27 | ###### Область видимости: 28 | 29 | Фрагмент кода, в котором идентификатор существует и может быть использован. 30 | 31 | На основе областей видимости также осуществляется классификация переменных. К базовым областям видимости относятся глобальная и локальные области. Глобальная область видимости распространяется на весь код. Глобальные переменные и константы существуют в любом месте кода (после их инициализации). Локальная область видимости распространяется только на явно ограниченный фрагмент кода. Локальные переменные и константы существуют только в той части кода, в которой происходила их инициализация. 32 | 33 | + Лексемы локальных переменных начинаются с подчеркивания или строчной буквы (принято использовать только строчные буквы, разделяя слова знаком подчеркивания - змеиная_нотация). Использование несуществующей локальной переменной считается вызовом метода; 34 | 35 | + Лексемы глобальных переменных начинаются с знака доллара. Использование несуществующей глобальной переменной считается её объявлением; 36 | 37 | + Лексемы констант начинаются с прописной буквы (принято использовать только прописные буквы, разделяя слова знаком подчеркивания - НОТАЦИЯ_ГРЕМУЧЕЙ_ЗМЕИ). Использование несуществующей константы считается исключением (поиск констант включает области видимости верхнего уровня). 38 | 39 | ООП вводит две дополнительные области видимости: область видимости класса и область видимости экземпляра класса. Так же добавляется два вида переменных. 40 | 41 | + Лексема переменной экземпляра начинается с знака @ (принято использовать змеиную нотацию). Использование несуществующей переменной экземпляра считается её объявлением; 42 | 43 | + Лексема переменной класса начинается с @@ (принято использовать змеиную нотацию). Использование несуществующей переменной класса считается исключением. 44 | 45 | ###### Сбор мусора: 46 | 47 | В Ruby ресурсы, используемые программой, управляются интерпретатором. Это позволяет избегать наиболее распространенных проблем работы с памятью. В то же время интерпретатор распознает только заранее определенные ситуации, что иногда приводит к довольно неприятным результатам. Дополнительная работа также увеличивает время интерпретации и выполнения программ. Баланс между этими двумя полюсами - важная задача для разработчиков интерпретатора. 48 | 49 | Для автоматического управления памятью реализован механизм, называемый сбором мусора. Под мусором подразумеваются объекты, сохраненные в памяти, но при этом не использующиеся. Как только интерпретатор понимает, что объект не связан ни с одним идентификатором, он освобождает память, которую этот объект занимал (потому что доступ к этому объекту больше невозможен). Это позволяет удалять одноразовые объекты сразу после их использования, а также сохранять синтаксические структуры на всем протяжении процесса выполнения. 50 | -------------------------------------------------------------------------------- /book/integer.md: -------------------------------------------------------------------------------- 1 | ## Целые числа (Integer) 2 | 3 | Абстрактный класс для работы с целыми числами. Производные классы Fixnum и Bignum отличаются только внутренней реализацией. 4 | 5 | ### Приведение типов 6 | 7 | `.to_i # -> self` 8 | 9 | `.to_r # -> rational` 10 | Синонимы: `rationalize` 11 | 12 | Преобразование в рациональную дробь. 13 | `0.to_r # -> (0/1)` 14 | 15 | `.to_f # -> float [Fixnum и Bignum]` 16 | 17 | Преобразование в десятичную дробь. 18 | `1.to_f # -> 1.0` 19 | 20 | `.to_s( numeral_system = 10 ) # -> string [Fixnum и Bignum]` 21 | 22 | Преобразование в текст, используя указанную систему счисления (от 2 до 36). 23 | 24 | ~~~~~ ruby 25 | 16.to_s 16 # -> "10" 26 | 0xF.to_s 16 # -> "f" 27 | 0x16.to_s 16 # -> "16" 28 | ~~~~~ 29 | 30 | ### Операторы: Fixnum и Bignum 31 | 32 | `.*(integer) # -> result` Произведение. 33 | 34 | `./(integer) # -> result` Деление. 35 | 36 | `.**(integer) # -> result` Возведение в степень. 37 | 38 | `.+(integer) # -> result` Сумма. 39 | 40 | `.-(integer) # -> result` Разность. 41 | 42 | `.~(integer) # -> result` Побитовое отрицание. 43 | 44 | `.[](index) # -> 0 или 1` 45 | 46 | Используется для получения указанного бита из двоичного представления числа. 47 | 48 | `.<<(integer) # -> result` Побитовый сдвиг влево. 49 | 50 | `.>>(integer) # -> result` Побитовый сдвиг вправо. 51 | 52 | `.&(integer) # -> result` Побитовое И. 53 | 54 | `.|(integer) # -> result` Побитовое ИЛИ. 55 | 56 | `.^(integer) # -> result` Побитовое исключающее ИЛИ. 57 | 58 | ### Арифметические операции 59 | 60 | `.next # -> integer` 61 | Синонимы: `succ` 62 | 63 | Увеличение числа на единицу. 64 | `1.next # -> 2` 65 | 66 | `.pred # -> integer` 67 | 68 | Уменьшение числа на единицу. 69 | `1.pred # -> 0` 70 | 71 | `.gcd(integer) # -> gcd` 72 | 73 | Используется для вычисления наибольшего общего делителя двух целых чисел. Если одно из них равно нулю, то возвращается результат вызова метода `integer.abs` для другого. 74 | `2.gcd 3 # -> 1` 75 | 76 | `.lcm(integer) # -> lcm` 77 | 78 | Используется для вычисления наименьшего общего кратного двух целых чисел. Если одно из них равно нулю, то возвращается ноль. 79 | `2.lcm 3 # -> 6` 80 | 81 | `.gcdlcm(integer) # -> array` 82 | 83 | Используется для вычисления `[ self.gcd(integer), self.lcm(integer) ]` 84 | `2.gcdlcm 3 # -> [ 1, 6 ]` 85 | 86 | ### Предикаты 87 | 88 | `.even? # -> bool` 89 | 90 | Проверка относится ли число к четным. 91 | 92 | ~~~~~ ruby 93 | 0.even? # -> true 94 | 1.even? # -> false 95 | 2.even? # -> true 96 | ~~~~~ 97 | 98 | `.odd? # -> bool` 99 | 100 | Проверка относится ли число к нечетным. 101 | 102 | ~~~~~ ruby 103 | 0.odd? # -> false 104 | 1.odd? # -> true 105 | 2.odd? # -> false 106 | ~~~~~ 107 | 108 | ### Итераторы 109 | 110 | `.upto(limit) { |integer| } # -> self` 111 | 112 | Перебор чисел (включительно) с шагом +1. 113 | 114 | `.downto(limit) { |integer| } # -> self` 115 | 116 | Перебор чисел (включительно) с шагом -1. 117 | 118 | `.times { |integer| } # -> self` 119 | 120 | Перебор чисел из диапазона `0...self`. 121 | 122 | ### Остальное 123 | 124 | `.chr( encode = "binary") # -> string` 125 | 126 | Используется для получения символа с переданной кодовой позицией. Отсутствие символа считается исключением `RangeError`. 127 | `42.chr # -> "*"` 128 | 129 | `.hash # -> integer [Fixnum и Bignum]` 130 | 131 | Цифровой код объекта. 132 | `1.hash # -> -861462684` 133 | 134 | `.size # -> integer [Fixnum и Bignum]` 135 | 136 | Количество байтов, занимаемых числом. 137 | `1.size # -> 4` 138 | -------------------------------------------------------------------------------- /book/io.tex: -------------------------------------------------------------------------------- 1 | \chapter{Чтение и запись данных} 2 | 3 | \input{stream.tex} 4 | \input{file.tex} 5 | \input{dir.tex} 6 | \input{filestat.tex} 7 | -------------------------------------------------------------------------------- /book/library.md: -------------------------------------------------------------------------------- 1 | # Библиотеки кода 2 | 3 | Чтобы облегчить повторное использование кода, программу принято разделять на файлы, которые могут быть выделены в отдельные библиотеки. Библиотека - это группа файлов, содержащих набор модулей и классов (обычно каждый файл содержит определение одного модуля или класса). 4 | 5 | ## Использование 6 | 7 | Для использования библиотеки требуется явно объявить это интерпретатору. В свою очередь, интерпретатор автоматически находит и извлекает содержимое библиотеки. Обычно используемые библиотеки объявляются в начале программы. 8 | 9 | Поиск всех объявленных библиотек происходит в каталогах, хранящихся в глобальном массиве `$LOAD_PATH ($:)` (изменение значения элементов запрещено в Ruby 2.0; для объектов не относящихся к String вызывается метод `object.to_path`). Поиск файла выполняется, начиная с первого элемента (начиная с первого каталога). 10 | 11 | `.require(path) # -> bool` 12 | 13 | Используется для однократной загрузки библиотеки. Названия загруженных библиотек сохраняются в массиве `$LOAD_FEAUTURES ($”)` (изменение значения элементов запрещено в Ruby 2.0; для объектов не относящихся к String вызывается метод `object.to_path`). Каждая библиотека может быть загружена только один раз. Уровень безопасности объявляемой библиотеки должен быть равен 0. 14 | 15 | ~~~~~ note 16 | На самом деле любую библиотеку можно загружать произвольное число раз, если перед этим удалять её название из массива. 17 | ~~~~~ 18 | 19 | В названии файла библиотеки расширение обычно не указывается. По умолчанию обрабатывается расширение `.rb`. Если файла с таким расширением не найдено, то будет произведен поиск бинарного файла с тем же именем (например, с расширениями `.so` или `.dll`). 20 | 21 | `.require_relative(path) # -> bool` 22 | 23 | Версия предыдущего метода, использующаяся для поиска библиотек относительно базового каталога программы. 24 | 25 | `.load( path, anonym = false )` 26 | 27 | Используется для многократной загрузки библиотеки. В имени файла должно быть указано его расширение. 28 | 29 | Код библиотеки может быть выполнен в теле анонимного модуля. В этом случае она не будет влиять на глобальную область видимости основной программы. 30 | 31 | `.autoload( name, path ) # -> nil` 32 | 33 | Используется для автоматизации загрузки библиотек (отложенная загрузка). Поиск библиотеки выполняется только при вызове соответствующей константы. 34 | 35 | `.autoload?(name) # -> path` 36 | 37 | Используется для получения названия библиотеки, загружаемой при получении соответствующей константы. Если такая библиотека не объявлена, то возвращается nil. 38 | 39 | Для загрузки библиотек относительно констант вызываемых в теле определенного модуля существуют версии методов `module.autoload` и `module.autoload?`. 40 | 41 | ## Усовершенствование (Ruby 2.0) 42 | 43 | **Во второй версии Ruby** добавлен механизм, позволяющий усовершенствовать используемые библиотеки кода, с помощью создания улучшений. Улучшение - это синтаксическая конструкция, позволяющая переопределять существующее поведение. В отличии от обычного переопределения, улучшения воздействуют только на текущую область видимости. 44 | 45 | Улучшения считаются экспериментальной функцией и их применение для рабочих приложений не рекомендуется. 46 | 47 | Достоинства: 48 | 49 | + Применение изменений только в текущей области видимости. 50 | 51 | Недостатки: 52 | 53 | + Усложнение понимания кода. 54 | + Усложнение поиска методов. 55 | + Результат выполнения кода зависит от его местоположения. 56 | 57 | `.refine(a_class) { } # -> a_module [private Module]` 58 | 59 | Используется для улучшения переданного класса. Метод создает анонимный модуль, содержащий сделанные улучшения (self ссылается на этот модуль). Модули могут содержать сразу несколько улучшений. Метод существует только в теле модуля (но не класса). 60 | 61 | Улучшения действуют только на сущности, создаваемые после применения улучшения. 62 | 63 | ~~~~~ ruby 64 | # Старый способ 65 | class String 66 | def bang 67 | "#{self}" 68 | end 69 | end 70 | "Hello".bang # -> "Hello" 71 | ~~~~~ 72 | 73 | ~~~~~ ruby 74 | # Новый способ 75 | module StringBang 76 | "Hello".bang # -> NoMethodError! 77 | 78 | refine String do 79 | def bang; "#{self}"; end 80 | end 81 | 82 | "Hello".bang # -> "Hello!" 83 | end 84 | "Hello".bang # -> NoMethodError! 85 | ~~~~~ 86 | 87 | `.using(module) # -> main [MAIN]` 88 | 89 | Используется для применения улучшений из модуля. Улучшения могут применяться только для файла и в методах `Kernel.eval`, `Kernel.instance_eval` или `Kernel.module_eval`. 90 | 91 | + Улучшения действуют только на сущности, создаваемые после применения. При наличии улучшений класса, поиск методов начинается с улучшений (улучшения добавляются в начало очереди вызова и могут быть доступны с помощью super). 92 | 93 | ~~~~~ ruby 94 | module Foo 95 | def foo 96 | puts "C#foo in Foo" 97 | end 98 | end 99 | 100 | class C 101 | prepend Foo 102 | def foo 103 | puts "C#foo" 104 | end 105 | end 106 | 107 | class D < C 108 | def foo 109 | super 110 | end 111 | end 112 | ~~~~~ 113 | 114 | ~~~~~ ruby 115 | module M 116 | refine C do 117 | def foo 118 | puts "C#foo in M" 119 | end 120 | end 121 | end 122 | 123 | C.new.foo # -> 'C#foo in Foo' 124 | 125 | using M 126 | C.new.foo # -> "C#foo in M" 127 | D.new.foo # -> "C#foo in Foo" 128 | 129 | class E < C 130 | def foo 131 | super 132 | end 133 | end 134 | 135 | E.new.foo # -> "C#foo in M" 136 | ~~~~~ 137 | 138 | + Улучшения не действуют на методы, определяемые вне улучшаемого контекста. Улучшения могут не действовать во время вызова `Kernel.send`, `Kernel.method`, и `Kernel.respond_to?`. 139 | 140 | ~~~~~ ruby 141 | C = Class.new 142 | 143 | module M 144 | refine C do 145 | def foo 146 | puts "C#foo in M" 147 | end 148 | end 149 | end 150 | 151 | def call_foo(x) 152 | x.foo 153 | end 154 | 155 | using M 156 | 157 | x = C.new 158 | x.foo # -> "C#foo in M" 159 | x.send :foo # -> NoMethodError! 160 | x.respond_to? :foo # -> false 161 | call_foo(x) # -> NoMethodError! 162 | ~~~~~ 163 | 164 | + Улучшения действую на методы, которые были определены после применения улучшений, даже если метод вызывается вне действия улучшения. 165 | 166 | ~~~~~ ruby 167 | # c.rb: 168 | 169 | class C 170 | end 171 | ~~~~~ 172 | 173 | ~~~~~ ruby 174 | # m.rb: 175 | 176 | require "c" 177 | 178 | module M 179 | refine C do 180 | def foo 181 | puts "C#foo in M" 182 | end 183 | end 184 | end 185 | ~~~~~ 186 | 187 | ~~~~~ ruby 188 | # m_user.rb: 189 | 190 | require "m" 191 | 192 | using M 193 | 194 | class MUser 195 | def call_foo(x) 196 | x.foo 197 | end 198 | end 199 | ~~~~~ 200 | 201 | ~~~~~ ruby 202 | # main.rb: 203 | 204 | require "m_user" 205 | 206 | x = C.new 207 | m_user = MUser.new 208 | m_user.call_foo(x) # -> C#foo in M 209 | x.foo # -> NoMethodError! 210 | ~~~~~ 211 | 212 | + Улучшения не действуют, если метод `.using` не вызывался. 213 | 214 | ~~~~~ ruby 215 | # В файле: 216 | 217 | # not activated here 218 | using M 219 | # activated here 220 | class Foo 221 | # activated here 222 | def foo 223 | # activated here 224 | end 225 | # activated here 226 | end 227 | # activated here 228 | ~~~~~ 229 | 230 | ~~~~~ ruby 231 | # В eval: 232 | 233 | # not activated here 234 | eval < float` Арккосинус. 16 | 17 | `.acosh(number) # -> float` Гиперболический косинус. 18 | 19 | `.asin(number) # -> float` Арксинус. 20 | 21 | `.asinh(number) # -> float` Гиперболический синус. 22 | 23 | `.atan(number) # -> float` Арктангенс. 24 | 25 | `.atan2( first_number, second_number ) # -> float` Арктангенс. 26 | 27 | `.atanh(number) # -> float` Гиперболический тангенс. 28 | 29 | `.cbrt(number) # -> float` Кубический корень. 30 | 31 | `.cos(number) # -> float` Косинус (в радианах). 32 | 33 | `.cosh(number) # -> float` Гиперболический косинус (в радианах). 34 | 35 | `.erf(number) # -> float` Функция ошибки. 36 | 37 | `.erfc(number) # -> float` Дополнительная функция ошибки. 38 | 39 | `.exp(number) # -> float` Возведение e в степень. 40 | 41 | `.frexp(number) # -> array` 42 | 43 | Индексный массив вида `[ float, integer]`, 44 | где `float * 2**integer == number`. 45 | 46 | `.gamma(number) # -> float` Гамма функция из числа. 47 | 48 | `.hypot( first_number, second_number ) # -> float` Длина гипотенузы. 49 | 50 | `.ldexp( float, integer ) # -> float` 51 | 52 | Аналогично выполнению `float * 2**integer`. 53 | 54 | `.lgamma(number) # -> array` 55 | 56 | Индексный массив вида 57 | `[ Math.log( Math.gamma(number).abs), Math.gamma(number) < 0 ? -1: 1 ]`. 58 | 59 | `.log( number, base = Math::E ) # -> float` Логарифм 60 | 61 | `.log10(number) # -> float` Десятичный логарифм. 62 | 63 | `.log2(number) # -> float` Логарифм по основанию 2. 64 | 65 | `.sin(number) # -> float` Синус (в радианах). 66 | 67 | `.sinh(number) # -> float` Гиперболический синус (в радианах). 68 | 69 | `.sqrt(number) # -> float` Квадратный корень. 70 | 71 | `.tan(number) # -> float` Тангенс (в радианах). 72 | 73 | `.tanh(number) # -> float` Гиперболический тангенс (в радианах). -------------------------------------------------------------------------------- /book/number.tex: -------------------------------------------------------------------------------- 1 | \chapter{Числа} 2 | $$ 3 | \xymatrix{ 4 | Numeric \: (+ \: Comparable) \ar[d]\ar[dr]\ar[drr]\ar[drrr] &&& \\ 5 | Complex & Rational & Float & Integer \ar[d]\ar[dr] & \\ 6 | &&& Fixnum & Bignum } 7 | $$ 8 | 9 | Для математических расчетов в Ruby определен модуль Math. 10 | 11 | \input{numeric} 12 | \input{integer} 13 | \input{float} 14 | \input{rational} 15 | \input{complex} 16 | \input{math} 17 | -------------------------------------------------------------------------------- /book/numeric.md: -------------------------------------------------------------------------------- 1 | ## Numeric 2 | 3 | **Добавленные модули: Comparable** 4 | 5 | Абстрактный класс для работы с числами. 6 | 7 | Если в результате выполнения какого-либо выражения интерпретатор возвращает число, то оно автоматически переводится в десятичную систему счисления. 8 | 9 | ### Приведение типов 10 | 11 | #### Неявное приведение 12 | 13 | Подклассы чисел за внешней схожестью имеют различную внутреннюю реализацию. Поэтому перед вызовом метода, интерпретатор приводит переданные аргументы к одному классу. Делается это в соответствии с приведенным ниже списком: 14 | 15 | 1. Если одно из чисел - комплексное, то и другие числа будут преобразованы в комплексные; 16 | 17 | 2. Если одно из чисел - десятичная дробь, то и другие числа будут преобразованы в десятичные дроби; 18 | 19 | 3. Если одно из чисел - рациональная дробь, то и другие числа будут преобразованы в рациональные дроби. 20 | 21 | Результат будет экземпляром того же класса, к которому приводятся аргументы. 22 | 23 | #### Явное приведение 24 | 25 | `.coerce(number) # -> array` 26 | 27 | Используется для преобразования двух чисел к одному типу. 28 | 29 | 1. Если числа принадлежат к разным классам, то они преобразуются в десятичные дроби с помощью метода `.Float`; 30 | 31 | 2. Текст преобразуется, если он содержит только цифры (поддерживаются двоичная и шестнадцатеричная системы счисления). 32 | 33 | ~~~~~ ruby 34 | 1.coerce 2.1 # -> [2.1, 1.0] 35 | 1.coerce "2.1" # -> [2.1, 1.0] 36 | 1.coerce "0xAF" # -> [175.0, 1.0] 37 | 1.coerce "q123" # -> error! 38 | ~~~~~ 39 | 40 | `.i # -> complex` 41 | 42 | Преобразование числа в комплексное. Метод удален из класса Complex. 43 | `1.i # -> (0+1i)` 44 | 45 | `.to_c # -> complex` 46 | 47 | Преобразование числа в комплексное. 48 | `1.to_c # -> (1+0i)` 49 | 50 | `.to_int # -> integer` 51 | 52 | Преобразование числа в целое с помощью метода `number.to_i`. 53 | `2.1.to_int # -> 2` 54 | 55 | ### Операторы 56 | 57 | `.%(number)` 58 | Синонимы: `modulo` 59 | 60 | Используется для вычисления остатка от деления. 61 | 62 | `.+(number)` Унарный плюс. 63 | 64 | `.-(number)` Унарный минус. 65 | 66 | `.<=>(number)` Сравнение. 67 | 68 | ### Округление 69 | 70 | `.ceil # -> integer` 71 | 72 | Используется для нахождения наименьшего целого числа, которое будет больше или равно текущего (округление в большую сторону). 73 | `2.1.ceil # -> 3` 74 | 75 | `.floor # -> integer` 76 | 77 | Используется для нахождения наибольшего целого числа, которое будет больше или равно текущего (округление в меньшую сторону). 78 | `2.1.floor # -> 2` 79 | 80 | `.round( precise = 0 ) # -> number` 81 | 82 | Используется для округления с заданной точностью. Точность определяет разряд, до которого будет выполнено округление. 83 | 84 | ~~~~~ ruby 85 | 2.11355.round 4 # -> 2.1136 86 | 2.round 4 # -> 2.0 87 | ~~~~~ 88 | 89 | `.truncate # -> integer` 90 | 91 | Целая часть числа. 92 | `2.1.truncate # -> 2` 93 | 94 | ### Математические функции 95 | 96 | `.abs2 # -> number` 97 | 98 | Квадрат числа. 99 | `-2.1.abs2 # -> 4.41` 100 | 101 | `.numerator # -> integer` 102 | 103 | Числитель рациональной дроби, полученной с помощью метода `number.to_r`. 104 | `2.1.numerator # -> 4728779608739021` 105 | 106 | `.denominator # -> integer` 107 | 108 | Знаменатель рациональной дроби, полученной с помощью метода `number.to_r`. 109 | `2.1.denominator # -> 2251799813685248` 110 | 111 | `.divmod(number) # -> array` 112 | 113 | Частное и остаток от деления. 114 | `1.divmod 3 # -> [0, 1]` 115 | 116 | `.div(number) # -> integer` 117 | 118 | Округленное частное (округление выполняется с помощью метода `number.to_i`). 119 | `1.div 3 # -> 0` 120 | 121 | `.fdiv(number) # -> float` 122 | 123 | Частное в виде десятичной дроби. 124 | `1.fdiv 3 # -> 0.3333333333333333` 125 | 126 | `.quo(number) # -> quotient` 127 | 128 | Частное двух чисел. Для двух целых чисел результатом будет рациональная дробь. 129 | `1.quo 3 # -> (1/3)` 130 | 131 | `.remainder(number) # -> integer` 132 | 133 | Остаток от деления, вычисляемый как 134 | `self – number * ( self / number ).truncate`. 135 | `1.remainder 3 # -> 1` 136 | 137 | `.abs # -> number` 138 | 139 | Модуль числа. 140 | `-2.1.abs # -> 2.1` 141 | 142 | `.arg # -> number` 143 | Синонимы: `angle, phase` 144 | 145 | Угловое значение для полярной системы координат. 146 | 147 | Для действительных чисел возвращает ноль, если число не отрицательно. В другом случае возвращается ссылка на константу `Math::PI`. 148 | 149 | ~~~~~ ruby 150 | 1.arg # -> 0 151 | -1.arg # -> 3.141592653589793 152 | ~~~~~ 153 | 154 | `.polar # -> array` 155 | 156 | Число в полярной системе координат (`[ self.abs, self.arg ]`). 157 | `1.polar # -> [1, 0]` 158 | 159 | `.real # -> number` 160 | 161 | Вещественная часть числа. 162 | `1.real # -> 1` 163 | 164 | `.imag # -> 0` 165 | Синонимы: `imaginary` 166 | 167 | Мнимая часть числа. 168 | 169 | `.rect # -> array` 170 | 171 | Число в прямоугольной системе координат (`[ self, 0 ]`). 172 | `1.rect # -> [ 1, 0 ]` 173 | 174 | `.conj # -> self` 175 | Синонимы: `conjugate` 176 | 177 | Сопряженное число (используется для комплексных чисел). 178 | 179 | ### Предикаты 180 | 181 | `.integer? # -> bool` 182 | 183 | Проверка относится ли число к целым. 184 | 185 | ~~~~~ ruby 186 | 1.integer? # -> true 187 | 2.1.integer? # -> false 188 | ~~~~~ 189 | 190 | `.real? # -> bool` 191 | 192 | Проверка относится ли число к действительным (отрицательный результат возвращается только для комплексных чисел). 193 | `1.real? # -> true` 194 | 195 | `.nonzero? # -> bool` 196 | 197 | Сравнение с нулем. Возвращает число, если оно не равно нулю. 198 | 199 | ~~~~~ ruby 200 | 1.nonzero? # -> 1 201 | 0.0.nonzero? # -> nil 202 | ~~~~~ 203 | 204 | `.zero? # -> bool` 205 | 206 | Сравнение с нулем. 207 | 208 | ~~~~~ ruby 209 | 1.zero? # -> false 210 | 0.0.zero? # -> true 211 | ~~~~~ 212 | 213 | ### Итераторы 214 | 215 | `.step( limit, step = 1) { |number| } # -> self` 216 | 217 | Перебор чисел. 218 | 219 | Если одно из чисел не относится к целым, то все числа преобразуются в десятичные дроби. При этом число итераций соответствует 220 | `n + n * Flt::EPSILON`, где `n == limit – self / step`. 221 | 222 | ### Остальное 223 | 224 | `.singleton_method_added(*object)` 225 | 226 | Попытка определить собственный метод числа считается исключением. -------------------------------------------------------------------------------- /book/random.md: -------------------------------------------------------------------------------- 1 | # Псевдослучайные числа (Random) 2 | 3 | Для генерации псевдослучайных чисел в Ruby используется алгоритм "Вихрь Мерсена", предложенный в 1997 году Мацумото и Нисимурой. Его достоинствами являются колоссальный период `(2 ** 19937 - 1)`, равномерное распределение в 623 измерениях, быстрая генерация случайных чисел (в 2-3 раза быстрее, чем стандартные генераторы). Однако, существуют алгоритмы, распознающие последовательность, порождаемую "Вихрем Мерсенна", как неслучайную. 4 | 5 | `::new( seed = Random.new_seed ) # -> random` 6 | 7 | Используется для создания генератора. Объект, переданный методу, необходим для исключения повторяющихся чисел. Его также называют "соль". 8 | `Random.new # -> #` 9 | 10 | `::rand( number = 0 ) # -> random_number` 11 | 12 | Используется для получения случайного числа. 13 | 14 | Проверяется результат `number.to_i.abs`: 15 | 16 | + когда он равен нулю или ссылается на nil, то возвращается псевдослучайная десятичная дробь в диапазоне `0.0...1.0`. 17 | + в другом случае возвращается псевдослучайное число в диапазоне 18 | `0...number.to_i.abs`. 19 | 20 | `Random.rand # -> 0.8736231696463861` 21 | 22 | `.rand( number = 0 ) # -> random_number [PRIVATE: Kernel]` 23 | 24 | Версия предыдущего метода из модуля Kernel. 25 | 26 | `::new_seed # -> integer` 27 | 28 | Используется для вычисления новой "соли". 29 | `Random.new_seed # -> 69960780063826734370396971659065074316` 30 | 31 | `::srand( number = 0 ) # -> number` 32 | 33 | Используется для вычисления новой "соли". Когда аргумент равен нулю, то используется время вызова, идентификатор процесса и порядковый номер вызова. С помощью аргумента программа может быть детерминирована во время тестирования. Возвращается предыдущее значение. 34 | 35 | `.srand( number = 0 ) # -> number [PRIVATE: Kernel]` 36 | 37 | Версия предыдущего метода из модуля Kernel. 38 | 39 | ## Генераторы 40 | 41 | `.bytes(bytesize) # -> string` 42 | 43 | Используется для получения случайного двоичного текста. 44 | `Random.new.bytes 2 -> "\xA1W"` 45 | 46 | `.rand( object = nil ) # -> number` 47 | 48 | + Когда передано целое число, возвращается псевдослучайное число в диапазоне `0...object`; 49 | 50 | + Передача отрицательного числа или нуля считается исключением; 51 | 52 | + Когда передана десятичная дробь, возвращается псевдослучайная десятичная дробь в диапазоне `0.0...object`; 53 | 54 | + Когда передан диапазон, возвращается случайный элемент диапазона. Для начальной и конечной границ должны быть определены операторы `-` (разность) и `+` (сумма); 55 | 56 | + Остальные случаи считаются исключением. 57 | 58 | `.seed # -> integer` 59 | 60 | Используется для получения новой "соли". 61 | `Random.new.seed # -> 173038287409845379387953855893202182131` -------------------------------------------------------------------------------- /book/range.md: -------------------------------------------------------------------------------- 1 | ## Range (диапазоны) 2 | 3 | Диапазоны необходимо ограничивать круглыми скобками. В противном случае метод будет вызван только для конечной границы. 4 | 5 | `::new( first, last, include_last = false ) # -> range` 6 | 7 | Используется для создания диапазона с переданными границами. Логическая величина влияет на обработку конечной границы. 8 | `Range.new 1, 5, 0 # -> 1...5` 9 | 10 | ### Приведение типов 11 | 12 | `.inspect # -> string` 13 | 14 | Преобразование диапазона в текст, с помощью вызова метода `.inspect` для каждой границы. 15 | `(1..3).inspect # -> "1..3"` 16 | 17 | `.to_s # -> string` 18 | Преобразование диапазон в текст. 19 | `(1..3).to_s # -> "1..3"` 20 | 21 | ### Элементы 22 | 23 | `.begin # -> object` 24 | 25 | Первый элемент диапазона. 26 | `(1..3).begin # -> 1` 27 | 28 | `.end # -> object` 29 | 30 | Последний элемент диапазона. 31 | `(1..3).end # -> 3` 32 | 33 | `.last( size = nil ) # -> array` 34 | 35 | Последний элемент или последний фрагмент. 36 | `(1..3).last 2 # -> [ 2, 3 ]` 37 | 38 | ### Операторы 39 | 40 | `.===(object)` 41 | Синонимы: `cover?, member?, include?` 42 | 43 | Проверяка входит ли объект в диапазон. 44 | `(1..3) === 2 # -> true` 45 | 46 | ### Итераторы 47 | 48 | `.each { |object| } # -> self` Перебор элементов с помощью метода `.succ`. 49 | 50 | `.step( step = 1 ) { |object| } # -> self` 51 | 52 | 53 | Перебор элементов с заданным шагом, либо прибавляя его после каждой итерации, либо используя метод `.succ`. 54 | 55 | ### Остальное 56 | 57 | `.exclude_end? # -> bool` 58 | 59 | Проверка входит ли конечная граница в диапазон. 60 | `(1..3).exclude_end? # -> false` 61 | 62 | `.bsearch { |x| } # -> elem [Ruby 2.0]` 63 | 64 | Реализация двоичного поиска (метода деления пополам, дихотомии). Используется для нахождения элемента, который отвечает заданному условию за O(log n), где n - это размер диапазона. Алгоритм выполняет поиск элемента, используя дробление диапазона на половины. 65 | 66 | Метод реализован как в классическом варианте, так и для использования бисекции. 67 | 68 | + Поиск элемента 69 | 70 | Блок должен возвращать логическую величину для каждого элемента. Диапазон должен содержать значение x, так что: 71 | 72 | + Блок возвращает false для любого элемента меньше чем x. 73 | + Блок возвращает true для любого элемента, больше или равного x. 74 | 75 | В результате возвращается x или nil. 76 | 77 | ~~~~~ ruby 78 | ary = [0, 4, 7, 10, 12] 79 | (0...ary.size).bsearch { |i| ary[i] >= 4 } # -> 1 80 | (0...ary.size).bsearch { |i| ary[i] >= 6 } # -> 2 81 | (0...ary.size).bsearch { |i| ary[i] >= 8 } # -> 3 82 | (0...ary.size).bsearch { |i| ary[i] >= 100 } # -> nil 83 | 84 | (0.0...Float::INFINITY).bsearch { |x| Math.log(x) >= 0 } # -> 1.0 85 | ~~~~~ 86 | 87 | + Метод бисекции (метод деления отрезка пополам) 88 | 89 | Простейший численный метод для решения нелинейных уравнений вида `F(x) = 0`. 90 | 91 | Блок должен возвращать число для каждого элемента. Диапазон должен содержать элементы x и y (`x <= y`), так что: 92 | 93 | + Блок возвращает положительное число для элементов меньше чем x. 94 | + Блок возвращает ноль для элементов из диапазона `x...v`. 95 | + Блок возвращает отрицательное число для элементов больше иди равным y. 96 | 97 | В результате возвращается любой из элементов из диапазона `x...y`. Если нет элементов, отвечающих условию, возвращается nil. 98 | 99 | ~~~~~ ruby 100 | ary = [0, 100, 100, 100, 200] 101 | (0..4).bsearch { |i| 100 - ary[i] } # -> 1, 2 или 3 102 | (0..4).bsearch { |i| 300 - ary[i] } # -> nil 103 | (0..4).bsearch { |i| 50 - ary[i] } # -> nil 104 | ~~~~~ 105 | 106 | `.hash # -> integer` 107 | 108 | Цифровой код объекта. 109 | `(1..3).hash # -> -337569967` 110 | -------------------------------------------------------------------------------- /book/rational.md: -------------------------------------------------------------------------------- 1 | ## Рациональные дроби (Rational) 2 | 3 | Рациональная дробь - это рациональное число, вида `(a/b)`, где число a называют числителем, а число b - знаменателем. Косая черта обозначает деление двух чисел. Рациональные дроби используются чтобы избежать ошибок приближения при работе с десятичными дробями. 4 | 5 | `.Rational( nom, denom = 1 ) # -> rational [Kernel]` 6 | 7 | Используется для создания рациональных дробей вида `(nom/denom)`. 8 | 9 | ~~~~~ ruby 10 | Rational 2, 3 # -> (2/3) 11 | Rational "2/3" # -> (2/3) 12 | Rational 8, 3 # -> (8/3) 13 | Rational 2.1, 3 # -> (4728779608739021/6755399441055744) 14 | ~~~~~ 15 | 16 | ### Приведение типов 17 | 18 | `.to_r # -> rational` 19 | 20 | `.inspect # -> string` 21 | 22 | Преобразование в текст. 23 | `Rational( 2, 3 ).inspect # -> "(2/3)"` 24 | 25 | `.to_s # -> string` 26 | 27 | Преобразование тела рациональной дроби в текст. 28 | `Rational( 2, 3 ).to_s # -> "2/3"` 29 | 30 | `.to_f # -> float` 31 | 32 | Преобразование рациональной дроби в десятичную. 33 | `Rational( 2, 3 ).to_f # -> 0.6666666666666666` 34 | 35 | `.to_i # -> integer` 36 | 37 | Используется для получения целой части числа. 38 | `Rational( 2, 3 ).to_i # -> 0` 39 | 40 | ### Операторы 41 | 42 | `.*(number) # -> result` Произведение. 43 | 44 | `.**(number) # -> result` Возведение в степень. 45 | 46 | `.+(number) # -> result` Сумма. 47 | 48 | `.-(number) # -> result` Разность. 49 | 50 | `./(number) # -> result` 51 | Синонимы: `quo` 52 | 53 | Деление. 54 | 55 | ### Остальное 56 | 57 | `.rationalize( number = Flt::EPSILON ) # -> rational` 58 | 59 | Преобразование рациональной дроби, так что 60 | `self – number.abs <= rational && rational <= self + number.abs` 61 | -------------------------------------------------------------------------------- /book/regexp.md: -------------------------------------------------------------------------------- 1 | ## Регулярные выражения 2 | 3 | ### Regexp 4 | 5 | ##### Константы 6 | 7 | `Regexp::IGNORECASE` - регистр символов игнорируется (модификатор i); 8 | 9 | `Regexp::EXTENDED` - пробельные символы и комментарии игнорируются (модификатор x); 10 | 11 | `Regexp::MULTILINE` - многострочный режим (модификатор m); 12 | 13 | `Regexp::FIXEDENCODING` - другая кодировка. 14 | 15 | ***** 16 | 17 | `::new( template, object = nil ) # -> regexp` 18 | Синонимы: `compile` 19 | 20 | Используется для создания нового регулярного выражения. Вторым аргументом передаются константы класса или произвольные объекты: 21 | 22 | + когда значение аргумента истинно, регистр символов будет игнорироваться; 23 | 24 | + когда передаются символы `?n` или `?N`, в теле регулярного выражения используется ASCII кодировка. 25 | 26 | `Regexp.new "abc", 2 # -> /abc/x` 27 | 28 | `::union( *template или array = nil ) # -> regexp` 29 | 30 | Используется для объединения нескольких регулярных выражений (объединение множеств). Без аргументов возвращается `/!?/`. 31 | `Regexp.union [ ?0, ?1, ?2 ] # -> /0|1|2/` 32 | 33 | #### Преобразование типов 34 | 35 | `::try_convert(object) # -> regexp` 36 | 37 | Преобразование в регулярное выражение с помощью метода `.to_regexp`. Если метод для объекта не определен, то возвращается nil. 38 | `Regexp.try_convert "abc" # -> nil` 39 | 40 | `.to_s # -> string` 41 | 42 | Текст, содержащий тело регулярного выражения и его модификаторы. 43 | `/(a-z)/i.to_s # -> "(?i-mx:(a-z))"` 44 | 45 | `.inspect # -> string` 46 | 47 | Текст, содержащий регулярное выражение. 48 | `/(a-z)/i.inspect # -> "/(a-z)/i"` 49 | 50 | `.source # -> string` 51 | 52 | Текст, содержащий тело регулярного выражения c экранированными спецсимволами. 53 | `/(a-z)/i.source # -> "(a-z)"` 54 | 55 | #### Операторы 56 | 57 | `.===(string) # -> bool` Поиск совпадений. 58 | 59 | `.=~(string) # -> integer` Поиск совпадений. 60 | 61 | `.~(regexp) # -> integer` 62 | 63 | Поиск совпадений с последней прочитанной строкой (`$_`). 64 | 65 | #### Поиск совпадений 66 | 67 | `::last_match # -> match` 68 | 69 | `(group) # -> string` 70 | 71 | Информация о последнем поиске совпадений. Если совпадений не найдено, то возвращается nil. 72 | 73 | `.match( text, start = 0 ) # -> match` 74 | 75 | `( text, start = 0 ) { |match| } # -> object` 76 | 77 | Используется для сохранения информации о поиске совпадений. Если совпадений не найдено, то возвращается nil. 78 | 79 | #### Кодировка символов 80 | 81 | `.encoding # -> encoding` 82 | 83 | Используемая кодировка. 84 | `/(a-z)/i.encoding # -> #` 85 | 86 | `.fixed_encoding? # -> bool` 87 | 88 | Проверка используется ли любая кодировка, кроме ASCII. 89 | `/(a-z)/i.fixed_encoding? # -> false` 90 | 91 | #### Остальное 92 | 93 | `.casefold? # -> bool` 94 | 95 | Проверка игнорирования регистра символов (модификатор i). 96 | `/(a-z)/i.casefold? # -> true` 97 | 98 | `.named_captures # -> hash` 99 | 100 | Массив идентификаторов групп, ассоциируемых с их позициями. 101 | `/(?a-z)/i.named_captures # -> { "group" => [1] }` 102 | 103 | `.names # -> array` 104 | 105 | Массив идентификаторов групп. 106 | `/(?a-z)/i.names # -> ["group"]` 107 | 108 | `.options # -> integer` 109 | 110 | Сумма чисел используемых модификаторов. 111 | `/(a-z)/i.options # -> 1` 112 | 113 | `.hash # -> integer` 114 | 115 | Цифровой код объекта. 116 | `/(a-z)/i.hash # -> -145911848` 117 | 118 | `::escape(text) # -> string` 119 | Синонимы: `quote` 120 | 121 | Используется для экранирования спецсимволов. 122 | 123 | При этом `Regexp.new( Regexp.escape string ) =~ string # -> 0` 124 | `Regexp.escape "'\*?{}.'" # -> "'\\*\\?\\{\\}\\.'"` 125 | 126 | ### MatchData 127 | 128 | Экземпляры класса содержат полную информацию о найденных совпадениях. 129 | 130 | #### Преобразование типов 131 | 132 | `.to_s # -> string` 133 | 134 | Полный текст найденного совпадения. 135 | 136 | `.inspect # -> string` 137 | 138 | Текст, содержащий информацию об объекте. 139 | 140 | `.to_a # -> array` 141 | 142 | Массив найденных совпадений. 143 | 144 | #### Элементы 145 | 146 | `.[index] # -> string` 147 | 148 | Используется для получения совпадения с группой (полный текст совпадения - элемент с индексом 0). 149 | 150 | `.[first, last] # -> array` 151 | 152 | Используется для получения массива фрагментов, совпадающих с переданными группами. Когда границы диапазона отрицательны, отсчет групп ведется справа налево. 153 | 154 | `.[range] # -> array` 155 | 156 | Используется для получения массива фрагментов, совпадающих с переданными группами. Когда границы диапазона отрицательны, отсчет групп ведется справа налево. 157 | 158 | `.[name] # -> string` 159 | 160 | Используется для получения фрагмента, совпадающего с группой. 161 | 162 | `.captures # -> array` 163 | 164 | Используется для получения массива фрагментов, совпадающих с нумерованными группами. 165 | 166 | `.offset(group) # -> array` 167 | 168 | Используется для получения массива индексов символов, с которых началось и которыми закончилось совпадение фрагмента с группой. 169 | 170 | `.begin(group) # -> integer` 171 | 172 | Используется для получения индекса символа, с которого началось совпадение фрагмента с группой. 173 | 174 | `.end(group) # -> integer` 175 | 176 | Используется для получения индекса символа, которым заканчивается совпадение фрагмента с группой. 177 | 178 | `.pre_match # -> string` 179 | 180 | Фрагмент текста перед найденным совпадением. 181 | 182 | `.post_match # -> string` 183 | 184 | Фрагмент текста после найденного совпадения. 185 | 186 | #### Остальное 187 | 188 | `.regexp # -> regexp` 189 | 190 | Регулярное выражение, с которым происходило сравнение. 191 | 192 | `.string # -> string` 193 | 194 | Неизменяемая копия текста, в котором выполнялся поиск совпадений. 195 | 196 | `.size # -> integer` 197 | Синонимы: `length` 198 | 199 | Количество всех элементов поиска (включая полный текст совпадения). 200 | 201 | `.names # -> array` 202 | 203 | Массив, содержащий идентификаторы групп регулярного выражения. 204 | 205 | `.hash # -> integer` 206 | 207 | Цифровой код объекта. 208 | -------------------------------------------------------------------------------- /book/security.md: -------------------------------------------------------------------------------- 1 | # Безопасность 2 | 3 | Реализация собственной системы безопасности - одна из спорных и неоднозначных особенностей в Ruby. 4 | 5 | Безопасность кода в Ruby обеспечивается с помощью применения различных модификаторов, запрещающих изменение значения объекта или маркирующих небезопасные данные. 6 | 7 | Интерпретатор автоматически считает небезопасными: 8 | 9 | + аргументы, переданные при запуске программы (элементы массива ARGV); 10 | + переменные окружения (элементы массива ENV); 11 | + любые данные, извлекаемые из файлов, сокетов или потоков; 12 | + объекты, создаваемые на основе небезопасных данных. 13 | 14 | `$SAFE` ссылается на значение текущего уровня безопасности. Переменная локальна для каждого отдельного блока кода или процесса. Уровень безопасности основного процесса объявляется при запуске программы с помощью ключа `-T` (по умолчанию - 0). 15 | 16 | Нарушение ограничений безопасности считается исключением `SecurityError`. 17 | 18 | ## Уровни безопасности 19 | 20 | Более высокие уровни безопасности наследуют ограничения более низких. 21 | 22 | ### Уровень 0 23 | 24 | Не предполагает ограничений. 25 | 26 | ### Уровень 1 27 | 28 | Запрещается: 29 | 30 | + загружать библиотеки, если их название небезопасно; 31 | + выполнять произвольный код, если текст кода небезопасен; 32 | + открывать файлы, если их название небезопасно; 33 | + соединяться с хостом, если его название небезопасно; 34 | + запускать программу с ключами `-e, -i, -l, -r, -s, -S, -X`; 35 | + выполнять методы из классов Dir, IO, File, FileTest, передавая им небезопасные аргументы; 36 | + выполнять методы `test`, `eval`, `require`, `load`, `trap`, передавая им небезопасные аргументы. 37 | 38 | Также игнорируются переменные окружения RUBYLIB и RUBYOPT и текущий каталог при поиске подключаемых библиотек. 39 | 40 | ### Уровень 2 41 | 42 | Запрещается выполнять методы 43 | 44 | + `fork` 45 | + `syscall` 46 | + `exit!` 47 | + `Process.equid=` 48 | + `Process.fork` 49 | + `Process.setpgid` 50 | + `Process.setsid` 51 | + `Process.kill` 52 | + `Process.seeprioprity` 53 | 54 | передавая им небезопасные аргументы. 55 | 56 | ### Уровень 3 57 | 58 | Все объекты, кроме предопределенных считаются небезопасными. Вызов метода `.untaint` запрещается. 59 | 60 | ### Уровень 4 61 | 62 | Запрещается: 63 | 64 | + изменять значение безопасных объектов; 65 | + загружать библиотеки с помощью `require` или `load` (разрешается в теле анонимного модуля); 66 | + использовать метапрограммирование; 67 | + работать с любыми процессами кроме текущего; 68 | + завершать выполнение процесса; 69 | + читать или записывать данные; 70 | + изменять переменные окружения; 71 | + вызывать методы `.srand` и `Random.srand. 72 | 73 | Разрешается вызывать метод `.eval`, передавая ему небезопасные аргументы. 74 | 75 | ## Модификаторы 76 | 77 | Модификаторы в данном случае объявляются с помощью методов. 78 | 79 | `.freeze # -> self` 80 | 81 | Запрещает изменять значение объекта. 82 | 83 | `.frozen? # -> bool` 84 | 85 | Проверка запрещено ли изменять значение объекта. 86 | 87 | `.taint # -> self` 88 | 89 | Используется для маркировки небезопасных данных. Этим модификатором отмечаются полученные внешние данные. 90 | 91 | `.untaint # -> self` 92 | 93 | Используется для маркировки безопасных данных. 94 | 95 | `.tainted? # -> bool` 96 | 97 | Проверка безопасно ли использование объекта. 98 | 99 | `.untrust # -> self` 100 | 101 | Используется для маркировки данных, которым разработчик не доверяет. Этим модификатором отмечаются данные, полученные при выполнении кода с уровнем безопасности 4. 102 | 103 | `.trust # -> self` 104 | 105 | Используется для маркировки данных, которым разработчик доверяет. 106 | 107 | `.untrusted? # -> bool` 108 | 109 | Проверка доверяет ли разработчик объекту. -------------------------------------------------------------------------------- /book/subroutine.md: -------------------------------------------------------------------------------- 1 | # Подпрограммы 2 | 3 | Подпрограмма - это именованный фрагмент кода, содержащий описание определенного набора действий. К подпрограммам относятся замыкания (процедуры и функции), методы и сопрограммы. 4 | 5 | ## Замыкания (Proc) 6 | 7 | Замыкание (англ. closure) в программировании - это процедура или функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции и не в качестве её параметров (а в окружающем коде). Эти переменные продолжают существовать во время выполнения функции, даже если во внешнем коде их уже не существует. 8 | 9 | Замыкания создаются заново каждый раз в момент выполнения. 10 | 11 | Замыкания, так же как и объекты служат для инкапсуляции функциональности и данных. 12 | 13 | Замыкания могут быть переданы методам как обычные блоки. Для этого перед аргументом используется амперсанд. 14 | 15 | Псевдопеременная self сохраняет значение, сущестовавшее в момент создания замыкания. 16 | 17 | ~~~~ ruby 18 | class FirstKlass 19 | def self.first; 1; end 20 | 21 | def first; 2; end 22 | 23 | @@first = proc { first } 24 | 25 | def klass; @@first.call; end 26 | 27 | def instance; instance_exec &@@first; end 28 | end 29 | 30 | FirstKlass.new.klass # -> 1 31 | FirstKlass.new.instance # -> 2 32 | ~~~~~ 33 | 34 | Замыкания разделяются на процедуры (ведущие себя как блоки, но в действительности также относящиеся к функциям) и лямбда-функции (ведущие себя как методы). 35 | 36 | ### Процедуры 37 | 38 | Инструкция return в теле процедуры приводит к завершению выполнения метода, в теле которого объект был создан. Если выполнение метода уже завершено, то вызывается исключение `LocalJumpError`. 39 | 40 | Процедуры принимают аргументы также как и обычные блоки. 41 | 42 | `::new { |*params| } # -> proc` 43 | 44 | Используется для создания нового замыкания. 45 | 46 | ~~~~~ ruby 47 | def proc_from 48 | Proc.new 49 | end 50 | 51 | proc = proc_from { "hello" } 52 | proc.call # -> "hello" 53 | ~~~~~ 54 | 55 | `.proc { |*params| } # -> proc [PRIVATE: Kernel]` 56 | 57 | Версия предыдущего метода из модуля Kernel. 58 | 59 | ~~~~~ ruby 60 | def foo 61 | f = Proc.new { return "return from foo from inside proc" } 62 | f.call # после вызова функции замыкания f осуществляется выход из foo 63 | # результатом работы функции foo является результат работы f замыкания 64 | return "return from foo" 65 | end 66 | 67 | puts foo # печатает "return from foo from inside proc" 68 | ~~~~~ 69 | 70 | ### Лямбда-функции 71 | 72 | Инструкция return в теле лямбда-функций приводит к завершению выполнения функции. 73 | 74 | Лямбда-функции принимают аргументы также как и обычные методы. 75 | 76 | Для создания лямбда функций существует специальный синтаксис. Круглые скобки не обязательны. Параметры могут иметь значения по умолчанию. 77 | 78 | `->(*params) { } # -> lambda` 79 | 80 | `.lambda { |*params| } # -> lambda` 81 | 82 | Используется для создания объекта. 83 | 84 | ~~~~~ ruby 85 | def bar 86 | f = lambda { return "return from lambda" } 87 | f.call # после вызова функции замыкания f продолжается выполнение bar 88 | return "return from bar" 89 | end 90 | 91 | puts bar # печатает "return from bar" 92 | ~~~~~ 93 | 94 | ### Использование замыканий 95 | 96 | #### Приведение типов 97 | 98 | `.to_proc # -> self` 99 | 100 | `.to_s # -> string` 101 | 102 | Информация об объекте. 103 | `Proc.new { }.to_s # -> "#"` 104 | 105 | #### Операторы 106 | 107 | `.==(proc)` 108 | Синонимы: `eql?` 109 | 110 | Проверка на равенство. Два замыкания равны, если относятся к копиям одного и того же объекта. 111 | `proc {} == proc {} # -> true` 112 | 113 | **Во второй версии Ruby** этот метод удален. Два замыкания считаются эквивалентными, только если ссылаются на один объект. 114 | `proc {} == proc {} # -> false` 115 | 116 | `.===(arg) # -> object` 117 | 118 | Используется для выполнения замыкания. 119 | `proc { |a| a } === 1 # -> 1` 120 | 121 | #### Выполнение замыкания 122 | 123 | `.call(*arg) # -> object` 124 | Синонимы: `yield, .(*arg), [*arg]` 125 | 126 | Используется для выполнения замыкания. 127 | `-> x {x**2}.(5) # -> 25` 128 | 129 | \declare{.curry( count = nil )*arg}{ \# -> proc} 130 | 131 | Используется для подготовки замыкания. Замыкание будет выполнено, когда передается достаточное количество аргументов. В другом случае замыкание сохраняет информацию о переданных аргументах. 132 | 133 | Дополнительный аргумент ограничивает количество передаваемых аргументов (остальным параметрам присваивается nil). 134 | 135 | ~~~~~ ruby 136 | b = proc { | x, y, z | x + y + z } 137 | b.curry[1][2][3] # -> 6 138 | b.curry[1, 2][3, 4] # -> 6 139 | b.curry[1][2][3][4][5] # -> 0 140 | b.curry(5) [ 1, 2 ][ 3, 4][5] # -> 6 141 | b.curry(1) [1] # -> type_error! 142 | 143 | b = lambda { | x, y, z | x + y + z } 144 | b.curry[1][2][3] # -> 6 145 | b.curry[1, 2][3, 4] # -> argument_error! 146 | b.curry(5) # -> argument_error! 147 | b.curry(1) # -> argument_error! 148 | ~~~~~ 149 | 150 | #### Остальное 151 | 152 | `.arity # -> integer` 153 | 154 | Количество принимаемых аргументов. Для произвольного количества возвращается отрицательное число. Его инверсия с помощью оператора `~` в результате возвращает количество обязательных аргументов. 155 | 156 | ~~~~~ ruby 157 | proc {}.arity # -> 0 158 | proc { || }.arity # -> 0 159 | proc { |a| }.arity # -> 1 160 | proc { |a, b| }.arity # -> 2 161 | proc { |a, b, c| }.arity # -> 3 162 | proc { |*a| }.arity # -> -1 163 | proc { |a, *b| }.arity # -> -2 164 | proc { | a, *b, c | }.arity # -> -3 165 | ~~~~~ 166 | 167 | `.parameters # -> array` 168 | 169 | Информация о параметрах. 170 | 171 | ~~~~~ ruby 172 | proc = lambda { | x, y = 42, *other | } 173 | proc.parameters 174 | # -> [ [:req, :x], [:opt, :y], [:rest, :other] ] 175 | ~~~~~ 176 | 177 | `.binding # -> binding` 178 | 179 | Используется для получения состояния выполнения программы для замыкания. 180 | 181 | `.lambda? # -> bool` 182 | 183 | Проверка относится ли объект к лямбда-функциям. 184 | `proc {}.lambda? # -> false` 185 | 186 | `.source_location # -> array` 187 | 188 | Местоположение создания замыкания в виде `[filename, line]`. Для замыканий, создаваемых не на Ruby, возвращается nil. 189 | `proc {}.source_location # -> ["(irb)", 19]` 190 | 191 | `.hash # -> integer` 192 | 193 | Цифровой код объекта. 194 | `proc {}.hash # -> -259341767` 195 | 196 | #### Мемоизация 197 | 198 | Мемоизация - это хранение ранее вычисленного результата с помощью замыканий и вложенных подпрограмм. 199 | 200 | ~~~~~ ruby 201 | closure = proc { counter = 0; proc {counter += 1} }.call 202 | closure.call # -> 1 203 | closure.call # -> 2 204 | closure.call # -> 3 205 | ~~~~~ 206 | 207 | ## Методы 208 | 209 | Подпрограммы могут быть созданы на основе уже существующих методов с помощью классов Method и UnboundMethod. 210 | 211 | ### Method 212 | 213 | Экземпляры класса сохраняют информацию о методе вместе с объектом, для которого он вызывается. 214 | 215 | `.method(name) # -> method` 216 | 217 | Используется для сохранения информации о переданном методе объекта. Отсутствие метода считается исключением. 218 | `12.method(?+) # -> #` 219 | 220 | `.public_method(name) # -> method` 221 | 222 | Версия предыдущего метода для поиска только общих методов. 223 | `12.public_method(?+) # -> #` 224 | 225 | #### Операторы 226 | 227 | `.==(method)` 228 | Синонимы: `eql?` 229 | 230 | Проверка на равенство. Объекты равны, если связаны с одним и тем же объектом и содержат информацию об одном и том же методе. 231 | `12.method(?+) == 13.method(?+) # -> false` 232 | 233 | #### Приведение типов 234 | 235 | `.to_proc # -> lambda` 236 | 237 | Используется для создания лямбда-функции на основе метода. 238 | `12.method(?+).to_proc # -> #` 239 | 240 | `.to_s # -> string` 241 | 242 | Информация об объекте. 243 | `12.method(?+).to_s # -> "#"` 244 | 245 | `.unbind # -> umethod` 246 | 247 | Испольуется для удаления информации об объекте, для которого вызывается метод. 248 | `12.method(?+).unbind -> #` 249 | 250 | #### Вызов метода 251 | 252 | `.call(*arg) # -> object` 253 | 254 | Используется для вызова метода с переданными аргументами. 255 | `12.method(?+).call 3 # -> 15` 256 | 257 | #### Остальное 258 | 259 | `.arity # -> integer` 260 | 261 | Количество принимаемых аргументов. Для произвольного количества возвращается отрицательное число. Его инверсия с помощью оператора `~` в результате возвращает количество обязательных аргументов. Для методов, определенных без помощи Ruby возвращается -1. 262 | `12.method(?+).arity # -> 1` 263 | 264 | `.name # -> symbol` 265 | 266 | Идентификатор метода. 267 | `12.method(?+).name # -> :+` 268 | 269 | `.owner # -> module` 270 | 271 | Модуль, в котором объявлен метод. 272 | `12.method(?+).owner # -> Fixnum` 273 | 274 | `.parameters # -> array` 275 | 276 | Массив параметров метода. 277 | `12.method(?+).parameters # -> [ [:req] ]` 278 | 279 | `.receiver # -> object` 280 | 281 | Объект, для которого метод вызывается. 282 | `12.method(?+).receiver # -> 12` 283 | 284 | `.source_location # -> array` 285 | 286 | Местоположение объявления метода в виде массива `[filename, line]`. Для методов, определенных без помощи Ruby, возвращается nil. 287 | `12.method(?+).source_location # -> nil` 288 | 289 | `.hash # -> integer` 290 | 291 | Цифровой код объекта. 292 | `12.method(?+).hash # -> -347045594` 293 | 294 | ### UnboundMethod 295 | 296 | Экземпляры класса сохраняют информацию только о методе. 297 | 298 | `.instance_method(name) # -> umethod [Module]` 299 | 300 | Используется для хранения информации о переданном методе. Отсутствие метода считается ошибкой. 301 | `Math.instance_method :sqrt # -> #` 302 | 303 | `.public_instance_method(name) # -> umethod [Module]` 304 | 305 | Версия предыдущего метода для поиска только общих методов. 306 | `Math.public_instance_method :sqrt # -> error` 307 | 308 | #### Операторы 309 | 310 | `.==(umethod)` 311 | Синонимы: `eql?` 312 | 313 | Проверка на равенство. Объекты равны, если содержат информацию об одном и том же методе. 314 | `Math.instance_method(:sin) == Math.instance_method(:sin) # -> true` 315 | 316 | #### Приведение типов 317 | 318 | `.to_s # -> string` 319 | Синонимы: `inspect` 320 | 321 | Информация об объекте. 322 | `Math.instance_method(:sqrt).to_s # -> "#"` 323 | 324 | `.bind(object) # -> method` 325 | 326 | Используется для добавления информации об объекте, для которого метод вызывается. Если такая информация уже существовала, то объекты должны принадлежать к одному классу. 327 | 328 | ~~~~~ ruby 329 | 12.method(?+).unbind.bind 1 # -> # 330 | 12.method(?+).unbind.bind 1.0 # -> error! 331 | ~~~~~ 332 | 333 | #### Остальное 334 | 335 | `.arity # -> integer` 336 | 337 | Количество принимаемых аргументов. Для произвольного количества возвращается отрицательное число. Его инверсия с помощью оператора `~` в результате возвращает количество обязательных аргументов. Для методов, определенных без помощи Ruby возвращается -1. 338 | `Math.instance_method(:sqrt).arity # -> 1` 339 | 340 | `.name # -> symbol` 341 | 342 | Идентификатор метода. 343 | `Math.instance_method(:sqrt).name # -> :sqrt` 344 | 345 | `.owner # -> module` 346 | 347 | Модуль, в котором объявлен метод. 348 | `Math.instance_method(:sqrt).owner # -> Math` 349 | 350 | `.parameters # -> array` 351 | 352 | Массив параметров метода. 353 | `Math.instance_method(:sqrt).parameters # -> [ [:req] ]` 354 | 355 | `.source_location # -> array` 356 | 357 | Местоположение объявления метода в виде массива `[filename, line]`. Для методов, определенных без помощи Ruby, возвращается nil. 358 | `Math.instance_method(:sqrt).source_location # -> nil` 359 | 360 | `.hash # -> integer` 361 | 362 | Цифровой код объекта. 363 | `Math.instance_method(:sqrt).hash # -> 563385534` 364 | 365 | ## Сопрограммы (Fiber) 366 | [](fiber) 367 | 368 | Сопрограмма - это фрагмент кода, поддерживающий несколько входных точек и остановку или продолжение выполнения с сохранением состояния выполнения. Сопрограмму также можно рассматривать как поток выполнения, прерываемый специальной инструкцией. 369 | 370 | Сопрограммы также могут использоваться для реализации многопоточности на уровне программы (в действительности код выполняется в единственном потоке выполнения). Такие потоки также называют "green thread". Использование сопрограмм позволяет уменьшить накладные расходы на переключение и обмен данными, так как не требует взаимодействия с ядром ОС. 371 | 372 | Проблема при использовании сопрограмм в том, что выполнение системного вызова будет блокировать процесс выполнения программы. Сопрограммы должны использовать специальные методы ввода/вывода, не блокирующие процесс выполнения. Также стоит заметить что управление переключением сопрограмм выполняется вручную и требует дополнительных затрат при разработке. 373 | 374 | Для управления сопрограммами создаются контрольные точки с помощью метода `::yield` и осуществляется последовательный переход между ними с помощью метода `.resume`. 375 | 376 | `::new { |*params| } # -> fiber` 377 | 378 | Используется для создания сопрограммы. Блок при этом не выполняется. 379 | 380 | `::yield(*temp_result) # -> object` 381 | 382 | Используется для создания контрольной точки. Переданные аргументы возвращаются в результате вызова `.resume`. 383 | 384 | Возвращаются объекты, переданные при вызове метода `.resume` или полученные в результате выполнения последнего выражения в теле сопрограммы. 385 | 386 | `.resume(*args) # -> temp_result` 387 | 388 | Используется для выполнения блока до следующей контрольной точки. 389 | 390 | Если метод был вызван впервые, то переданные аргументы отправляются в сопрограмму. В другом случае они возвращаются в результате вызова метода `::yield` в теле блока. 391 | 392 | Если сопрограмма уже выполнена, то вызывается исключение `FiberError`. -------------------------------------------------------------------------------- /book/test.md: -------------------------------------------------------------------------------- 1 | # Тестирование и отладка 2 | 3 | ## Тестирование 4 | 5 | > Если вы хотите улучшить программу, вы должны не тестировать больше, а программировать лучше. 6 | 7 | ### Основы 8 | 9 | Любая, даже самая маленькая программа, не может гарантировать правильной работы. Тестирование программ и исправление обнаруженных ошибок - один из самых трудоемких этапов разработки. Он не заканчивается и после публикации приложения. 10 | 11 | Тестирование - это средство обнаружения ошибок. Для поиска и устранения их причин выполняется отладка. Устранение дефектов - это дорогой и длительный процесс. Легче сразу создать высококачественную программу, чем создать низкокачественную и исправлять ее. 12 | 13 | Тесты создаются для обнаружения ошибок, которые никогда не должны происходить, в отличии от обработки исключений, возникновение которых возможно и предусмотрено реализацией. 14 | 15 | Обзор кода часто эффективнее, чем тестирование, но выполнение тестов позволяет проверить влияние изменений, внесенных в ходе разработки. 16 | 17 | Существует множество подходов к тестированию приложения, но в основном грамотное тестирование - процесс прежде всего творческий. 18 | 19 | В общем случае тестирование приложения разделяется на четыре уровня: 20 | 21 | + _Модульное тестирование_ - тестирование минимально возможного фрагмента кода (unit test); 22 | _Интеграционное тестирование_ - тестирование взаимодействия между различными элементами приложения; 23 | _Функциональное тестирование_ - тестирование задач, выполняемых с помощью приложения; 24 | _Тестирование производительности_ - тестирование скорости выполнения программы и затрачиваемых на это ресурсов компьютера. 25 | 26 | Обычно для облегчения тестирования код разделяют на работающий с проверенными и непроверенными данными. 27 | 28 | При выполнении теста ему передаются как заведомо правильные, так и заведомо неправильные данные. 29 | 30 | Для тестирования программы может быть использована команда `testrb` (исполняемый файл на Ruby, использующий стандартную библиотеку Test::Unit). 31 | 32 | Программа принимает путь к файлу с тестами (или выполняет все тесты в каталоге) и выводит результатаы тестирования. 33 | 34 | Для проверки выполнения небольших кусков кода может быть использован интерактивный терминал irb. 35 | 36 | ### TDD 37 | 38 | Одна из популярных техник тестирования - разработка, управляемая тестами (TDD, Test-Drive Development). Использование этой техники разделено на следующие этапы: 39 | 40 | + Написание кода, тестирующего часть приложения; 41 | + Выполнение теста. Получение отрицательного результата (этот этап необходим для проверки корректности теста); 42 | + Написание кода приложения; 43 | + Выполнение теста. Получение положительного результата. 44 | 45 | Создание тестов перед кодом фокусирует внимание на требованиях к программе (т.е. необходимо понимание для чего она создается). 46 | 47 | Тестирование -> написание кода -> удовлетворение требований -> улучшение кода (рефакторинг). 48 | 49 | ## Отладка 50 | 51 | ### Состояние программы 52 | 53 | Так как вся программа по сути является объектом, то интроспекция также позволяет узнать о состоянии выполнения программы. 54 | 55 | `.global_variables # -> array [PRIVATE: Kernel]` 56 | 57 | Идентификаторы глобальных переменных. 58 | 59 | `.local_variables # -> array [PRIVATE: Kernel]` 60 | 61 | Идентификаторы локальных переменных. 62 | 63 | `::constants # -> array [Module]` 64 | 65 | Идентификаторы всех констант в теле программы (в теле Object). 66 | 67 | `::nesting # -> array [Module]` 68 | 69 | Очередь вызовов метода. 70 | 71 | `.__method__ # -> symbol [Kernel]` 72 | Синонимы: `__callee__` 73 | 74 | Идентификатор текущего метода. Вне тела метода возвращается nil. 75 | 76 | **Во второй версии Ruby** возвращается оригинальное название метода, а не имя синонима. 77 | 78 | ~~~~~ ruby 79 | def first; __callee__; end 80 | first # -> :first 81 | 82 | alias second first 83 | second # -> :first 84 | ~~~~~ 85 | 86 | ##### Переменные и константы 87 | 88 | `RUBY_PATCHLEVEL` - версия интерпретатора; 89 | 90 | `RUBY_PLATFORM` - название используемой системы; 91 | 92 | `RUBY_RELEASE_DATE` - дата выпуска интерпретатора; 93 | 94 | `RUBY_VERSION` - версия языка; 95 | 96 | `$PROGRAM_NAME ($0)` - имя выполняемой программы (по умолчанию - имя файла с расширением); 97 | 98 | `__dir__` - путь к текущему каталогу (ruby 2.0). 99 | 100 | Аналогично `File.dirname __FILE__`; 101 | 102 | `__FILE__` - имя выполняемого файла; 103 | 104 | `__LINE__` - номер выполняемой строки кода; 105 | 106 | `__Encoding__` - кодировка программы. 107 | 108 | ***** 109 | 110 | [](backtrace) 111 | ### Стек выполнения 112 | 113 | `.caller( offset = 1 ) # -> array [Kernel]` 114 | 115 | Состояние стека выполнения в виде массива, содержащего: 116 | `"файл:строка_кода"` или `"файл: строка_кода in метод"`. 117 | 118 | **Во второй версии Ruby** второй аргумент влияет на размер результата. Если он больше, чем количество выполненных строк кода, то возвращается nil. 119 | 120 | #### Ruby 2.0 121 | 122 | **Во второй версии** добавлен новый способ получить доступ к состоянию стека выполнения программы. 123 | 124 | `.caller_locations( start = 1, length = nil ) # -> array or nil [Ruby 2.0]` 125 | 126 | `(range) # -> array or nil` 127 | 128 | Фрагмент состояния стека выполнения программы в виде массива, содержащего экземпляры `Thread::Backtrace::Location`. 129 | 130 | Если начальная позиции фрагмента превышает текущий размер стека, то возвращается nil. 131 | 132 | ~~~~~ ruby 133 | # Ruby 1.9: 134 | def whoze_there_using_caller 135 | caller[0][/`([^']*)'/, 1] 136 | end 137 | 138 | # Ruby 2.0: 139 | def whoze_there_using_locations 140 | caller_locations(1, 1)[0].label 141 | end 142 | ~~~~~ 143 | 144 | ###### Thread::Backtrace::Location 145 | 146 | `.absolute_path # -> string` 147 | 148 | Полный путь к файлу. 149 | `caller_locations.last.absolute_path # -> "/usr/bin/irb"` 150 | 151 | `.base_label # -> string` 152 | 153 | Основная метка. Обычно соответсвует простой метке без дополнительного оформления. 154 | 155 | `caller_locations.last.base_label # -> "main"` 156 | 157 | `.inspect # -> string` 158 | Информация об объекте. 159 | 160 | `caller_locations.last.inspect # -> "\"/usr/bin/irb:12:in '
'\""` 161 | 162 | `.label # -> string` 163 | 164 | Метка. Обычно содержит название метода, класса, модуля и т.д. с дополнительным оформлением. 165 | `caller_locations.last.label # -> "
"` 166 | 167 | `.lineno # -> integer` 168 | 169 | Номер строки кода. 170 | `caller_locations.last.lineno # -> 12` 171 | 172 | `.path # -> string` 173 | 174 | Имя файла. 175 | 176 | ~~~~~ ruby 177 | loc = caller_locations(0..1).first 178 | loc.path # -> 'caller_locations.rb' 179 | ~~~~ 180 | 181 | `.to_s # -> string` 182 | 183 | Иноформация об объекте в стиле метода `Kernel.caller`. 184 | `caller_locations.last.to_s # -> "/usr/bin/irb:12:in '
'"` 185 | 186 | ### Трассировка 187 | 188 | Трассировка программы может выполняться с помощью частных методов экземпляров из модуля Kernel. 189 | 190 | `.set_trace_func( proc = nil )` 191 | 192 | Используется для выполнения переданной подпрограммы при возникновении ряда событий. Трассировка в теле подпрограммы при этом не выполняется. 193 | 194 | Подпрограмме передаются: идентификатор события, имя файла, номер строки кода, цифровой идентификатор объекта, экземпляр класса Binding и идентификатор класса объекта. 195 | 196 | Передача nil отменяет трассировку. 197 | 198 | Возможные события: 199 | + _"c-call"_ - вызов Си функции; 200 | _"c-return"_ - завершение выполнения Си функции; 201 | _"call"_ - вызов Ruby метода; 202 | _"return"_ - завершение выполнения Ruby метода; 203 | _"class"_ - начало определения класса или модуля; 204 | _"end"_ - завершение определения класса или модуля; 205 | _"line"_ - выполнение новой строки кода; 206 | _"raise"_ - вызов ошибки. 207 | 208 | ~~~~~ note 209 | Метод признан устаревшим во второй версии Ruby. Вместо него используется класс TracePoint. 210 | ~~~~~ 211 | 212 | `.trace_var( name, code ) # -> nil` 213 | 214 | `(name) { |object| } -> nil` 215 | 216 | Используется для выполнения кода при изменении глобальных переменных. В блок передается новое значение. 217 | 218 | `.untrace_var( name, code = nil ) # -> array` 219 | 220 | Используется для отмены трассировки глобальной переменной. Возвращается массив, содержащий выполняемый при трассировке код. 221 | 222 | #### TracePoint (ruby 2.0) 223 | 224 | Класс предназначен для замены `Kernel.set_trace_func` в объектном стиле. С помощью его экземпляров можно легко собирать информацию о процессе выполнения программы. 225 | 226 | ###### Создание трассировщика 227 | 228 | `::new(*events) { |a_trace_point| } # -> a_trace_point` 229 | 230 | Метод используется для создания объекта. Трассировка не начнется до тех пор пока не будет запущена в явной форме. 231 | 232 | По умолчанию будут отслеживаться все доступные события. Для фильтрации событий могут использоваться следующие идентификаторы: 233 | 234 | + _line:_ выполнение новой строки кода; 235 | _class:_ начало определения модуля или класса; 236 | _end:_ конец определения модуля или класса; 237 | _call:_ вызов метода; 238 | _return:_ возвращение результата выполнения метода; 239 | _c_call:_ вызов Си подпрограммы; 240 | _c_return:_ возвращение результата выполнения Си подпрограммы; 241 | _raise:_ получение исключения; 242 | _b_call:_ начало выполнения блока; 243 | _b_return:_ конец выполнения блока; 244 | _thread_begin:_ начало выполнения потока; 245 | _thread_end:_ конец выполнения блока. 246 | 247 | ~~~~~ ruby 248 | trace = TracePoint.new(:call) do |tp| 249 | p [tp.lineno, tp.defined_class, tp.method_id, tp.event] 250 | end 251 | # -> # 252 | ~~~~~ 253 | 254 | + Отсутствие блока считается исключением ThreadError. 255 | 256 | + Вызов методов, бесполезных для отслеживаемых событий, считается исключением RuntimeError. 257 | 258 | ~~~~~ ruby 259 | TracePoint.trace(:line) do |tp| 260 | p tp.raised_exception 261 | end 262 | # -> RuntimeError! 263 | ~~~~~ 264 | 265 | + Вызов методов вне блока считается исключением RuntimeError. 266 | 267 | ~~~~~ ruby 268 | TracePoint.trace(:line) do |tp| 269 | $tp = tp 270 | end 271 | $tp.line # -> RuntimeError! 272 | ~~~~~ 273 | 274 | `::trace(*events) { |a_trace_point| } # -> a_trace_point` 275 | 276 | Версия предыдущего метода, автоматически запускающая трассировку. 277 | 278 | ###### Управление трассировкой 279 | 280 | `.enable # -> boolean` 281 | 282 | `{ } # -> self` 283 | 284 | Метод используется для запуска трассировки. Когда трассировка не выполняется возвращается false. 285 | 286 | ~~~~~ ruby 287 | trace.enabled? # -> false 288 | trace.enable # -> false 289 | trace.enabled? # -> true 290 | trace.enable # -> true 291 | ~~~~~ 292 | 293 | Когда методу передается блок, то трассировка выполняется только в теле блока. 294 | 295 | ~~~~~ ruby 296 | trace.enabled? # -> false 297 | 298 | trace.enable do 299 | trace.enabled? 300 | end 301 | 302 | trace.enabled? # -> false 303 | ~~~~~ 304 | 305 | `.disable # -> boolean` 306 | 307 | `{ } # -> self` 308 | 309 | Метод используется для прекращения трассировки. Когда трассировка не выполняется возвращается false. 310 | 311 | ~~~~~ ruby 312 | trace.enabled? # -> true 313 | trace.disable # -> false 314 | trace.enabled? # -> false 315 | trace.disable # -> false 316 | ~~~~~ 317 | 318 | Когда методу передается блок, то трассировка прекращается только во время выполнения блока. 319 | 320 | ~~~~~ ruby 321 | trace.enabled? # -> true 322 | 323 | trace.disable do 324 | trace.enabled? 325 | end 326 | 327 | trace.enabled? # -> true 328 | ~~~~~ 329 | 330 | `.enabled? # -> boolean` 331 | 332 | Метод используется для проверки статуса активности трассировки. 333 | 334 | ###### Интроспекция 335 | 336 | `.binding # -> a_binding` 337 | 338 | Метод используется для сохранения текущего состояния выполнения программы. 339 | 340 | `.defined_class # -> a_module` 341 | 342 | Метод используется для получения ссылки на класс или модуль (возвращается собственный класс объекта), в котором был вызван обрабатываемый метод. Это позволяет выполнять интроспекцию состояния. 343 | 344 | ~~~~~ ruby 345 | class C; def foo; end; end 346 | trace = TracePoint.new(:call) do |tp| 347 | p tp.defined_class # -> C 348 | end.enable do 349 | C.new.foo 350 | end 351 | ~~~~~ 352 | 353 | ~~~~~ ruby 354 | module M; def foo; end; end 355 | class C; include M; end; 356 | 357 | trace = TracePoint.new(:call) do |tp| 358 | p tp.defined_class # -> M 359 | end.enable do 360 | C.new.foo 361 | end 362 | ~~~~~ 363 | 364 | ~~~~~ ruby 365 | class C; def self.foo; end; end 366 | trace = TracePoint.new(:call) do |tp| 367 | p tp.defined_class # -> # 368 | end.enable do 369 | C.foo 370 | end 371 | ~~~~~ 372 | 373 | `.event # -> symbol` 374 | 375 | Метод используется для получения типа события. 376 | 377 | `.inspect # -> string` 378 | 379 | Метод используется для получения текстового сообщения о состоянии объекта. 380 | 381 | `.lineno # -> integer` 382 | 383 | Метод используется для получения номера строки кода. 384 | 385 | `.method_id # -> string` 386 | 387 | Метод используется для получения имени вызванного метода. 388 | 389 | `.path # -> string` 390 | 391 | Метод используется для получения пути к выполняемому файлу. 392 | 393 | `.raised_exception # -> an_exception` 394 | 395 | Метод используется для получения экземпляра вызванного исключения (только для события `:raise`). 396 | 397 | `.return_value # -> object` 398 | 399 | Метод используется для получения возвращенного результата (только для событий `:return`, `:c_return`, `:b_return`). 400 | 401 | `.self # -> a_trace_point` 402 | 403 | Метод используется для получения трассировщика, отслеживающего событие. 404 | -------------------------------------------------------------------------------- /book/text.tex: -------------------------------------------------------------------------------- 1 | \chapter{Текст} 2 | 3 | \input{string} 4 | \input{regexp} 5 | \input{encode} 6 | --------------------------------------------------------------------------------