Linguagem Ruby: entendendo a magia dos métodos

Linguagem Ruby: entendendo a magia dos métodos

Publicado em: 20/4/2016

Entra ano e sai ano e a linguagem Ruby lança um novo release no Natal.

Em 2019 saiu o release 2.7 e trouxe inúmeras atualizações de performance que você certamente gostará de aplicar em suas aplicações.

A grande questão é: será que você terá muitos problemas para aplicar essa nova atualização?

Nas atualizações anteriores você teve problemas?

Baseado nas atualizações da linguagem Ruby 2.7, vamos ver como tornar nossos métodos safe para funcionar em versões anteriores e futuras!

Se quiser saber quais as razões para programar em Ruby, só ler esse artigo!

Formas de assinaturas da linguagem Ruby

Basicamente quando criamos um método temos cinco tipos de assinaturas possíveis.

1. Não passar parâmetros.

2. Passar parâmetros posicionais.

3. Passar parâmetros com palavras-chaves (keywords arguments).

4. Passar parâmetros como array.

5. Passando um bloco.

Somos capazes de mesclar essas formas e então gerar “novas” formas mescladas, mas basicamente essas são as formas básicas de passar parâmetros.

No nosso dia a dia programando, iremos nos deparar com as formas puras e mescladas.

Vamos a alguns exemplos abaixo…

def method_without_params
end

def method_with_posicional_params(my_param)

def method_with_named_key_argument(key:)
end

def method_with_array_argument(*array)
end

def method_with_key_argument(**kw)
end

def method_with_block(&block)
end

Você pode perceber nos exemplos acima que temos dois tratando de keywords são so metodos method_with_named_key_argument e method_with_key_argument.

A diferença entre eles é que o method_with_named_key_argument recebe um único parametro e ele já vem nomeado para usar ele.

Basicamente você fará o seguinte:

method_with_named_key_argument(key: ‘my key’)

E para usar o parâmetro você chamará o key como sendo o parâmetro, ficando:

def method_with_named_key_argument(key:)
  p key
end

method_with_named_key_argument(key: ‘my key’)
=> "my key"

Já com o método method_with_key_argument, você passa um keywords sem nomear.

Basicamente, para chamar o método você vai fazer a mesma coisa que fez para chamar o outro método:

method_with_key_argument(key: ‘my key’)

Porém, para usar o parâmetro, você vai ter que passar a key dele, desta forma:

def method_with_key_argument(**kw)
  p kw[:key]
end

method_with_key_argument(key: ‘my key’)
=> "my key"

Se você usar apenas o parâmetro sem passar a key então você irá trabalhar com o hash que foi passado, desta forma:

def method_with_key_argument(**kw)
  p kw
end

method_with_key_argument(key: ‘my key’)
=> {:key=>"my key"}

Assinaturas mescladas

A brincadeira das mesclas não tem limites!

Lembra que falei das assinaturas mescladas?

def method_with_posicional_and_named_key_argument(posicional, named_key:)
end

def method_with_posicional_and_array(posicional, *array)

def method_with_array_and_key_argument(*array, **kw)
end

def method_with_named_key_and_array(key:, *array)
end

def method_with_all_kinds(positional, *array, **kw, &block)
end

Porém, tudo o que acontece dentro deles são mágicas da linguagem Ruby para facilitar ou destruir a nossa vida, depende de como você vai usar isso…

Entendendo a mágica da linguagem Ruby

Os keywords arguments na linguagem Ruby foram introduzidos na versão 2.0.

Não sei se você conseguiu notar no exemplo acima, mas a forma de nomear as keyword no método apenas faz com que você possa chamar o valor de um hash e sua key apenas através da key.

Sendo que quando você passa key: ‘value’ você está passando um hash que tem uma key chamada key e que corresponde a value.

Sendo assim o método method_with_named_key_argument poderia ser usado das seguintes maneiras:

method_with_named_key_argument(key: ‘value’)
method_with_named_key_argument({ key: ‘value’ })

Uma usando os {} para deixar explicito que é um hash e a outra sem deixar.

Mudanças na linguagem Ruby 2.7

Na versão 2.7 da linguagem Ruby, essa mágica de conversão automática de keywords entrou em deprecated e vai ser removida no Ruby 3.

Então, a partir da atualização para a nova versão, você vai começar a receber alguns warmings informando que aquele método que você está utilizando irá quebrar na próxima atualização.

Maravilha, então você pode atualizar sem problemas que não vai quebrar seu código ainda…

Como deixar os meu método safe para atualizações

Porém, a grande pergunta é: atualizei e agora? Como deixar os meus métodos safe para não ter problemas no futuro?

Primeiro, temos que saber quais os tipos de métodos irão gerar erros, vamos a eles.

Pegando os exemplos anteriores de métodos com keywords, os seguintes darão mensagens de warnings se forem usados da seguinte maneira:

method_with_named_key_argument({ key: 42 }) # usando {}
method_with_key_argument({ key: 42 }) # usando {}

Para evitar o warming, nessas duas chamadas basta remover o {} e sucesso!

Porém, começa a ficar um pouco mais complicado se você usar uma assinatura mesclada, por exemplo:

def method_with_posicional_and_named_key_argument(posicional={}, key:)
end

Nesse exemplo acima iremos usar o posicional como um hash, dessa forma…

method_with_posicional_and_named_key_argument("key" => ’posicional’, key: ‘keyword’) # passando tudo sem `{}`

method_with_posicional_and_named_key_argument({"key" => ’posicional’, key: ‘keyword’}) # passando tudo dentro um único `{}`

method_with_posicional_and_named_key_argument({"key" => 'posicional'}, {key: 'keyword'}) # passando tudo entre `{}` porém separadamente

Perceba que o só de olhar, já da um nó mental porque tem dois keys dentro da assinatura.

Apesar disso, a linguagem Ruby não se perde nessa versão e faz a mágica acontecer com o warming.

Para resolver isso nesse caso você teria que fazer assim:

method_with_posicional_and_named_key_argument({"key" => 'posicional'}, key: 'keyword')

Vale a pena?

assinaturas na linguagem ruby
Se você reparar, nenhuma assinatura mudou.

O que mudou é a forma como iremos chamar os nossos métodos, a forma como passamos os parâmetros.

A orientação da mudança deixa claro que podemos usar as três formas seguintes para keywords:

def my_final_method(k: 'default')
end

def my_final_method(k:)
end

def my_final_method(**kwargs)
end

Se você gostou e quer ver os exemplos de Ruby na prática, veja o vídeo.

Quer ver outras novidades da linguagem Ruby 2.7?

O que achou das alterações? Gostou? Ficou com alguma dúvida? Quer sugerir algo? Deixe nos comentários!

Publicado originalmente em Geek Hunter