Ruby: A Linguagem da Felicidade

Aprenda Ruby e Rails para desenvolvimento web elegante e produtivo


Ruby: A Linguagem da Felicidade
1 Carregando...

Ruby: A Linguagem da Felicidade

Ruby é uma linguagem de programação dinâmica, de código aberto, focada em simplicidade e produtividade. Criada por Yukihiro “Matz” Matsumoto em 1995 no Japão, Ruby foi projetada para fazer programadores felizes, com uma sintaxe natural que lê quase como inglês.

Filosofia Ruby: “Ruby é projetada para fazer programadores felizes.” - Matz. Essa filosofia se reflete em cada aspecto da linguagem.

Características Distintivas

  1. Tudo é Objeto - Mesmo números e booleanos são objetos
  2. Blocos e Procs - Closures poderosas e elegantes
  3. Metaprogramação - Código que escreve código
  4. Duck Typing - Se caminha como pato e faz quack…
  5. DSLs - Facilidade para criar Domain Specific Languages
  6. Ruby on Rails - Framework que revolucionou o desenvolvimento web

Fundamentos

Tipos e Variáveis

# Variáveis locais
nome = "Maria"
idade = 25
altura = 1.68
ativo = true

# Símbolos (imutáveis e únicos)
status = :pendente
role = :admin

# Arrays
frutas = ["maçã", "banana", "laranja"]
frutas << "uva"  # Adiciona
frutas.push("morango")

# Hashes
usuario = {
  nome: "Maria",
  email: "[email protected]",
  idade: 25
}

# Acesso
usuario[:nome]  # "Maria"
usuario.fetch(:telefone, "Não informado")

# Ranges
numeros = (1..10)
letras = ("a".."z")
numeros.to_a  # [1, 2, 3, ..., 10]

# String interpolation
mensagem = "Olá, #{nome}! Você tem #{idade} anos."

# Heredoc para strings multilinhas
descricao = <<~TEXT
  Esta é uma descrição
  que ocupa múltiplas linhas
  e mantém a formatação.
TEXT

Métodos e Blocos

# Método simples
def saudar(nome)
  "Olá, #{nome}!"
end

# Método com valor padrão
def criar_usuario(nome, email, ativo: true)
  { nome: nome, email: email, ativo: ativo }
end

# Método com bloco
def executar_com_log
  puts "Iniciando..."
  resultado = yield
  puts "Finalizando..."
  resultado
end

executar_com_log { 2 + 2 }  # Retorna 4

# Blocos com parâmetros
[1, 2, 3].map { |n| n * 2 }  # [2, 4, 6]

# Procs e Lambdas
duplicar = ->(x) { x * 2 }
duplicar.call(5)  # 10

# Proc (menos restritivo)
meu_proc = Proc.new { |x| x * 2 }

# Method chaining
resultado = [1, 2, 3, 4, 5]
  .select { |n| n.even? }
  .map { |n| n * 2 }
  .sum

# Splat operators
def somar(*numeros)
  numeros.sum
end

def info(**opcoes)
  opcoes.each { |k, v| puts "#{k}: #{v}" }
end

info(nome: "Maria", idade: 25)

Classes e Objetos

# Classe básica
class Usuario
  attr_reader :id, :email
  attr_accessor :nome

  def initialize(nome, email)
    @id = SecureRandom.uuid
    @nome = nome
    @email = email
    @ativo = true
  end

  def saudar
    "Olá, #{@nome}!"
  end

  def ativo?
    @ativo
  end

  def desativar!
    @ativo = false
  end

  private

  def log(mensagem)
    puts "[LOG] #{mensagem}"
  end
end

# Herança
class Admin < Usuario
  attr_reader :permissoes

  def initialize(nome, email, permissoes = [])
    super(nome, email)
    @permissoes = permissoes
  end

  def pode?(acao)
    permissoes.include?(acao.to_sym)
  end
end

# Módulos (mixins)
module Timestamps
  def touch
    @updated_at = Time.now
  end

  def created_at
    @created_at ||= Time.now
  end
end

class Artigo
  include Timestamps

  def initialize(titulo)
    @titulo = titulo
  end
end

# Struct para classes simples
Ponto = Struct.new(:x, :y) do
  def distancia_origem
    Math.sqrt(x**2 + y**2)
  end
