Руби роуз

Некоторые изменения в релизе

С выходом версии Crystal 1.0 в кортежах (tuples) теперь допускается обращение к элементам отличающихся типов по индексу, поскольку компилятор «знает», к какому типу относится каждый из них.

Стандартная библиотека подверглась зачистке от устаревших и не рекомендованных к использованию определений, в частности методов HTTP::Request, HTTP::WebSocket, HTTP::LogHandler; URI#full_path; Time::Span#duration.

Внесены изменения, касающиеся того, как обрабатываются cookie-файлы. Так, метод HTTP::Cookies.from_headers разделен на отдельные серверную и клиентскую версии. Значения и имена cookie больше не кодируются/декодируются по соображениям безопасности.

Некоторые из возможностей Crystal 1.0 реализованы, но официально пока не поддерживаются. В их числе моногопоточность (выполнение в среде с многоядерным процессором; активируется флагом -Dpreview_mt), поддержка Microsoft Windows, а также процессоров архитектуры ARM.

Особенности языка

Crystal, в отличие от Ruby, является языком со статической типизацией, то есть ошибки несоответствия типов переменных выявляются компилятором на стадии переработки кода программы в код машинный, а не в процессе его выполнения интерпретатором.

Как пандемия изменила подходы к организации рабочего пространства
Бизнес

Тем не менее, синтаксис языка не требует указания конкретных типов переменных или аргументов метода, поскольку компилятор способен их самостоятельно вывести при помощи соответствующего механизма. Язык решает проблему автоматического управления памятью за счет использования «консервативного» сборщика мусора (garbage collector) Boehm GC. Crystal поддерживает макросы, дженерики, а также перегрузку методов и операторов.

Как и Ruby, Crystal предлагает независимую от операционной системы реализацию многопоточности. Легковесные потоки в Crystal называются «файберами» или «волокнами» (от англ. fiber – волокно; – прим. CNews). Потоки, как и в языках Go и Clojure, взаимодействуют друг с другом при помощи каналов, без необходимости прибегать к использованию общей памяти или блокировкам.

В Crystal реализован интерфейс вызова функций из библиотек на языке C, причем синтаксис взаимодействия с ними достаточно прост, чтобы позволяет без особого труда создавать библиотеки-обертки, а не писать весь код «с нуля».

Как расти в профессии

Самая главная проблема для начинающих — понять, как правильно писать, что использовать, как использовать. Тут я бы просто посоветовал почитать блоги ведущих разработчиков и изучать практики — именно они позволяют ребятам расти быстрее.

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

Пригодится любой предыдущий опыт работы. Например, если вы до этого занимались ремонтом или продажей машин, то наиболее перспективно реализовать себя сможете скорее всего именно в тех проектах, где используется эта тематика.

Для понимания скажу так: старшие разработчики — это, как правило, люди, которые не только хорошо пишут код и умеют дебажить, но и хорошо понимают специфику текущего проекта.

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

Касательно построения карьеры в разработке, считаю, что каждый разработчик должен знать фронтенд в той или иной степени, и не важно — вы будете чистый бекенд или нет. С фронтендом, вёрсткой и разметкой вам всегда придётся работать

Стоит развиваться не только вглубь, но ещё и вширь — поглощать другие сферы.

Программа обучения: «Профессия frontend-разработчик»

Сейчас фронтенд усложнился намного больше, чем бекенд. Стоит понимать, как с ним работают, где с ним работают, как выстроить хорошую архитектуру для фронтенда. Потому что зачастую проблемы начинаются с фронтенда и уже потом заканчиваются на бекенде. Сайты сейчас становятся очень большими и тяжёлыми, фронтенд периодически нужно улучшать и делать так, чтобы он меньше весил и быстрее загружался.

Требования постоянно растут к разработчикам и их проектам. И соответственно с базами данных надо уметь работать. Потому что если вы не умеете работать с базами данных, обращаться к ним, то проект будет терять очень много денег и никакой клиент не захочет вам платить хорошие деньги, если вы не можете выстроить хороший фреймворк в данной ситуации под данную задачу.

