Lucas Caton

Ruby 2.6 acaba de ser lançado!

Por Lucas Caton

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.

Ruby 2.6

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.348.3
2.6.054.5
2.6.0 + JIT85.7

(Fonte) {: .text-right}

Outros benchmarks mostram resultados ainda mais significativos:

BenchmarkQuanto mais rápido?Código
Mandlebrot1.27xVer código
Fibonacci3.19xVer código
const/const2Quase 4xVer código

Leia mais sobre JIT (e MJIT) neste artigo.

Bundler agora vem com o Ruby

Bundler

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.

Tags: