Ruby 2.6 acaba de ser lançado!
Com mais performance, JIT, ranges infinitos, método "then" e muito mais!
Desde 2013, os desenvolvedores do Ruby mantém uma tradição de lançar uma nova versão da linguagem
na época do Natal e nesse ano não foi diferente.
Como instalar/atualizar?
Antes de mais nada: sim, já é possível instalar e usar a nova versão!
Para instalar usando os gerenciadores mais populares:
RVM:
bash
# Atualize o RVM:
$ rvm get stable
# Instale o Ruby 2.6:
$ rvm install 2.6.0
rbenv:
bash
# Atualize a lista de versões do Ruby:
$ cd "$(rbenv root)"/plugins/ruby-build && git pull
# Instale o Ruby 2.6:
$ rbenv install 2.6.0
* * *
Vamos então dar uma olhada no que há de novo nessa nova versão!
Melhorias de performance
Essa versão tem algumas melhorias de performance, como:
- O método
Proc#call
está aproximadamente 1.4x mais rápido. - Hashes de vida-útil curta consomem 7% menos memória.
Na RubyConf de 2015, Matz (criador do Ruby) anunciou o Ruby 3x3,
que são os planos para fazer o Ruby 3.0 ficar 3x mais rápido.
Essa versão provavelmente será lançada em 2020.
Uma das estratégias que viabilizará essa grande melhoria de performance é o JIT/MJIT,
que está sendo incluída (como recurso experimental) na versão 2.6, conforme você confere na sessão abaixo:
JIT (Just-in-time)
Uma das funcionalidades mais notáveis da versão 2.6 do Ruby
é que ela vem com uma implementação (experimental) de um compilador JIT (Just-in-time).
Segundo esse artigo do Guy Maliar
(em uma tradução livre):
A idéia por trás de um compilador JIT é "inspencionar" o código em tempo de execução e tentar otimizar de forma mais inteligente o código atualmente em execução, que é o oposto do que acontece em um compilador AOT (Ahead Of Time compiler).
Essa é apenas a implementação inicial e ainda está um pouco instável.
Entretando, benchmarks iniciais mostram resultados muito bons.
O emulador de NES "Optcarrot" rodou ~ 77% mais rápido, se comparado com o Ruby 2.5.3:
Ruby (versão) | FPS (frames por segundo) |
---|---|
2.5.3 | 48.3 |
2.6.0 | 54.5 |
2.6.0 + JIT | 85.7 |
(Fonte)
{: .text-right}
Outros benchmarks mostram resultados ainda mais significativos:
Benchmark | Quanto mais rápido? | Código |
---|---|---|
Mandlebrot | 1.27x | Ver código |
Fibonacci | 3.19x | Ver código |
const /const2 | Quase 4x | Ver código |
Leia mais sobre JIT (e MJIT) neste artigo.
Bundler agora vem com o Ruby
Já faz um tempo que essa discussão começou e agora é oficial:
a gem
bundler
vem por padrão com o Ruby!Quem tiver curiosidade, esse é o Pull Request
com tudo que foi alterado.
Essa mudança é especialmente bem-vinda pelo fato de ajudar iniciantes, já que elimina um passo na instalação do Ruby
(e é com prazer que eu vou ter que regravar já regravei essa aula do meu curso 🙂).
Você pode ler mais sobre essa integração no blog de engenharia da Appfolio.
O método #then
O método
yield_self
foi adicionado no Ruby 2.5.
A novidade agora é que ele ganhou um alias: then
.Considere o seguinte exemplo de código de controller do Rails:
ruby
events = Event.upcoming
events = events.limit(params[:limit]) if params[:limit]
events = events.where(status: params[:status]) if params[:status]
events
Podemos reescrever o código acima usando
yield_self
ou then
(já que o segundo é apenas um alias do primeiro):ruby
Event.upcoming
.yield_self { |events| params[:limit] ? events.limit(params[:limit]) : events }
.yield_self { |events| params[:status] ? events.where(status: params[:status]) : events }
Agora com
then
, que faz o código ficar um pouco mais legível:ruby
Event.upcoming
.then { |events| params[:limit] ? events.limit(params[:limit]) : events }
.then { |events| params[:status] ? events.where(status: params[:status]) : events }
Ranges infinitos
Agora podemos criar ranges sem especificar um valor final.
Isso significa que podemos escrever códigos como:
ruby
array[1..]
# O código acima é identico à `array[1..-1]`
ruby
# Loop infinito que começa com índice 1
(1..).each { |index| ... }
ruby
array.zip(1..) { |elem, index| ... }
# O código acima é identico à `array.each.with_index(1) { }`
Novo método #filter
para arrays (alias para o método #select
)
Nós conhecemos bem o método
select
, mas em outras linguagens
(como JavaScript, Java e PHP), ele é mais conhecido como filter
.
Se você, assim como eu, sempre quis que um alias fosse criado, esse momento chegou:ruby
[:foo, :bar].filter { |x| x == :foo }
# => [:foo]
Métodos #union
e #difference
para arrays
Para quem lembra das aulas de matemática da escola
ou para quem precisa trabalhar com união e diferença entre arrays, tenho uma boa notícia:
Dois métodos (
#union
e #difference
) foram adicionados aos arrays.Eis um exemplo:
ruby
[1, 1, 2, 2, 3, 3, 4, 5].difference([1, 2, 4])
# => [3, 3, 5]
ruby
['a', 'b', 'c'].union(['c', 'd', 'a'])
# => ['a', 'b', 'c', 'd']
ruby
['a'].union([['e', 'b'], ['a', 'c', 'b']])
# => ['a', 'e', 'b', 'c']
Veja também
post oficial
sobre o lançamento da versão 2.6.