Мнение автора и редакции может не совпадать. Хотите написать колонку для «Нетологии»? Читайте наши условия публикации. Чтобы быть в курсе всех новостей и читать новые статьи, присоединяйтесь к Телеграм-каналу Нетологии.

Artificial Intelligence, герой нашего времени. Этюд

Из песочницы

Хм. Один из пунктов, регламентирующих действия модераторов на Хабре, сформулирован следующим образом: не надо пропускать статьи, слабо относящиеся к IT-тематике или не относящиеся к ней вовсе. Что сходу заставило автора призадуматься, а имеет ли прямое отношение к «IT-тематике» его пост, повествующий о некоторых этапах программирования забавного и увлекательного своего pet-проекта, несложного AI, выстраивающего нейронную сеть на основе ruby-обертки FANN для игры в крестики-нолики? Вопрос не содержит скрытого кокетства, ведь описанию логики программного кода в моем рассказе предназначено далеко не первостепенное значение. «Да это злая ирония!» – скажете вы. – Не знаю.

ОК. Данная разработка де-факто является иллюстрацией ряда странных наблюдений автора, некоторое число знакомых и даже друзей-приятелей которого в последние годы… заставили его припомнить уроки литературы своей когда-то в бытность очень-очень средней советской школы. Несмотря на перманентное его убеждение в том, что «проходить» всегда возможно только лишь мимо чего-то — некие персонажи русской классики вспоминаются с течением времени все чаще. Или, может статься, так и должно быть?

Итак, с места в карьер… после первого запуска программа начинает процесс самообучения, проигрывая сама с собой несколько десятков (минута — две максимум) тысяч партий (число, понятное дело, доступно для редактирования в конфиге; учитывая описываемый далее не вполне обычный алгоритм, положенный в основу логики этого AI — эксперименты такого рода также способны предоставить интересный материал для умозаключений). Здесь имитируется процесс обучения, свойственный многим другим Artificial Intelligence, с той лишь разницей, что оба «игрока» в равной степени играть не умеют, делая абсолютно рандомные ходы. Но правила игры действуют: если случайный ход не соответствует, программа обязана переходить, соответственно и выигрыш достанется той стороне, которая выиграет. Все честно: никаких подчисток и хаков, скрытых предпочтений, никаких тебе фейковых допинг-проб, зачастую в реальной жизни опрокидывающих результаты спортивных игр.

Римейк

В феврале 2010 года ABS-CBN объявил, что Televisa дала им разрешение на создание версии сериала для Пиной. В адаптации «Пиной» в главных ролях снимаются Анжелика Панганибан и Шайна Магдаяо, а в главных ролях — Джейк Куэнка и Дитер Окампо . Он был запущен как одно из предложений сети по случаю 60-летнего юбилея Pinoy Soap Opera («ika-60 taon ng Pinoy Soap Opera») во время Trade Launch в 1 квартале того же года под названием «Bagong Simula» (Новое начало ).

В январе 2012 года O3 выпустила с разрешения Televisa арабскую версию сериала. В арабской адаптации в главных ролях сыграли Кайрин Абдельнур и Диамант Абу Аббуд, а в главных ролях — Максим Халил и Амир Карара . Он транслировался на MBC4 в арабском мире и LBCI в Ливане.

Театр

Бразильский актер Меттуро Гомес снялся в первой сценической версии «Руби» под псевдонимом Даймонд Андар, являющейся мужской версией

Сам Те привлекает внимание тем, что у него вертикальные брови, похожие на Bárbara Mori ando для красоты истории .. В январе 2020 года Univision сняли ремейк с Камилой Соди в главной роли

Это римейк и сиквел одновременно, поскольку он будет следовать за событиями через 20 лет после оригинального финала.

В январе 2020 года Univision сняли ремейк с Камилой Соди в главной роли. Это римейк и сиквел одновременно, поскольку он будет следовать за событиями через 20 лет после оригинального финала.

Скрипт на ruby, который с помощью яндекс-сервиса Yandex SpeechKit распознает текст в видео-файле (длинные аудио)

Начну с того, что я совсем недавно начала погружаться в IT в целом и Ruby в частности, и это задание мне выдали в качестве тестового для получения места на стажировке. Заранее скажу, что тут еще есть что приглаживать и улучшать, но в целом код работает.

Однако, возможно, мой опыт может быть для кого то полезен, так что представляю вашему вниманию подробное описание создания этого скрипта

ВАЖНО: Моя операционная система Fedora 32, так же я использую заранее установленный в систему bundler. Так что если вы тоже используете linux-подобные системы, читаем далее

Суть задания: есть видеофайл в формате mp4 нужно написать скрипт на чистом ruby, который будет конвертировать этот файл в аудио, отправлять его в сервис яндекса Yandex SpeechKit и получив ответ, создавать текстовый файл.

Синтаксис и Семантика

 puts "foo"
 foo
=> nil

Вывод – , но при этом значение – .

Печать

  • печатает передаваемые аргументы
  • печатает передаваемые аргументы с переводом на новую строку в конце
  • inspects and prints its arg plus a newline

Продвинутая печать

  • «красивая» печать параметров с переводом на новую строку
  • еще более «красивая» печать, чем
  • предоставляется gem’ом
  • если , печатает
  • Блоки также могут принимать параметры и возвращать значения
  • к примеру, итератор переносит каждый элемент массива в новый массив

     "hello", "world"map { |string| string.upcase }
    => "HELLO", "WORLD"
    
  • определяет блок

Опциональная пунктуация

  • Точки с запятой, скобки, и являются опциональными

  • Следующие выражения эквивалентны:

    def inc(x)
      return x + 1;
    end
    
    def inc x
      x + 1
    end
    
    def inc(x); x + 1; end
    
    def inc(x) x + 1; end
    
x = 1 + 2
x #=> 3

x = 1
  + 2
x #=> 1

Решение: всегда оставлять операторы на верхней строке

x = 1 +
    2
x #=> 3

Используйте круглые скобки только если они нужны

 "Hello".gsub "H", "h"
=> "hello"

 "Hello".gsub "H", "h".reverse
=> "hello"

 "Hello".gsub("H", "h").reverse
=> "olleh"

Интерполяция строк

"boyz #{1 + 1} men"
=> "boyz 2 men"
  • Любой Ruby-код может быть написан внутри фигурных скобок
  • Он выполняется и результат записывается в строке
def add a, b
  a + b
end

add 2, 2
#=> 4
  • Заметьте, ‘return’ не необходим
  • также разрешено
class Calculator
  def add(a,b)
    a + b
  end
end

calc = Calculator.new
calc.add(2, 2)
#=> 4

функция внутри класса называется методом

Сообщения и методы

  • на объект ссылаются через переменную или литерал
  • оператор «точка» () отсылает сообщение объекту
  • объект принимает сообщение и вызывает метод
  • если точка не написано, то сообщение принимает объект по умолчанию ()

Цепочки методов

  • Цепочки методов – удобная и мощная особенность Ruby
  • Она зависит от трех возможностей языка:
    • У каждого выражения есть значеие
    • Каждое значение является объектом
    • Итераторы – циклы внутри методов
  • Таким образом, методы можно вызывать для всего, в том числе для результата итератора

Пример

Дана строка:

s = "my dog is sick"

Без применения цепочки методов:

words = s.split
words = words.map{ |word| word.capitalize }
s = words.join(" ")

С применением:

s = "my dog has is sick"
s.split.map{ |word| word.capitalize }.join(" ")

Методы с восклицательным и вопросительным знаками

  • имена методов могут заканчиваться на или
  • значит, что объект вернет boolean-значение
  • означает предостережение, метод, скорее всего, изменяет объект, для которого он вызывается

Идентификаторы

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

Видимость переменных

var   # локальная переменная (или вызов метода)
@var  # instance переменная
@@var # переменная класса
$var  # глобальная переменная
VAR   # константа

и

  • вставляет содержимое запрашиваемого файла в текущий
  • делает методы запрашиваемого файла доступными в текущем
    • игнорирует уже загруженные файлы
    • опускает окончаение
    • также может быть использован для расширений, написанных на языке C (, , и т. п.)

Культура и стандарты

