No começo do ano passado escrevi sobre o Ruby 2.6 e o tão esperado JIT, que foi lançado no último natal depois de um longo ano de espera.

Cerca de um mês depois, já temos o primeiro release para corrigir bugs dessa nova versão. Vou falar sobre dois fixes que acredito ser os que mais podem nos afetar no dia a dia.

Sequência no loop infinito

No Ruby 2.6 foi adicionado uma nova notação para o fazer o loop infinito. Ex.:

# Ruby 2.5
(1..Float::INFINITY).first(10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Ruby 2.6
(1..).first(10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

O problema estava quando você colocava usava o método step que iria direcionar a sequência:

# Ruby 2.5
(1..Float::INFINITY).step(1).first(10)
=> [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
# Ruby 2.6
(1..).step(1).first(10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Na versão 2.5, ele transformava o retorno em float. Na nova versão, ele retornava integer.

O problema estava justamente aí: o Range#each e o Range#step deveriam ter retornos diferentes, mas estavam retornando a mesma coisa. Consulte o código da correção aqui.

Constante definidas em módulos

No Ruby podemos criar módulos e importá-los em classes da seguinte maneira:

module M
end

class C
 include M
end

Isso funciona normalmente, inclusive para importar métodos e constantes:

module M

 MY_CONSTANT = ‘my constant’
 def my_method
   puts ‘my method’

 end
end

class C
 include M
end

Dessa forma, a constante e o método definidos no módulo são acessíveis na classe C.

O erro está no método `const_defined?`. Ele é responsável por verificar se uma constante está definida. Por exemplo:

Object.const_defined?("M::MY_CONSTANT")
=> true

No exemplo acima, estamos verificando se a constante `MY_CONSTANT` está definida no módulo M. O retorno é `true`, pois ela está definida. O problema se dava no momento que tentava fazer o mesmo na classe C que dá um include no M.

Object.const_defined?("C::MY_CONSTANT")
=> false

Nessa correção, ao fazer essa mesma chamada a resposta é `true`, porque através do include a constante `MY_CONSTANT` do módulo M passa a ser definida na classe C. Consulte o código da correção aqui.

Esses foram alguns dos bugs encontrados na primeira release do Ruby 2.6. 

Você já tinha se deparado com alguns deles? Conseguiu resolver? Se sim como fez? Compartilhe conosco nos comentários!

Exibir ComentáriosOcultar Comentários

Faça um comentário