Ruby do Zero: Métodos — Parâmetros, Retorno, Argumentos Nomeados e Escopo

Capítulo 12

Tempo estimado de leitura: 8 minutos

+ Exercício

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) # 20

Não há return aqui, mas o método retorna n * 2.

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

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
end

Early 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
end

Note 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}"
end

Agora 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.50

Splat (*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()          # 0

Dentro 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 aqui

Passando 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

RecursoQuando usarExemplo de assinatura
PosicionaisPoucos parâmetros, ordem óbviadef area(largura, altura)
Valores padrãoQuando há um valor comumdef conectar(host, porta = 5432)
*argsQuantidade variável de argumentosdef soma(*nums)
KeywordsParâmetros com significado, evitar confusão de ordemdef criar(nome:, email:)
**kwargsOpções flexíveis/encaminhamentodef 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)

Agora responda o exercício sobre o conteúdo:

Ao refatorar um método para deixar a chamada mais legível e menos dependente da ordem dos valores, qual abordagem é a mais indicada?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Keyword arguments tornam a chamada autoexplicativa (ex.: limite:, percentual:) e reduzem erros por troca de ordem. Valores padrão ajudam quando há um valor comum.

Próximo capitúlo

Ruby do Zero: Blocos, yield, Proc e Lambda

Arrow Right Icon
Capa do Ebook gratuito Ruby do Zero: Fundamentos, Coleções, Blocos e Organização de Código
57%

Ruby do Zero: Fundamentos, Coleções, Blocos e Organização de Código

Novo curso

21 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.