Ruby on Rails — это фреймворк. Зачастую фреймворк не позволяет вам самодеятельность. Конечно же, в Ruby on Rails можно «изобрести свой велосипед» и программировать в любых направлениях, не опираясь на стандарты; но зачастую этого не требуется. Стандарты размещения файлов в проекте, стандарты написания кода в проекте, общие правила программирования в Ruby on Rails сильно структурируют любой проект. За счет этого проект становится читаемым. Вхождение в проект новичков происходит очень быстро. Опыт показывает, что любой новичок в проекте в первый же день работы делает свои первые полезные правки. За счет этого не считается большой проблемой, если разработку проекта изначально вела одна команда программистов, а поддержку проекта или доработку — совершенно другая. Проект на RoR априори понятен любому разработчику.

PGHero — дашборд для мониторинга БД PostgreSQL

Tutorial

Всем привет. Сегодня я бы хотел поделиться рецептом установки утилиты PGHero с подключением нескольких баз данных. PGHero — это простенькая утилита, написанная на Ruby, с минималистичным дашбордом для мониторинга производительности БД PostgreSQL.

Что может показать нам PGHero:

• статистику по запросам: количество вызовов, среднее и суммарное время выполнения (с возможностью хранения истории);

• активные в данный момент запросы;

• информацию о таблицах: занимаемое на диске место, даты последних запусков VACUUM и ANALYSE;

• информацию об индексах: занимаемое на диске место, наличие дублируемых/неиспользуемых индексов. Также может порекомендовать добавить индекс при наличии сложных запросов с Seq Scan;

• статистику по открытым подключениям к БД;

• вывод основных настроек БД, влияющих на производительность (shared_buffers, work_mem, maintenance_work_mem и т.д.)

Зачем изучать Ruby?

1.Вы получаете все удобства (удовольствия) без уловок.

RubysmalltalkJavaPerlPython

  • Исключения. Верите или нет, исключения являются одной из важнейших вещей при разработке программ любого рода. Программисты на PHP4, не знают ничего о них и будут говорить вам, что можно просто печатать(ошибки) на экран или использовать их собственный «супер-пупер» класс для обслуживания ошибок. К счастью для всех нас, Ruby поставляется с try/catch (или еще лучше begin/rescue) блоками и набором предопределенных, расширяемых Исключений, для правильной обработки ошибок.
  • Пространства имен: модули Ruby делают использование пространства имен легким, это должно понравиться энтузиастам C++ и Java.
  • Встроенные регулярные веражения: Для всех знатоков Perl, вы можете заключить нечто в // и оно становится регулярным выражение, готовым для сравнения (для этого используем оператор =~).
  • Перегрузка операторов: Ruby позволяет определять операторы, такие как +, -, >, и т.д. для любого вашего класса.
  • Пакеты: называемые «gems»(камешки), они действительно оправдывают свое название, кроме того — они работают. Пакеты поддерживают зависимости, а еще могут быть как кросс-платформенные, так и платформо-зависимыми.
  • Интерактивная консоль: может использоваться для тестирования кода интерактивно, подобно консоли Python

2.Вы полюбите мелочи.

Ruby

  • Вы можите использовать оба оператора, if и unless в условных выражениях. Кончно же вы можите использовать if с противоположным значением выражения, но использования unless обычно приводит к меньшему числу ошибок. Кроме того, вы можите использовать оба оператора, как условные модификаторы, ставя их после выражения, а не до:
  • Можно использовать знаки вопроса и восклицания в конце имени метода. Данное соглашение не навязывается, но знак «?» используется, когда метод возвращает true или false, в то время, как знак «!» используется для методов, делающих нечто необратимое, на подобии удаления записи из базы данных, отщепления последнего символа из строки и т.п.
  • Можно использовать псевдонимы (alias) для уже созданных методов. Таким образом можно получить методы exist и exists, без накладных расходов и без повторений.
  • Вы можете использовать директивы attr_reader, attr_writer или attr_accessor для автоматического создания getter/setteer для членов класса.
  • И еще некоторое соглашение об именах: константы, классы и модули пишут с заглавной буквы, методы и члены класса должны начинатся с маленькой буквы, глобальные переменные именуют начиная с «$», имена переменных объекта начинаются с «@», а имена переменных класса с «@@», ну и т.д.
  • При вызове методов, можно не писать скобки. Можно писать или просто , что особенно удобно с методами, без аргументов.

6.Можете изменять окружение любым доступным способом.

  • Вы изменяете исходный код класса, если вы имеете к нему доступ. Но обычно это — плохая идея, не делайте так.
  • Вы наследуете свой класс от того и добавляете к нему новый метод. Обычно это — хорошая идея. Но из-за одного метода это может оказаться несколько монрообразным. Кроме того, придется немного подправить другой свой код соответственно.
  • Можно просто создать метод вне класса. Это сработает, но будет не очень изящно, а еще — идет в разрез с ООП.

RubyNumericRuby

Установщики

Если версия Ruby, предоставляемая вашей операционной системой
или пакетным менеджером, не актуальна, то вы можете установить новую версию
при помощи сторонних установщиков. Некоторые из них также позволяют установить
несколько версий Ruby в вашей системе и переключаться между ними. Если вы
планируете использовать как менеджер версий — то вам не нужен
отдельный установщик, он идет со своим.

ruby-build

— это плагин для , который позволяет
вам скомпилировать и установить разные версии Ruby в произвольные каталоги.
ruby-build может использоваться как отдельная программа без rbenv.
Он доступен для macOS, Linux и других UNIX-подобных операционных систем.

ruby-install

позволяет вам скомпилировать и установить
различные версии Ruby в произвольные каталоги. Существует также родственник
, который управляет переключением между версиями Ruby.
Он доступен для macOS, Linux и других UNIX-подобных операционных систем.

RubyInstaller

Для пользователей Windows существует отличный проект, помогающий
установить Ruby: RubyInstaller. Он предоставляет вам все,
что нужно для настройки полноценного окружения Ruby на Windows.

Просто скачайте его, запустите и все готово!

Ruby Stack

Если вы устанавливаете Ruby для того, чтобы воспользоваться Ruby on Rails,
вы можете использовать следующий установщик:

Bitnami Ruby Stack,
которые предоставляет полное окружение для разработки на Rails.
Поддерживает macOS, Linux, Windows, виртуальные машины и облачные сервисы.

Почему Ruby и Ruby on Rails перспективны

Быстрый вход в индустрию. Ruby — один из наиболее простых для изучения языков. Существует множество обучающих ресурсов, а вся нужная информация содержится в open source, поэтому не требует дополнительных трат с вашей стороны — только если понадобится какое-то очень специфичное решение, но это вряд ли случится на начальном этапе.

Качественный вход. На Ruby очень просто изучать объектно-ориентированное программирование. Здесь проще читается код, проще приводятся примеры и проще само понимание кода — для новичка это плюс. В некоторых проектах доходит до того, что вы можете читать без скобок код и понимать, что он выглядит почти как обычный текст, за исключением некоторых уникальных программ, которые пролетают где-то в коде.

Высокая конкурентная мотивация. Я могу судить по Воронежу, где годовалый джуниор-разработчик на Ruby может просить зарплату в районе 90 тыс. руб. в месяц. Это достаточно серьёзные деньги. А на входе можно получать от 30 до 40 тыс. руб.

Если вы будете искать работу, то вы должны понимать, что Ruby on Rails — это комьюнити, где люди привыкли работать в стартапах. В 80% это будут небольшие компании, зарубежные или нет, и в меньшей степени — большие компании. Государственные компании также в последнее время переходят на разработку на Ruby on Rails. Они понимают, что платить джависту или дотнетчику за то, что он будет писать год — это очень дорого. Проще заплатить Ruby-разработчику, который стоит чуть подороже, но напишет решение за 2−3 месяца.

Возможность релокации. Здесь речь идёт о знании английского языка: если знаете английский на разговорном уровне или хотя бы можете переписываться, то ваша цена сразу растёт. Есть компании, которые работают на российский рынок и ограничения у таких русскоязычных компаний где-то в районе 3000 долларов. Если вы выйдете на уровень зарубежных компаний, то зарплата будет варьироваться от 2500 до 5000 долларов в американских компаниях. Поэтому советую как можно скорее начинать учить английский язык.

