Skip to content
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[Makefile]
indent_style = tab

[*.md]
indent_size = 4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*.log
tmp
23 changes: 12 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
-include /opt/basics/common/common.mk

# export RUBYLIB=$(realpath lib)
# export PATH:=$(realpath bin):$(PATH)

compose-setup: compose-build compose-install

compose:
docker-compose up
docker-compose up --abort-on-container-exit

compose-install:
docker-compose run exercises bundle install
docker-compose run --rm exercises bundle install

compose-bash:
docker-compose run exercises bash
docker-compose run --rm exercises bash

compose-down:
docker-compose down -v --remove-orphans

compose-build:
docker-compose build

compose-test:
docker-compose run exercises make test
docker-compose run --rm exercises make test

compose-code-lint:
docker-compose run exercises make code-lint
docker-compose run --rm exercises make code-lint

compose-lint:
docker-compose run exercises make code-lint
docker-compose run --rm exercises make code-lint

compose-description-lint:
docker-compose run exercises make description-lint
docker-compose run --rm exercises make description-lint

compose-schema-validate:
docker-compose run exercises make schema-validate
docker-compose run --rm exercises make schema-validate

ci-check:
docker-compose --file docker-compose.yml down -v --remove-orphans
docker-compose --file docker-compose.yml build
docker-compose --file docker-compose.yml up --abort-on-container-exit

Expand Down
27 changes: 23 additions & 4 deletions modules/10-basics/10-hello-world/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
Наберите в редакторе код, чтобы программа вывела **точно такую строку**:

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

```ruby
puts 'Hello, World!'
```text
Hello, World!
```

### Важно!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно объяснять в теории (я как раз в python делал)


* Строка должна совпадать **символ в символ**: заглавные и строчные буквы, запятые, пробелы и восклицательный знак.
* Кавычки обязательны.
* Скобки у `puts` можно ставить или нет — это не повлияет на результат.

### Типичные ошибки
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Убираем, курс не для новичков


* `hello, World!` — первая буква маленькая
* `Hello, world!` — буква "w" маленькая
* `Hello World!` — пропущена запятая
* `puts Hello, World!` — забыты кавычки
* `puts(‘Hello, World!’)` — неправильные кавычки

### Если тест не пройден

1. Сравните вывод вашей программы с образцом `Hello, World!`.
2. Исправьте отличия **символ в символ**.
3. Запустите проверку снова.
9 changes: 7 additions & 2 deletions modules/10-basics/10-hello-world/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@

describe 'output' do
it 'should works' do
_(-> { require_relative 'index' }).must_output(/^Hello, World!$/)
puts 'Hello, World!'
out, _err = capture_io do
require_relative 'index'
end

result = out.strip

assert { result == "Hello, World!" }
end
end
12 changes: 11 additions & 1 deletion modules/10-basics/15-ruby-as-a-second-language/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@

На данном этапе мы знаем ещё слишком мало, чтобы писать какой-то интересный код, поэтому просто скопируйте и выполните код ниже. В этом коде используется библиотека ActiveSupport, которая расширяет язык некоторыми полезными возможностями. Изначально она была создана для Rails, но используется и за его пределами.
На данном этапе мы знаем ещё слишком мало, чтобы писать какой-то интересный код, поэтому просто скопируйте и выполните код ниже. В этом коде используется библиотека ActiveSupport, которая расширяет язык некоторыми полезными возможностями.Изначально она была создана для Rails, но используется и за его пределами.

Библиотека ActiveSupport уже подключена в файл, поэтому просто наберите код:

```ruby
# На сервере время в UTC
# Считаться будет от него
puts 1.day.ago - 1.week + 3.hours
```

Код должен нужно набрать между специальными комментариями:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

код должен нужно


```text
# BEGIN (write your solution here)
... тут пишем код
# END
```
26 changes: 21 additions & 5 deletions modules/10-basics/15-ruby-as-a-second-language/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,28 @@
require 'active_support/all'
require 'test_helper'

describe 'function' do
describe 'output' do
it 'should works' do
puts "current time: #{Time.now}"
# Захватываем stdout из index.rb
out, _err = capture_io do
require_relative 'index'
end

puts "Current time:"
puts Time.now
puts "Captured time output:"
puts out

# Вычисляем ожидаемую дату
date = 1.day.ago - 1.week + 3.hours
r = Regexp.new(date.year.to_s, Regexp::MULTILINE)
_(-> { require_relative 'index' }).must_output(r)
puts date

# Приводим вывод к строке без лишних переводов строки
out_str = out.strip

# Убираем миллисекунды, сравниваем только по секундам
expected = date.change(usec: 0).to_s

# Power Assert проверка
assert { out_str == expected }
end
end
4 changes: 1 addition & 3 deletions modules/10-basics/20-everything-is-object/index.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# BEGIN
puts 'hexlet'.methods.grep(/\?/)
# END
puts 'hexlet'.methods.shuffle.first(5)
28 changes: 22 additions & 6 deletions modules/10-basics/20-everything-is-object/ru/EXERCISE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,26 @@
Напечатайте на экран следующий вызов:

```ruby
# Здесь выводятся на экран все методы строк,
# которые содержат знак вопроса в имени
# Фактически — это вывод списка предикатов
# То же самое можно сделать для любого типа
puts 'hexlet'.methods.grep(/\?/)
# Будет выведено около 20 имен
puts 'hexlet'.methods.shuffle.first(10)
```

Вот что он делает:

1. `'hexlet'.methods` — массив всех методов объекта строки.
3. `.shuffle` — перемешивает массив методов случайным образом.
4. `.first(10)` — берёт первые 10 методов из перемешанного массива.
5. `puts` — выводит их по одному на строку.

💡 Важное: **результат будет случайным**, потому что `.shuffle` перемешивает методы.

Пример возможного вывода (точно будет другим при каждом запуске):

```text
reverse
inspect
lines
display
casecmp
```

То есть **это 5 случайных методов строки**.
19 changes: 16 additions & 3 deletions modules/10-basics/20-everything-is-object/test.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
# frozen_string_literal: true

require 'active_support/all'
require 'test_helper'

describe 'function' do
describe 'output' do
it 'should works' do
_(-> { require_relative 'index' }).must_output(/respond_to/)
puts 'hexlet'.methods.grep(/\?/)
# Захватываем stdout из index.rb
out, _err = capture_io do
require_relative 'index'
end

puts out

methods = out.strip.split("\n")

assert { methods.size == 5 }

methods.each do |method|
assert { "hexlet".respond_to? method }
end
end
end
4 changes: 0 additions & 4 deletions modules/10-basics/25-first-function/index.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# frozen_string_literal: true

# BEGIN
def double(num)
num * 2
end
# END
6 changes: 5 additions & 1 deletion modules/10-basics/25-first-function/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@

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

Пример вызова:

```ruby
double(3) # 6
double(8) # 16
```

Функцию не нужно вызывать вручную, она будет вызвана в тестах.
48 changes: 47 additions & 1 deletion modules/10-basics/25-first-function/ru/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@

Начнем сразу с комплексного примера, включающего в себя определение функции, переменной и простые арифметические операции. Посмотрим на синтаксис и разберём некоторые интересные особенности Ruby. Ниже дано определение функции, находящей среднее арифметическое:
В Ruby функция выглядит так:

```ruby
# Определение функции
def имя_функции(параметр)
# тело функции
end

