O que é um método em Ruby (e por que ele melhora seu código)
Métodos são blocos de código nomeados que você pode chamar sempre que precisar repetir uma ação. Eles ajudam a reduzir duplicação, organizar regras de negócio e deixar a intenção do código mais clara.
Em Ruby, um método é definido com def e finalizado com end. Você pode (e deve) escolher nomes que descrevam a ação: calcular_total, formatar_nome, validar_email.
Definição básica com def/end
def saudacao(nome)
"Olá, #{nome}!"
end
puts saudacao("Ana")O método acima recebe um parâmetro (nome) e devolve uma string.
Retorno: implícito, explícito e early return
Retorno implícito (o padrão em Ruby)
Em Ruby, o valor retornado por um método é, por padrão, o resultado da última expressão avaliada.
def dobro(n)
n * 2
end
puts dobro(10) # 20Não há return aqui, mas o método retorna n * 2.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
Retorno explícito com return
Você pode usar return para deixar explícito o que está sendo devolvido, mas não é obrigatório.
def dobro(n)
return n * 2
endEarly return (retorno antecipado)
O return é especialmente útil para “sair cedo” quando uma condição invalida o processamento, evitando aninhamentos e deixando o fluxo mais legível.
def preco_final(preco, cupom)
return preco if cupom.nil?
if cupom == "DESC10"
preco * 0.9
else
preco
end
endNote como o return preco if cupom.nil? evita um if maior envolvendo todo o método.
Parâmetros posicionais (ordem importa)
Parâmetros posicionais são recebidos na ordem em que você passa os argumentos na chamada do método.
def intervalo(inicio, fim)
(inicio..fim).to_a
end
p intervalo(3, 6) # [3, 4, 5, 6]Se você inverter os argumentos, o resultado muda. Por isso, quando a ordem pode confundir, considere argumentos nomeados (keyword arguments), que veremos adiante.
Valores padrão (default values)
Você pode definir valores padrão para parâmetros, tornando a chamada mais simples quando o valor “comum” é conhecido.
def saudacao(nome, prefixo = "Olá")
"#{prefixo}, #{nome}!"
end
puts saudacao("Ana")
puts saudacao("Ana", "Bem-vinda")O valor padrão só é usado quando o argumento não é fornecido.
Passo a passo: evoluindo um método com valor padrão
Imagine que você tem um método que formata um preço:
def formatar_preco(valor)
"R$ #{'%.2f' % valor}"
endAgora surge a necessidade de permitir outra moeda, mas a maioria dos casos continua sendo “R$”. Refatoração com valor padrão:
def formatar_preco(valor, moeda = "R$")
"#{moeda} #{'%.2f' % valor}"
end
puts formatar_preco(12.5) # R$ 12.50
puts formatar_preco(12.5, "US$") # US$ 12.50Splat (*args): recebendo quantidade variável de argumentos
O splat (*) permite capturar vários argumentos posicionais em um array. Isso é útil quando a quantidade de itens varia.
def soma(*numeros)
numeros.sum
end
puts soma(1, 2, 3) # 6
puts soma(10) # 10
puts soma() # 0Dentro do método, numeros é um array.
Combinando parâmetros fixos e *args
def registrar_evento(tipo, *detalhes)
"tipo=#{tipo} detalhes=#{detalhes.inspect}"
end
puts registrar_evento("login", "user_id=10", "ip=1.2.3.4")Aqui, tipo é obrigatório e o restante vai para detalhes.
Keyword arguments (argumentos nomeados)
Argumentos nomeados permitem passar valores por nome, deixando a chamada mais legível e menos dependente de ordem.
def criar_usuario(nome:, email:)
{ nome: nome, email: email }
end
p criar_usuario(nome: "Ana", email: "ana@exemplo.com")Os dois parâmetros acima são obrigatórios porque não têm valor padrão.
Keyword arguments com valores padrão
def criar_usuario(nome:, email:, admin: false)
{ nome: nome, email: email, admin: admin }
end
p criar_usuario(nome: "Ana", email: "ana@exemplo.com")
p criar_usuario(nome: "Bia", email: "bia@exemplo.com", admin: true)Isso evita chamadas confusas como criar_usuario("Ana", "ana@...", false), onde o false não diz nada sozinho.
Double splat (**kwargs): capturando keywords extras
O double splat (**) captura argumentos nomeados extras em um hash. É útil quando você quer aceitar opções adicionais sem listar todas.
def log_evento(evento, **dados)
{ evento: evento, dados: dados }
end
p log_evento("compra", user_id: 10, total: 59.9, cupom: "DESC10")Dentro do método, dados é um hash com as chaves extras.
Encaminhando keywords com **kwargs (padrão comum em refatorações)
Quando você cria um método “casca” que chama outro, **kwargs ajuda a repassar opções sem perder nada.
def enviar_email(to:, subject:, **opcoes)
{ to: to, subject: subject, opcoes: opcoes }
end
def notificar_boas_vindas(email:, **opcoes)
enviar_email(to: email, subject: "Bem-vindo!", **opcoes)
end
p notificar_boas_vindas(email: "ana@exemplo.com", cc: "suporte@exemplo.com")O método notificar_boas_vindas fixa parte dos parâmetros e repassa o restante.
Escopo de variáveis: o que existe dentro e fora do método
Um ponto essencial: variáveis definidas dentro de um método não “vazam” para fora. E variáveis locais de fora não são acessíveis dentro do método (a menos que sejam passadas como argumento).
Variáveis locais dentro do método
def exemplo
x = 10
x * 2
end
exemplo
# puts x # erro: x não existe aquiPassando valores para o método (forma correta)
taxa = 0.1
def aplicar_taxa(valor, taxa)
valor * (1 + taxa)
end
puts aplicar_taxa(100, taxa)Se você tentar usar taxa diretamente dentro do método sem passar, não vai funcionar, porque o método tem seu próprio escopo.
Parâmetros são variáveis locais do método
Os parâmetros (valor, taxa) são variáveis locais criadas no escopo do método. Alterá-las não altera variáveis externas (você está trabalhando com referências/objetos, mas o “nome” da variável é local).
Refatorações guiadas: extraindo métodos para reduzir duplicação
Extrair métodos é uma das refatorações mais comuns: você pega um trecho repetido, dá um nome para ele e passa as diferenças como parâmetros. O objetivo é reduzir duplicação e aumentar legibilidade.
Exemplo 1: duplicação ao aplicar desconto
Suponha um código que calcula total para dois tipos de pedido, repetindo regra de desconto:
itens = [19.9, 5.0, 12.0]
total = itens.sum
if total >= 50
total = total * 0.9
end
puts "Total A: #{'%.2f' % total}"
itens_b = [100.0, 25.0]
total_b = itens_b.sum
if total_b >= 50
total_b = total_b * 0.9
end
puts "Total B: #{'%.2f' % total_b}"Passo a passo da extração
- Passo 1: identifique o trecho repetido (calcular soma + aplicar desconto).
- Passo 2: crie um método com um nome que descreva a intenção.
- Passo 3: transforme o que muda em parâmetro (a lista de itens e a regra/limite, se necessário).
def total_com_desconto(itens, limite: 50, percentual: 0.1)
total = itens.sum
return total if total < limite
total * (1 - percentual)
end
puts "Total A: #{'%.2f' % total_com_desconto([19.9, 5.0, 12.0])}"
puts "Total B: #{'%.2f' % total_com_desconto([100.0, 25.0])}"
puts "Total C: #{'%.2f' % total_com_desconto([100.0], limite: 80, percentual: 0.2)}"O método usa keyword arguments para deixar claro o que significa cada número (limite, percentual) e usa early return para simplificar o fluxo.
Exemplo 2: extraindo método para padronizar mensagens
Quando você repete formatação de saída, extraia um método para “dar nome” ao padrão.
puts "[INFO] Pedido criado: id=10"
puts "[INFO] Pagamento aprovado: id=10"
puts "[ERRO] Falha ao enviar email: id=10"Refatorando com método e parâmetros:
def log(nivel, mensagem, id: nil)
sufixo = id ? " id=#{id}" : ""
"[#{nivel}] #{mensagem}:#{sufixo}"
end
puts log("INFO", "Pedido criado", id: 10)
puts log("INFO", "Pagamento aprovado", id: 10)
puts log("ERRO", "Falha ao enviar email", id: 10)
puts log("INFO", "Rotina finalizada")Aqui, id: é um keyword argument opcional com comportamento controlado dentro do método.
Escolhendo entre posicionais, default, *args, keywords e **kwargs
| Recurso | Quando usar | Exemplo de assinatura |
|---|---|---|
| Posicionais | Poucos parâmetros, ordem óbvia | def area(largura, altura) |
| Valores padrão | Quando há um valor comum | def conectar(host, porta = 5432) |
*args | Quantidade variável de argumentos | def soma(*nums) |
| Keywords | Parâmetros com significado, evitar confusão de ordem | def criar(nome:, email:) |
**kwargs | Opções flexíveis/encaminhamento | def call(**opts) |
Exemplo combinado (realista e compacto)
def gerar_relatorio(titulo, *linhas, formato: "txt", **opcoes)
cabecalho = "Relatório: #{titulo}"
corpo = linhas.join("\n")
if formato == "txt"
[cabecalho, corpo].join("\n\n")
else
# apenas para exemplo: outras opções poderiam ser tratadas via **opcoes
"formato=#{formato} opcoes=#{opcoes.inspect}"
end
end
puts gerar_relatorio("Vendas", "Item A: 10", "Item B: 20")
puts gerar_relatorio("Vendas", "Item A: 10", formato: "json", indent: 2)