Читать ещё: «Где лучше всего жить и работать разработчику»

Opensource-головорезы. Open source — это не инхаус-разработка, а разработка на комьюнити: любой человек сможет прийти и оценить ваши наработки, а работодатели и заказчики очень часто требуют показать Github-профиль. Поэтому я советую не только завести аккаунт на Github, но и начать прокачивать его.

О трудностях, которые возникли при входе

Основная проблема — у меня не было знакомых разработчиков, не было наставника. Я примерно полгода изучал HTML и CSS, чтобы дойти до какого-то уровня в разработке. Были простые проекты, но они были маловостребованны для работодателя. В тот момент я не знал, у кого молодому разработчику спросить совета.

Консультанты просили большие деньги за такую информацию. Молодой разработчик платил и чаще всего понимал, что ему не рассказали ничего, чтобы продвинуться в работе. У Нетологии в этом плане есть плюс — у вас будет не один ментор, а целая группа. Можно переключаться и спрашивать, что и как нужно делать — есть возможность получить более объективную информацию и знания у нескольких человек.

Самое трудное в карьере — это выбрать свой язык, свой стек. Когда входил в мир фронтенда, нужно было знать очень много решений и фреймворков, уметь верстать правильно, понимать, какие используются приёмы при вёрстке, хорошо работать со стилями. В то время не было такого многообразия, как сейчас, но тоже было трудно выбрать набор скиллов. Сейчас же очень разросся стек фронтенда и молодым разработчикам всё труднее выбирать.

Я через это прошёл и предлагаю в качестве решения молодым начинающим разработчикам написать одну задачу на разных языках, на разных препроцессорах стилей — так поймете, что вам нравится.

Дальше будет стоять вопрос поиска работы. Для меня самым трудным в первой работе было понять, чего от меня хотят и как мне это сделать. Обычно здесь начинаются первые трудности, когда начинающий разработчик просто не знает, что ему говорить, что учить и что делать.

Когда ищете работу, работодателям важно увидеть ваши знания, портфолио, какой-то бекграунд — подойдут даже сертификаты и дипломные проекты. Первая работа в компании была для меня самой сложной — стало понятно, что предстоит многое выучить, многое попробовать и очень многое прочитать

Первая работа в компании была для меня самой сложной — стало понятно, что предстоит многое выучить, многое попробовать и очень многое прочитать.

Читать ещё: «Найти работу в новой сфере: резюме, поиск контактов, самопрезентация»

Философия языка

Юкихиро Мацумото, создателю языка Ruby принадлежат следующие высказывания:
«Человек создан для творчества, и я всегда знал, что люблю творить. Увы, я обделён талантом художника или музыканта. Зато умею писать программы.»

«Я хочу, чтобы компьютер был моим слугой, а не господином, поэтому я должен уметь быстро и эффективно объяснить ему, что делать.»

Мацумото, фанат объектно-ориентированного программирования, мечтал о языке более мощном, чем Perl, и более объектно-ориентированном, чем Python. Основное назначение Ruby — создание простых и в то же время понятных программ, где важна не скорость работы программы, а малое время разработки, понятность и простота синтаксиса.
Язык следует принципу «наименьшей неожиданности»: программа должна вести себя так, как ожидает программист. Однако в контексте Ruby это означает наименьшее удивление не при знакомстве с языком, а при его основательном изучении. Сам Мацумото утверждает, что целью разработки была минимизация неожиданностей при программировании для него, но после распространения языка он с удивлением узнал, что мышление программистов похоже, и для многих из них принцип «наименьшей неожиданности» совпал с его принципом.

Метапрограммирование в реальной задаче

Из песочницы

Всем привет! В этой статье хочу рассказать про метапрограммирование на примере реальной часто встречающейся проблемы.

Когда кто то говорит про метапрограммирование у олдскульного кодировщика случается приступ ярости)

И на это есть причины так и на большом проекте может показаться безумием использовать метапрограммирование, так как код становится очень сложным для чтения. А если в проект включится специалист со стороны, то он и подавно ничего не разберет в этом мета-коде.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *