Novidades do Ruby 3

Novidades do Ruby 3

Publicado em: 20/4/2016

Esse ano maluco que estamos vivendo atrasou tudo e o tão aguardado preview 1 do Ruby que normalmente sai em abril foi liberado agora em setembro. Recheado de novidades o novo Ruby 3.0 e com uma promessa feita em 2016 de aumentar a performance do Ruby em em três vezes comparado com a versão 2.0

Sem mais delongas vamos a eles:

RBS

Não vou me aprofundar muito no RBS porque ele merece um post exclusivo, mas sendo bem resumido já que não tem como não falar dele que é a maior atração do Ruby 3 o RBS seria um "Ruby Tipado". Muito parecido com o que o Typescript se propõe a fazer com o Javascript, mas com toda a elegância que só o Ruby tem.

Eu acredito que o RBS vai ser aquele que ajudará e muito na promessa do Ruby 3x3, mas ainda não fiz e não vi nenhum teste de benchmark usando ele então vou aguardar até fazer ou ver algum teste nesse sentido para incluir no próximo artigo que será só sobre o RBS.

Ractor

Uma feature experimental que promete bastante e também irá influênciar bastante na performance do novo Ruby é o Ractor. Ele é uma abstração concorrente no estilo "Actor-model" (não me lembro de uma tradução melhor para isso).

Importante ficar esperto com o uso do Ractor porque ele foi construido sem os se preocupar com thread-safe. Se você quiser usar eles com thread-safe você pode porque eles não compartilham objetos normais e podem se comunicar através de mensagens.

Outro ponto importante que por ser experimental sempre que você utilizar ele, teremos um warming sempre que um objeto Ractor for criado.

Baseado no exemplo do que veio no próprio release fiz alguns ajustes para testarmos o benchmark desse cara:

require 'prime'
require 'benchmark'

time = Benchmark.realtime do
  r1, r2, r3 = *(1..3).map do
    Ractor.new do
      n = Ractor.recv
      n.prime?
    end
  end

  r1.send 2**61 - 1
  r2.send 2**61 + 15
  r3.send 2**61 + 20

  p r1.take
  p r2.take
  p r3.take
end

p "Time with raptor - #{time}"

time = Benchmark.realtime do
  p (2**61 - 1).prime?
  p (2**61 + 15).prime?
  p (2**61 + 20).prime?
end

p "Time without raptor - #{time}"

Endless functions

Esse é um ponto que muito me incomodava. No ruby costumamos usar guards para escrever menos linhas e deixar o código mais bonito, mas nas funções sempre eramos obrigados a ter no mínimo três linhas uma com a assinatura, uma com o código e uma com o end.

Com essa nova feature seremos capazes de criar funções com apenas uma linhas desse jeito:

def square(x) = x * x

p square(5) #=> 25

Isso é lindo principalmente para métodos boleanos onde só é feito um if para retornar um true ou false. Importante saber que mesmo que a função não receba parametros ela precisa do () (só descobri isso no live coding que está ao final do post)

Find pattern

Se você ficou feliz com o Pattern Matching do Ruby 2.7 com certeza vai gostar do Find Pattern. Ele te ajuda a encontrar padrões em arrays. Como no exemplo abaixo:

case ["a", 1, "b", "c", 2, "d", "e", "f", 3]
in [*pre, String => x, String => y, *post]
  p pre  #=> ["a", 1]
  p x    #=> "b"
  p y    #=> "c"
  p post #=> [2, "d", "e", "f", 3]
end

Você pode ver que o padrão definido que queriamos buscar é o Array, String, String, Array. Dentro desse padrão conseguimos pegar o valores que casam com o padrão que definimos. No item um pegamos tudo o que tem no array até encontrar duas strings seguidas, esse valor atribuimos a váriavel pre, as duas strings seguintes atribuimos a x e y na ordem do array e o restante do array atribuimos a post.

Hash#expect

Quantas vezes você já não quis remover um item de um hash? Eu já precisei fazer isso algumas vezes e com o método expect ficou muito mais fácil, basta chamar o expect no seu hash passando a key que deseja ignorar.

my_hash = { key1: 1, key2: 2, key3: 3 }
p my_hash.except(:key1) #=> {:b=>2, :c=>3}

MJIT

Tivemos alguns improves no MJIT, mas nenhum deles que seja tão simples e visual de testar.

Se você quer fazer o seu teste na sua máquina você pode utilizar esse repositório docker que criei para disponibilizar a imagem do Ruby 3.0 preview1.

Live Coding

Também te convido a ver o meu teste no vídeo abaixo rodando isso em clássico live coding sem cortes. Inclusive falo exclusivamente no video sobre o Rightward assignment statement e como não entendi o que ele faz ainda.

E ae gostou das mudanças? Sentiu falta de alguma coisa? Fica a vontade nos comentários abaixo para mandar dúvidas críticas e sugestões.