# Вызов функции
имя_функции(значение)
```

* `def` — ключевое слово для создания функции
* `имя_функции` — название функции (используем `snake_case`)
* `(параметр)` — имя переменной, которая будет использоваться внутри функции
* `end` — завершает функцию

Ниже дано определение функции, находящей среднее арифметическое:

```ruby
# def – определение функции
Expand All @@ -21,6 +38,8 @@ find_average 1, 2
find_average(1)
```

## Стиль кода в Ruby

Сначала пара слов о стиле. В Ruby существует ровно один общепринятый стиль оформления кода, которого [придерживается](https://ukupat.github.io/tabs-or-spaces/) все комьюнити:

* Отступы — два пробела
Expand All @@ -43,3 +62,30 @@ sum = a + b
```

По своему смыслу функция `find_average()` должна возвращать число с плавающей точкой, поэтому такое преобразование необходимо.

## Где проверить код
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Про репл как в python рассказываем


Если у вас установлен Ruby, то можно запустить код внутри REPL, набрав в терминале команду `irb`:

```bash
irb
irb(main):001* def find_average(a, b)
irb(main):002* sum = a + b
irb(main):003* sum.to_f / 2
irb(main):004> end
=> :find_average
irb(main):005>
irb(main):005> find_average(1, 5)
=> 3.0
irb(main):006>
```

Или онлайн в [Repl.it Ruby](https://replit.com/languages/ruby).

## Итог

* Функции в Ruby определяются через `def ... end`
* Имя функции пишется в стиле `snake_case`
* Аргументы перечисляются в круглых скобках
* `return` писать не обязательно — функция возвращает результат последнего выражения
* Функции можно запускать как с круглыми скобками, так и без
8 changes: 6 additions & 2 deletions modules/10-basics/27-conditions/ru/EXERCISE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
Реализуйте функцию предикат `even?`, которая проверяет, является ли переданное число чётным. Функция должна возвращать `true`, если число чётное и `false`, если не чётное.

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

Примеры вызова:

```ruby
even?(5) # false
even?(6) # true
# Скобки при вызове можно опустить
even? 6 # true
```
52 changes: 52 additions & 0 deletions modules/10-basics/27-conditions/ru/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ nil && false # nil

В Ruby только `nil` и `false` рассматриваются как *falsey*, все остальные значения в логических выражениях приводятся к `true`.

## Spaceship-оператор

Этот оператор удобно использовать в функциях сортировки для определения того, нужно менять местами два соседних элемента или нет. Всего у функции возможны три разных варианта возврата:

```ruby
1 <=> 1 # 0 числа равны
2 <=> 1 # 1 левое больше правого
1 <=> 2 # -1 левое меньше правого
```

## Значение по умолчанию

В Ruby широко используется такой код:
Expand Down Expand Up @@ -58,3 +68,45 @@ items.any?
# пустой массив
items.empty?
```

Пример: функция, которая проверяет, что число положительное:

```ruby
def positive?(num)
num > 0
end

positive?(3) # true
positive?(-1) # false
```

**Правила:**

* Название метода должно заканчиваться на `?`
* Метод возвращает `true` или `false`
* Параметры могут быть любыми объектами


## Типичные ошибки
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно убрать


```ruby
# ❌ Не используем ? в имени
def even_length(str)
str.length.even?
end

# ❌ Возвращаем не логическое значение
def even_length?(str)
str.length
end
```

## Итог

* Логические значения в Ruby: `true` и `false`
* Логические операторы: `&&` (и), `||` (или), `!` (не)
* В Ruby только `nil` и `false` — falsey, остальные значения считаются true
* Значение по умолчанию можно задавать через `||=`
* Предикаты — методы, которые возвращают `true` или `false`
* Методы-предикаты по соглашению заканчиваются на `?`
* Можно создавать свои предикаты для любых проверок
Loading
Loading