Embora o Ruby 3 tenha introduzido o Pattern Matching com o objetivo de manipular estruturas de dados de forma mais expressiva, passei a utilizar esse recurso para realizar checagens de tipos em tempo de execução, como um “hack” elegante. Vamos explorar como isso pode ser aplicada para validar tipos primitivos e um tipo personalizado.

Há uns dias atrás eu publiquei este insight no Mastodon e ví que a galera interagiu bem, então decidi compartilhar um pouco mais sobre essa técnica.

Checando um Tipo Básico

Suponha que você queira verificar se uma variável é uma String. Com o Pattern Matching, você pode fazer isso de uma maneira bem direta:

def check_string(value)
  value => String
  "É uma string válida!"
rescue
  "Tipo inválido, esperava uma string."
end

Nesse método, se value não for uma String, o Ruby interromperá a execução e passará para o bloco rescue.

Checando um tipo Personalizados

Agora, digamos que você criou uma classe chamada Vehicle e quer garantir que um objeto pertença a essa classe:

class Vehicle
  attr_accessor :make, :model

  def initialize(make, model)
    @make = make
    @model = model
  end
end

def check_vehicle(obj)
  obj => Vehicle
  "É um veículo válido!"
rescue
  "Tipo inválido, esperava um veículo."
end

Se obj não for uma instância de Vehicle, o método lançará uma exceção capturada pelo rescue, informando que o tipo é inválido.

Conclusão

Apesar de não ser a intenção original do Pattern Matching, essa técnica de checagem de tipos pode ser uma solução elegante, fácil e descritiva para checar um tipo em Ruby. Ela permite uma forma de assegurar que os objetos sejam do tipo correto, reduzindo a chance de erros inesperados em tempo de execução. Entretanto, é importante lembrar que essa é uma adaptação e menos eficiente se comparado à:

obj.is_a?(Vehicle)

Vale resaltar também que existem gems especializadas para validação de tipos pode ser mais adequado para aplicações críticas. Experimente com moderação e sempre considere as convenções e boas práticas da comunidade Ruby.