Lançado Ruby 3.0.0 Preview 1

Temos o prazer de anunciar o lançamento do Ruby 3.0.0-preview1.

Ele apresenta uma série de novos recursos e melhorias de desempenho.

RBS

RBS é uma linguagem para descrever os tipos de programas Ruby. Os verificadores de tipo, incluindo criador de perfil de tipos e outras ferramentas de suporte ao RBS, compreenderão os programas Ruby muito melhor com as definições do RBS.

Você pode escrever a definição de classes e módulos: métodos definidos na classe, variáveis de instância e seus tipos e relações de herança / mix-in. O objetivo do RBS é oferecer suporte a padrões comumente vistos em programas Ruby e permite escrever tipos avançados, incluindo tipos de união, sobrecarga de método e genéricos. Ele também oferece suporte à duck typing com tipos de interface.

Ruby 3.0 vem com gem rbs, que permite analisar e processar definições de tipo escritas em RBS.

A seguir está um pequeno exemplo de RBS.

module ChatApp
  VERSION: String

  class Channel
    attr_reader name: String
    attr_reader messages: Array[Message]
    attr_reader users: Array[User | Bot]              # `|` significa união de tipos, `User` ou `Bot`.

    def initialize: (String) -> void

    def post: (String, from: User | Bot) -> Message   # Sobrecarga de método é suportada.
            | (File, from: User | Bot) -> Message
  end
end

Veja README da gem rbs para mais detalhes.

Ractor (experimental)

Ractor é uma abstração concorrente semelhante a um modelo de ator, projetada para fornecer um recurso de execução paralela sem preocupações com a segurança do thread.

Você pode fazer vários ractores e executá-los em paralelo. Ractor permite fazer programas paralelos thread-safe porque ractors não podem compartilhar objetos normais. A comunicação entre os ractores é apoiada pela troca de mensagens.

Para limitar o compartilhamento de objetos, o Ractor apresenta várias restrições à sintaxe do Ruby (sem vários Ractors, não há mudanças).

A especificação e implementação não estão amadurecidas e serão alteradas no futuro, portanto, esse recurso é marcado como experimental e mostra o aviso de recurso experimental se um Ractor for criado.

O pequeno programa a seguir calcula prime? em paralelo com dois ractores e cerca de x2 vezes mais rápido com dois ou mais núcleos do que o programa sequencial.

require 'prime'

# n.prime? com inteiros r1 e r2 enviados rodando em parelelo
r1, r2 = *(1..2).map do
  Ractor.new do
    n = Ractor.recv
    n.prime?
  end
end

# envio de parâmetros
r1.send 2**61 - 1
r2.send 2**61 + 15

# aguardando os resultados de expr1, expr2
p r1.take #=> true
p r2.take #=> true

Veja doc/ractor.md para mais detalhes.

Scheduler (Experimental)

Thread#scheduler é introduzido para interceptar operações bloqueantes. Isso permite concorrência leve sem alterar o código existente.

Classes/métodos atualmente suportados:

  • Mutex#lock, Mutex#unlocke Mutex#sleep
  • ConditionVariable#wait
  • Queue#pop e SizedQueue#push
  • Thread#join
  • Kernel#sleep
  • IO#wait, IO#read, IO#write e métodos correlatos (ex.: #wait_readable, #gets, #puts etc.).
  • IO#select não é suportado.

O ponto de entrada atual para concorrência é Fiber.schedule {...} no entanto, está sujeito a alterações no momento em que o Ruby 3 for lançado.

Atualmente, existe um agendador de teste disponível em Async::Scheduler. Veja doc/scheduler.md para mais detalhes. [Feature #16786]

cuidado: Este recurso é fortemente experimental. O nome e o recurso serão alterados na próxima versão de prévia.

Outros novos recursos notáveis

  • A instrução de atribuição para a direita foi adicionada.
  fib(10) => x
  p x #=> 55
  
  • A definição de método sem a keyword end foi adicionada.
  def square(x) = x * x
  
  • Find pattern foi adicionada.
  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
  
  • Hash#except agora é nativo.
  h = { a: 1, b: 2, c: 3 }
  p h.except(:a) #=> {:b=>2, :c=>3}
  
  • A visualização da memória é adicionada como um recurso experimental

    • Este é um novo conjunto C-API para trocar uma área de memória bruta, como uma matriz numérica e uma imagem de bitmap, entre bibliotecas de extensão. As bibliotecas de extensão também podem compartilhar os metadados da área de memória que consiste na forma, no formato do elemento e assim por diante. Usando esses tipos de metadados, as bibliotecas de extensão podem compartilhar até mesmo uma matriz multidimensional de forma adequada. Este recurso é projetado com referência ao protocolo de buffer do Python.

Melhorias de desempenho

  • Muitas melhorias foram implementadas no MJIT. Veja NEWS em detalhes.

Outras mudanças notáveis desde 2.7

  • Os argumentos de palavra-chave são separados de outros argumentos.
    • Em princípio, códigos que imprimem um aviso no Ruby 2.7 não funciona. Veja o documento em detalhe.
    • A propósito, o encaminhamento de argumentos agora suporta argumentos principais.
    def method_missing(meth, ...)
      send(:"do_#{ meth }", ...)
    end
    
  • O recurso de $SAFE foi completamente removido; agora é uma variável global normal.

  • A ordem de backtrace foi revertida em Ruby 2.5, mas foi cancelada. Agora ele se comporta como Ruby 2.4; uma mensagem de erro e o número da linha onde ocorre a exceção são impressos primeiro e seus chamadores são impressos posteriormente.

  • Algumas bibliotecas padrão são atualizadas.
    • RubyGems 3.2.0.rc.1
    • Bundler 2.2.0.rc.1
    • IRB 1.2.6
    • Reline 0.1.5
  • As seguintes bibliotecas não são mais gem padrão. Instale as gems correspondentes para usar esses recursos.
    • net-telnet
    • xmlrpc
  • Promove gems padrão para gems nativas.
    • rexml
    • rss
  • Promova stdlib para gem padrão. As seguintes gems padrão foram publicadas em rubygems.org
    • abbrev
    • base64
    • English
    • erb
    • find
    • io-nonblock
    • io-wait
    • net-ftp
    • net-http
    • net-imap
    • net-protocol
    • nkf
    • open-uri
    • optparse
    • resolv
    • resolv-replace
    • rinda
    • securerandom
    • set
    • shellwords
    • tempfile
    • time
    • tmpdir
    • tsort
    • weakref

Veja NEWS ou commit logs para mais detalhes.

Com essas mudanças, 3385 arquivos alterados, 150159 inserções(+), 124949 deleções(-) desde Ruby 2.7.0!

Por favor, experimente Ruby 3.0.0-preview1 e nos dê qualquer feedback!

Download

  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview1.tar.bz2

    SIZE: 15538340
    SHA1: 032697f3ace0a697cd72f68bac0032c31a8328d4
    SHA256: 013bdc6e859d76d67a6fcd990d401ed57e6e25896bab96d1d0648a877f556dbb
    SHA512: 3a6a6458d9c5f06555ab8705160f6b071f4dbe9d2a91cd7848852633657b495c480d74e4b2ff2cebddda556118d26bbb271160c989bc970bb1b5cb234e868d2f
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview1.tar.gz

    SIZE: 17747808
    SHA1: 2842d2af2568d74c8d4071f5f536889a6b149202
    SHA256: ce8bd7534e7ec2a870b24d2145ea20e9bbe5b2d76b7dfa1102dbee5785253105
    SHA512: b94892951f842a1538f4b99022606ac2c0b5031f1ede7eef3833a8caa9ed63e9b22868509173bfefb406f263c65211db75597b152b61f49e5ba2a875fce63a27
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview1.tar.xz

    SIZE: 12703060
    SHA1: 91d9fbe87504924148deeec90199d6ff4d7dcf56
    SHA256: aa7cce0c99f4ea2145fef9b78d74a44857754396790cd23bad75d759811e7a2a
    SHA512: dca5dcc965c434371947c100864090e29e649e19ae24b8bb2e88a534ebd8220c5a086035a999b1e8b1cd5ec154a6985a8d8dfea56095d712d62aeea7a2054f7d
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview1.zip

    SIZE: 22002645
    SHA1: 4b5b61066373daf0a947d3fafe2645788504a164
    SHA256: a39a48ed9a8ca2c83d65d225a1bb3db331c6587a77ba156c20e630c1b4bfc23b
    SHA512: 10f6f28715a52093d7d9da82d1678147091b45e2f279e463626adea8efbf181485daa42565e5086057ffb45a097ffb8ff395c572b247b6b5da27d85933cf58a8
    

Trailer de 3.0.0-preview2

Planejamos incluir “type-profiler” que é um recurso de análise de tipo estático. Fique ligado!

O que é Ruby

Ruby foi desenvolvido pela primeira vez por Matz (Yukihiro Matsumoto) em 1993, e agora é desenvolvido como Open Source. Ele roda em várias plataformas e é usado em todo o mundo, especialmente para desenvolvimento web.