-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #159 from hexlet-basics/new
new structure
- Loading branch information
Showing
96 changed files
with
2,116 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
Наберите в редакторе код из задания символ в символ и нажмите «Проверить». | ||
|
||
```ruby | ||
puts 'Hello, World!' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
По традиции начнем с написания программы 'Hello, World!'. Эта программа будет выводить на экран текст: | ||
|
||
```ruby | ||
# В конце инструкции нет символа ; | ||
# В Ruby не ставятся ; практически никогда | ||
puts 'Hello, World!' | ||
``` | ||
|
||
`puts()` — функция печати на экран. В Ruby функции могут вызываться как со скобками, так и без них — разница только в способе записи. Код выше можно было бы записать так: | ||
|
||
```ruby | ||
puts('Hello, World!') | ||
``` | ||
|
||
Решение о том, ставить скобки или нет, зависит от предпочтений программиста и удобства в каждой конкретной ситуации. Это понимание придёт со временем. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name: Привет, Мир! | ||
tips: [] |
8 changes: 8 additions & 0 deletions
8
modules/10-basics/15-ruby-as-a-second-language/ru/EXERCISE.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
На данном этапе мы знаем ещё слишком мало, чтобы писать какой-то интересный код, поэтому просто скопируйте и выполните код ниже. В этом коде используется библиотека ActiveSupport, которая расширяет язык некоторыми полезными возможностями. Изначально она была создана для Rails, но используется и за его пределами. | ||
|
||
```ruby | ||
# На сервере время в UTC | ||
# Считаться будет от него | ||
puts 1.day.ago - 1.week + 3.hours | ||
``` |
76 changes: 76 additions & 0 deletions
76
modules/10-basics/15-ruby-as-a-second-language/ru/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
|
||
Ruby на нашем проекте дается как «второй язык» — это значит, что мы подразумеваем определенный багаж знаний у тех, кто учится ему здесь. В первую очередь это владение каким-либо другим языком программирования. Для понимания материала курса нужно иметь представление о типах данных, переменных, условных конструкциях, циклах, функциях, объектах (свойствах и методах) и лямбда-функциях (анонимных функциях). | ||
|
||
Изучение второго языка значительно проще первого, поэтому и структура материала сильно меняется. Здесь мы обзорно касаемся базовых конструкций для быстрого знакомства с синтаксисом, и переходим к интересным задачкам, ради которых, собственно, и изучается Ruby. | ||
|
||
## В чём соль? | ||
|
||
Ruby — динамический, строго типизированный язык с глубоким уклоном в объектно-ориентированную и функциональную парадигму программирования. | ||
|
||
```ruby | ||
# Строгая типизация, число нельзя умножить на строку | ||
4 * 'hexlet' # TypeError (String can't be coerced into Integer) | ||
# Всё объекты | ||
1.8.round # 2 | ||
# Функции высшего порядка | ||
['one', 'two'].map(&:upcase) # ["ONE", "TWO"] | ||
``` | ||
|
||
Он обладает местами непривычным, но невероятно выразительным синтаксисом. Благодаря этому код на Ruby читается как английский язык и при этом остаётся компактным: | ||
|
||
```ruby | ||
# Определение конечного автомата | ||
class Job | ||
include AASM | ||
|
||
aasm do | ||
state :sleeping, initial: true | ||
state :running, :cleaning | ||
|
||
event :run do | ||
transitions from: :sleeping, to: :running | ||
end | ||
|
||
event :sleep do | ||
transitions from: [:running, :cleaning], to: :sleeping | ||
end | ||
end | ||
end | ||
|
||
job = Job.new | ||
job.sleeping? # true | ||
job.may_run? # true | ||
job.run | ||
job.running? # true | ||
job.may_run? # false | ||
``` | ||
|
||
На Ruby создано большое количество решений, которые потом распространились по другим языкам. Самым ярким примером является фреймворк Ruby On Rails, который когда-то перевернул веб-разработку, и до сих пор является самым продвинутым бэкенд фреймворком для веб-разработки. И github.com, и gitlab.com написаны с использованием Rails. Даже этот сайт написан на Rails. | ||
|
||
В Ruby очень много метапрограммирования, встроенного во все части языка. Это значит, что программа может менять свое поведение прямо во время работы практически в любую сторону. Посмотрите, как происходит добавление методов во встроенные классы: | ||
|
||
```ruby | ||
# Этот код можно написать в любом месте программы | ||
class String # встроенный в Ruby класс, отвечающий за строки | ||
def wow # определение метода | ||
'ruby power' | ||
end | ||
end | ||
|
||
# Вызываем метод | ||
'hexlet'.wow # 'ruby power' | ||
``` | ||
|
||
И даже так: | ||
|
||
```ruby | ||
# Только для демонстрации | ||
# Класс New наследуется от случайно выбранного | ||
# класса One или Two, в зависимости от того, | ||
# какой из них выберет метод sample на момент загрузки файла с классом | ||
class New < [One, Two].sample | ||
# тут код класса | ||
end | ||
``` | ||
|
||
На этом моменте у вас возможно возникла мысль «это же ад». Как и любой мощный инструмент, Ruby можно использовать во зло — это правда, но если посмотреть на реальное положение дел, то при правильном использовании Ruby позволяет писать невероятно выразительный код. И раз вы здесь, то давайте научимся это делать. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
name: Ruby, Ruby, Ruby | ||
tips: | ||
- | | ||
[Ruby-комьюнити](https://t.me/hexletcommunity/9) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
Напечатайте на экран следующий вызов: | ||
|
||
```ruby | ||
# Здесь выводятся на экран все методы строк, | ||
# которые содержат знак вопроса в имени | ||
# Фактически — это вывод списка предикатов | ||
# То же самое можно сделать для любого типа | ||
puts 'hexlet'.methods.grep(/\?/) | ||
# Будет выведено около 20 имен | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
|
||
Ruby по своим возможностям и подходам в разработке близок к JavaScript и Python, но имеет свои особенности. Разработчики языка во многом опирались на Smalltalk, Lisp (это семейство языков), Perl и другие подобные языки. Это привело к интересному результату. Во-первых, Ruby — **очень** объектно-ориентированный язык. В Ruby всё есть объект, включая `nil` (это аналог `null`), и каждая операция — это вызов метода: | ||
|
||
```ruby | ||
'hexlet'.reverse # telxeh | ||
1.7.round # 2 | ||
nil.to_i # 0 | ||
1 + 1 # на самом деле 1.+(1) | ||
``` | ||
|
||
Одна из сильных сторон Ruby – [стандартная библиотека](https://ruby-doc.org/). Она решает практически все возникающие задачи. В одних только строках 185 встроенных методов! | ||
|
||
*Это одна из причин, почему Ruby чаще других выигрывает в [CodeBattle](https://codebattle.hexlet.io/)* | ||
|
||
```ruby | ||
# Количество методов у разных типов данных | ||
# В примерах ниже вызывается метод methods, | ||
# хотя кажется, что это обращение к свойству | ||
''.methods.count # 185 | ||
1.methods.count # 145 | ||
[].methods.count # 191 | ||
``` | ||
|
||
В Ruby всё, кроме присваивания, это вызовы методов. Такой подход позволяет переопределять буквально любое поведение: | ||
|
||
```ruby | ||
# То, что на самом деле происходит, когда мы выполняем «операции» | ||
1.+(5) # 6 | ||
1.>(3) # false | ||
``` | ||
|
||
На этом основано очень много кода, особенно библиотечного. Например, у любого объекта можно определить синтаксис, аналогичный доступу к массиву `[]`. Или можно определить операции для дат, сделав работу с ними максимально простой (как в примере прошлого урока). А вот как выглядят сеттеры у объектов: | ||
|
||
```ruby | ||
# Кажется, что это прямое изменение свойства | ||
# На самом деле это сеттер object.key=('value') | ||
obj.key = 'value' | ||
``` | ||
|
||
Все данные в Ruby — это объекты. Например `nil`, представлен классом `NilClass`, и является единственным его объектом. `true` — объект класса `TrueClass`, а `false` — объект класса `FalseClass`. У остальных типов свои классы. | ||
|
||
Узнать класс любого объекта можно так: | ||
|
||
```ruby | ||
1.class # Integer | ||
''.class # String | ||
nil.class # NilClass | ||
``` | ||
|
||
С другой стороны классы в Ruby — тоже объекты, у которых есть свои классы 0_o. Но это уже совсем другая история) Есть даже такая шутка (но это не шутка): в Ruby объект это класс, а класс — это объект. Почему это так – узнаем чуть позже. | ||
|
||
## Отладочная печать | ||
|
||
Иногда в работе приходится прибегать к отладочной печати и в Ruby есть несколько особенностей, о которых надо знать. Функция `puts()` выводит любые типы данных без необходимости преобразования их в строку. С другой стороны, такой вывод не останавливает выполнение и иногда это неудобно, если хочется посмотреть только первый вывод. Для таких ситуаций лучше использовать выброс исключения, которое и выведет на экран нужную информацию и прервёт выполнение. Делается это так: | ||
|
||
```ruby | ||
# raise – бросить исключение | ||
# .inspect – метод, который преобразует | ||
# любые данные в строковое представление | ||
raise something.inspect | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name: Всё есть объект | ||
tips: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
|
||
Реализуйте функцию `double()`, которая удваивает любое переданное ей число и возвращает его: | ||
|
||
```ruby | ||
double(3) # 6 | ||
double(8) # 16 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
|
||
Начнем сразу с комплексного примера, включающего в себя определение функции, переменной и простые арифметические операции. Посмотрим на синтаксис и разберём некоторые интересные особенности Ruby. Ниже дано определение функции, находящей среднее арифметическое: | ||
|
||
```ruby | ||
# def – определение функции | ||
def find_average(a, b) | ||
# создание переменной sum | ||
sum = a + b | ||
# преобразование к Float | ||
sum.to_f / 2 | ||
end | ||
|
||
find_average(3, 1) # 2.0 | ||
find_average(1, 2) # 1.5 | ||
|
||
# Можно вызывать и так | ||
find_average 3, 1 | ||
find_average 1, 2 | ||
|
||
# ArgumentError (wrong number of arguments (given 1, expected 2) | ||
find_average(1) | ||
``` | ||
|
||
Сначала пара слов о стиле. В Ruby существует ровно один общепринятый стиль оформления кода, которого [придерживается](https://ukupat.github.io/tabs-or-spaces/) все комьюнити: | ||
|
||
* Отступы — два пробела | ||
* Для определения имен переменных и функций используется snake_case | ||
* Определение классов — CamelCase | ||
|
||
Определение функции начинается ключевым словом `def`, за которым идёт имя функции и её параметры. В конце добавляется `end`. В отличие от своих собратьев, в Ruby не обязательно писать ключевое слово `return`. Как и в Smalltalk, в Ruby функции всегда возвращают результат последнего вычисленного выражения. Иногда `return` всё же используется, когда нужно досрочно выйти из функции. В остальных случаях его опускают. | ||
|
||
Определение переменных в Ruby крайне простое. Достаточно написать имя и присвоить ему любое значение. Затем переменную можно использовать и менять как угодно и где угодно в поле её видимости. | ||
|
||
```ruby | ||
sum = a + b | ||
``` | ||
|
||
Необычно в примере выше может выглядеть код `sum.to_f`. Здесь происходит вызов метода `to_f()` у числа, записанного в `sum`. Для чего это нужно? В Ruby при делении целых чисел на выходе всегда получается целое число. Если при этом была дробная часть, она отбрасывается: | ||
|
||
```ruby | ||
3 / 2 # 1 | ||
3.to_f / 2 # 1.5 | ||
``` | ||
|
||
По своему смыслу функция `find_average()` должна возвращать число с плавающей точкой, поэтому такое преобразование необходимо. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name: Первая функция | ||
tips: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
|
||
Реализуйте функцию предикат `even?`, которая проверяет, является ли переданное число чётным. Функция должна возвращать `true`, если число чётное и `false`, если не чётное. Не используйте встроенные функции для определения четности: | ||
|
||
```ruby | ||
even?(5) # false | ||
even?(6) # true | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
|
||
## Логические операторы | ||
|
||
Логический тип в Ruby представлен привычными значениями `true` и `false`, а также набором операторов `&&` (и), `==` (равно), `||` (или) и `!` (не): | ||
|
||
```ruby | ||
true && false # false | ||
false || true # true | ||
``` | ||
|
||
В отличие от многих других языков сравнение с логическим значением в Ruby строгое, то есть `true` и `false` равны только самим себе: | ||
|
||
```ruby | ||
true == 1 # false | ||
false == nil # false | ||
``` | ||
|
||
Что не отменяет возможности использовать в логических выражениях значения любых типов: | ||
|
||
```ruby | ||
0 && 'one' # "one" | ||
nil && false # nil | ||
``` | ||
|
||
В Ruby только `nil` и `false` рассматриваются как *falsey*, все остальные значения в логических выражениях приводятся к `true`. | ||
|
||
## Значение по умолчанию | ||
|
||
В Ruby широко используется такой код: | ||
|
||
```ruby | ||
a ||= 'что-то' | ||
# a = a || 'что-то' | ||
``` | ||
|
||
Он используется для задания значения по умолчанию. Такое возможно и почти всегда безопасно из-за очень ограниченного списка *falsey* значений. Единственное место, где этот способ не сработает – там, где `false` это допустимое значение. | ||
|
||
## Предикаты | ||
|
||
В Ruby в отличие от большинства других языков принято использовать предикаты практически для всех часто встречающихся проверок. Например, как мы обычно проверяем, что число равно нулю? С помощью сравнения с нулем. В Ruby это тоже работает, но это не Ruby Way: | ||
|
||
```ruby | ||
0.zero? # true | ||
1.zero? # false | ||
2.positive? # true | ||
|
||
# чётное/нечётное | ||
8.even? # true | ||
8.odd? # false | ||
|
||
''.empty? # true | ||
'wow'.empty? # false | ||
|
||
something.nil? | ||
|
||
# не пустой массив | ||
items.any? | ||
# пустой массив | ||
items.empty? | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name: Логический тип | ||
tips: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
В Ruby встроен оператор `<=>` (spaceship). Этот оператор удобно использовать в функциях сортировки для определения того, нужно менять местами два соседних элемента или нет. Всего у функции возможны три разных варианта возврата: | ||
|
||
```ruby | ||
1 <=> 1 # 0 числа равны | ||
2 <=> 1 # 1 левое больше правого | ||
1 <=> 2 # -1 левое меньше правого | ||
``` | ||
|
||
Вашей задачей в этом задании будет написать функцию `compare()`, которая ведёт себя так же, как и spaceship-оператор: | ||
|
||
```ruby | ||
compare(1, 1) # 0 числа равны | ||
compare(2, 1) # 1 левое больше правого | ||
compare(1, 2) # -1 левое меньше правого | ||
``` |
Oops, something went wrong.