end

ponto = Ponto.new(3, 4)
ponto.distancia_origem  # 5.0

Enumerables

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Transformações
dobrados = numeros.map { |n| n * 2 }
pares = numeros.select { |n| n.even? }
impares = numeros.reject { |n| n.even? }

# Reduções
soma = numeros.reduce(0) { |acc, n| acc + n }
soma = numeros.sum  # Atalho

# Buscas
primeiro_par = numeros.find { |n| n.even? }
todos_pares = numeros.all? { |n| n.even? }
algum_par = numeros.any? { |n| n.even? }

# Agrupamento
grupos = numeros.group_by { |n| n.even? ? :par : :impar }
# { par: [2,4,6,8,10], impar: [1,3,5,7,9] }

# Ordenação
usuarios = [
  { nome: "Maria", idade: 25 },
  { nome: "João", idade: 30 },
  { nome: "Ana", idade: 22 }
]

ordenados = usuarios.sort_by { |u| u[:idade] }
mais_velho = usuarios.max_by { |u| u[:idade] }

# Lazy evaluation
primeiro_grande = (1..Float::INFINITY)
  .lazy
  .map { |n| n * 2 }
  .select { |n| n > 1000 }
  .first(5)

Metaprogramação

# define_method dinâmico
class Usuario
  [:admin, :moderador, :editor].each do |role|
    define_method "#{role}?" do
      @role == role
    end
  end
end

# method_missing para proxy
class HashWrapper
  def initialize(hash)
    @hash = hash
  end

  def method_missing(name, *args)
    if @hash.key?(name)
      @hash[name]
    else
      super
    end
  end

  def respond_to_missing?(name, include_private = false)
    @hash.key?(name) || super
  end
end

wrapper = HashWrapper.new(nome: "Maria", email: "[email protected]")
wrapper.nome  # "Maria"

# DSL example
class Configuracao
  def self.configure(&block)
    config = new
    config.instance_eval(&block)
    config
  end

  def database(nome)
    @database = nome
  end

  def cache(enabled)
    @cache_enabled = enabled
  end
end

config = Configuracao.configure do
  database "production"
  cache true
end

Ruby on Rails Essencial

# Model com validações
class Usuario < ApplicationRecord
  has_many :posts, dependent: :destroy
  belongs_to :empresa

  validates :nome, presence: true, length: { minimum: 2 }
  validates :email, presence: true, uniqueness: true

  scope :ativos, -> { where(ativo: true) }
  scope :admins, -> { where(role: :admin) }

  before_create :gerar_token

  def saudar
    "Olá, #{nome}!"
  end

  private

  def gerar_token
    self.token = SecureRandom.hex(20)
  end
end

# Controller RESTful
class UsuariosController < ApplicationController
  before_action :set_usuario, only: [:show, :update, :destroy]

  def index
    @usuarios = Usuario.ativos.includes(:empresa)
    render json: @usuarios
  end

  def show
    render json: @usuario
  end

  def create
    @usuario = Usuario.new(usuario_params)
    
    if @usuario.save
      render json: @usuario, status: :created
    else
      render json: { errors: @usuario.errors }, status: :unprocessable_entity
    end
  end

  private

  def set_usuario
    @usuario = Usuario.find(params[:id])
  end

  def usuario_params
    params.require(:usuario).permit(:nome, :email, :empresa_id)
  end
end

# Rotas
Rails.application.routes.draw do
  resources :usuarios do
    member do
      post :ativar
      post :desativar
    end
    
    collection do
      get :exportar
    end
  end
end

Ferramentas Essenciais

FerramentaPropósito
BundlerGerenciador de dependências
RailsFramework web full-stack
RSpecFramework de testes
RubocopLinter e formatador
PryConsole interativo avançado

Checklist de Aprendizado

  • Dominar blocos, procs e lambdas
  • Entender módulos e mixins
  • Aprender Enumerable methods
  • Estudar metaprogramação
  • Praticar com Ruby on Rails
  • Escrever testes com RSpec
  • Criar uma API REST

Recursos Essenciais

Citação

“Ruby é simples na aparência, mas muito complexo por dentro, como o corpo humano.” - Yukihiro Matsumoto


Ruby torna a programação uma experiência prazerosa. Descubra a felicidade de codar com Ruby!