Выпуск языка программирования Ruby 2.7.0
25 декабря 2019 года
После года разработки опубликован релиз Ruby 2.7.0, динамического объектно-ориентированного языка программирования, отличающегося высокой эффективностью разработки программ и вобравшего в себя лучшие черты Perl, Java, Python, Smalltalk, Eiffel, Ada и Lisp. Код проекта распространяется под лицензиями BSD ("2-clause BSDL") и "Ruby", которая ссылается на последний вариант лицензии GPL и полностью совместима с GPLv3. Ruby 2.7 является седьмым значительным выпуском, подготовленным в рамках планового процесса разработки, подразумевающего отведение года на подготовку функциональных улучшений и формирование каждые 2-3 месяца корректирующих выпусков.
Основные улучшения:
- Экспериментальная поддержка сопоставлений с образцом ( Pattern matching), позволяющих перебрать заданный объект и назначить значение, если имеется совпадение с образцом.
case [0, [1, 2, 3]] in [a, [b, *c]] p a #= 0 p b #= 1 p c #= [2, 3] end case {a: 0, b: 1} in {a: 0, x: 1} :unreachable in {a: 0, b: var} p var #= 1 end
- В оболочке интерактивных вычислений irb (REPL, Read-Eval-Print-Loop) появилась возможность многострочного редактирования, реализованная при помощи readline-совместимой библиотеки reline, написанной на языке Ruby. Интегрирована поддержка rdoc, позволяющая просматривать в irb справочную информацию по заданным классам, модулям и методам. Обеспечена цветная подсветка строк с кодом, показываемых через Binding#irb и результатов инспектирования объектов базовых классов.
- Добавлен уплотняющий сборщик мусора (Compaction GC), который может выполнять дефрагментацию области памяти, решая проблемы снижения производительности и повышения потребления памяти из-за фрагментации памяти, возникающей в процессе работы некоторых многопоточных Ruby-приложений. Для упаковки объектов в куче предложен метод GC.compact, позволяющий снизить число используемых страниц памяти и оптимизировать кучу для операций
CoW (copy-on-write).
- Проведена подготовка к разделению аргументов, определяемых на основе позиции в списке ("def foo(a,b,c)") и ключевых слов ("def foo(key: val)"). Автоматическое преобразование аргументов на основе ключевых слов и позиции объявлено устаревшим и не будет поддерживаться в ветке Ruby 3.0. В частности, объявлено устаревшим использование последнего аргумента как параметров ключевого слова, передача аргументов на основе ключевых слов как последнего параметра хеша и разделение последнего аргумента на позиционные и ключевые параметры.
def foo(key: 42); end; foo({key: 42}) # warned def foo(**kw); end; foo({key: 42}) # warned def foo(key: 42); end; foo(**{key: 42}) # OK def foo(**kw); end; foo(**{key: 42}) # OK def foo(h, **kw); end; foo(key: 42) # warned def foo(h, key: 42); end; foo(key: 42) # warned def foo(h, **kw); end; foo({key: 42}) # OK def foo(h, key: 42); end; foo({key: 42}) # OK def foo(h={}, key: 42); end; foo("key" = 43, key: 42) # warned def foo(h={}, key: 42); end; foo({"key" = 43, key: 42}) # warned def foo(h={}, key: 42); end; foo({"key" = 43}, key: 42) # OK def foo(opt={}); end; foo( key: 42 ) # OK def foo(h, **nil); end; foo(key: 1) # ArgumentError def foo(h, **nil); end; foo(**{key: 1}) # ArgumentError def foo(h, **nil); end; foo("str" = 1) # ArgumentError def foo(h, **nil); end; foo({key: 1}) # OK def foo(h, **nil); end; foo({"str" = 1}) # OK h = {}; def foo(*a) a end; foo(**h) # [] h = {}; def foo(a) a end; foo(**h) # {} and warning h = {}; def foo(*a) a end; foo(h) # [{}] h = {}; def foo(a) a end; foo(h) # {}
- Возможность использования нумерованных имён переменных по умолчанию для параметров блока.
[1, 2, 3].each { puts @1 } # как аналог [1, 2, 3].each { |i| puts i }
- Экспериментальная поддержка диапазонов без начального значения.
ary[..3] # аналогично ary[0..3] rel.where(sales: ..100)
- Добавлен метод Enumerable#tally, подсчитывающий сколько раз встречается каждый элемент.
["a", "b", "c", "b"].tally #= {"a"=1, "b"=2, "c"=1}
- Разрешён вызов приватного метода с литералом "self"
def foo end private :foo self.foo
- Добавлен метод Enumerator::Lazy#eager для генерации обычного перечисления из "ленивого" (Enumerator::Lazy) перечисления.
a = %w(foo bar baz) e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.eager p e.class #= Enumerator p e.map {|x| x + "?" } #= ["FOO!?", "BAR!?", "BAZ!?"]
- Продолжено развитие экспериментального JIT-компилятора, который позволяет ощутимо поднять производительность приложений на языке Ruby. Предложенный в Ruby JIT-компилятор вначале записывает на диск код на языке Си, после чего вызывает внешний Си-компилятор для генерации машинных инструкций (поддерживается вызов GCC, Clang и Microsoft VC++). В новой версии реализован метод для inline-развёртывания при необходимости, обеспечено выборочное применение режимов оптимизации при компиляции, значение по умолчанию "--jit-min-calls" увеличено с 5 до 10000, а "--jit-max-cache" уменьшено с 1000 до 100.
- Повышена производительность CGI.escapeHTML, Monitor и MonitorMixin.
- В Module#name, true.to_s, false.to_s и nil.to_s обеспечен возврат строки, неизменной для указанного объекта.
- Сокращён размер бинарных файлов, генерируемых методом RubyVM::InstructionSequence#to_binary;
- Обновлены версии встроенных компонентов, включая
Bundler 2.1.2, RubyGems 3.1.2, Racc 1.4.15, CSV 3.1.2, REXML 3.2.3, RSS 0.2.8, StringScanner 1.0.3;
- Из базовой поставки во внешние gem-пакеты вынесены библиотеки
CMath (cmath gem), Scanf (scanf gem), Shell (shell gem), Synchronizer (sync gem), ThreadsWait (thwait gem), E2MM (e2mmap gem).
- На rubygems.org опубликованы поставляемые по умолчанию модули stdlib:
benchmark, cgi, delegate, getoptlong, net-pop, net-smtp, open3, pstore, singleton. Не перенесены в rubygems.org модули monitor observer, timeout, tracer, uri, yaml, которые поставляются только в ruby-core.
- Для сборки Ruby теперь требуется Си-компилятор, поддерживающий стандарт C99.
Источники
править
Любой участник может оформить статью: добавить иллюстрации, викифицировать, заполнить шаблоны и добавить категории.
Любой редактор может снять этот шаблон после оформления и проверки.
Комментарии
Если вы хотите сообщить о проблеме в статье (например, фактическая ошибка и т. д.), пожалуйста, используйте обычную страницу обсуждения.
Комментарии на этой странице могут не соответствовать политике нейтральной точки зрения, однако, пожалуйста, придерживайтесь темы и попытайтесь избежать брани, оскорбительных или подстрекательных комментариев. Попробуйте написать такие комментарии, которые заставят задуматься, будут проницательными или спорными. Цивилизованная дискуссия и вежливый спор делают страницу комментариев дружелюбным местом. Пожалуйста, подумайте об этом.
Несколько советов по оформлению реплик:
- Новые темы начинайте, пожалуйста, снизу.
- Используйте символ звёздочки «*» в начале строки для начала новой темы. Далее пишите свой текст.
- Для ответа в начале строки укажите на одну звёздочку больше, чем в предыдущей реплике.
- Пожалуйста, подписывайте все свои сообщения, используя четыре тильды (~~~~). При предварительном просмотре и сохранении они будут автоматически заменены на ваше имя и дату.
Обращаем ваше внимание, что комментарии не предназначены для размещения ссылок на внешние ресурсы не по теме статьи, которые могут быть удалены или скрыты любым участником. Тем не менее, на странице комментариев вы можете сообщить о статьях в СМИ, которые ссылаются на эту заметку, а также о её обсуждении на сторонних ресурсах.