Skip to content

Commit

Permalink
Merge pull request #159 from hexlet-basics/new
Browse files Browse the repository at this point in the history
new structure
  • Loading branch information
Malcom1986 authored Dec 27, 2023
2 parents 9d14e3d + 3e8b76e commit 2da1569
Show file tree
Hide file tree
Showing 96 changed files with 2,116 additions and 0 deletions.
6 changes: 6 additions & 0 deletions modules/10-basics/10-hello-world/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

Наберите в редакторе код из задания символ в символ и нажмите «Проверить».

```ruby
puts 'Hello, World!'
```
16 changes: 16 additions & 0 deletions modules/10-basics/10-hello-world/ru/README.md
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!')
```

Решение о том, ставить скобки или нет, зависит от предпочтений программиста и удобства в каждой конкретной ситуации. Это понимание придёт со временем.
2 changes: 2 additions & 0 deletions modules/10-basics/10-hello-world/ru/data.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name: Привет, Мир!
tips: []
8 changes: 8 additions & 0 deletions modules/10-basics/15-ruby-as-a-second-language/ru/EXERCISE.md
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 modules/10-basics/15-ruby-as-a-second-language/ru/README.md
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 позволяет писать невероятно выразительный код. И раз вы здесь, то давайте научимся это делать.
4 changes: 4 additions & 0 deletions modules/10-basics/15-ruby-as-a-second-language/ru/data.yml
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)
11 changes: 11 additions & 0 deletions modules/10-basics/20-everything-is-object/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

Напечатайте на экран следующий вызов:

```ruby
# Здесь выводятся на экран все методы строк,
# которые содержат знак вопроса в имени
# Фактически — это вывод списка предикатов
# То же самое можно сделать для любого типа
puts 'hexlet'.methods.grep(/\?/)
# Будет выведено около 20 имен
```
61 changes: 61 additions & 0 deletions modules/10-basics/20-everything-is-object/ru/README.md
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
```
2 changes: 2 additions & 0 deletions modules/10-basics/20-everything-is-object/ru/data.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name: Всё есть объект
tips: []
7 changes: 7 additions & 0 deletions modules/10-basics/25-first-function/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

Реализуйте функцию `double()`, которая удваивает любое переданное ей число и возвращает его:

```ruby
double(3) # 6
double(8) # 16
```
45 changes: 45 additions & 0 deletions modules/10-basics/25-first-function/ru/README.md
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()` должна возвращать число с плавающей точкой, поэтому такое преобразование необходимо.
2 changes: 2 additions & 0 deletions modules/10-basics/25-first-function/ru/data.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name: Первая функция
tips: []
7 changes: 7 additions & 0 deletions modules/10-basics/27-conditions/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

Реализуйте функцию предикат `even?`, которая проверяет, является ли переданное число чётным. Функция должна возвращать `true`, если число чётное и `false`, если не чётное. Не используйте встроенные функции для определения четности:

```ruby
even?(5) # false
even?(6) # true
```
60 changes: 60 additions & 0 deletions modules/10-basics/27-conditions/ru/README.md
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?
```
2 changes: 2 additions & 0 deletions modules/10-basics/27-conditions/ru/data.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name: Логический тип
tips: []
16 changes: 16 additions & 0 deletions modules/10-basics/30-if/ru/EXERCISE.md
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 левое меньше правого
```
Loading

0 comments on commit 2da1569

Please sign in to comment.