Aprenda Ruby

  • Página Inicial
  • Contato!
  • Tudo sobre Ruby Parte 1!
  • Tudo sobre Ruby Parte 2!
  • Tudo sobre Ruby Parte 3!
  • Tudo sobre Ruby Parte 4!
  • Tudo sobre Ruby Parte 3

    Hashes

    Um hashe é como um array, só que ele permite nomes literais nos índices, por exemplo:

    
    pessoa = {nome: "Fulano", idade: 25, sexo: "M"}
    
    # Podemos adicionar valores posteriormente assim:
    pessoa[:fuma] = false
    
    # Iteração com loop:
    pessoa.each do |k, v|
        puts "Chave: #{k} - Valor: #{v}."
    end
    
    

    Hashes vazios podem ser declarados assim:

    
    h1 = {}
    h2 = Hash.new
    
    

    Para exibir os índices literalmente, use os dois pontos, assim:

    
    conta = {tipo: "CC", saldo: 1500.99, ativo: true}
    
    puts "Tipo de conta: #{conta[:tipo]}"
    puts "Saldo da conta: R$#{'%.2f' % conta[:saldo]}"
    puts "Conta ativa: #{conta[:ativo]}"
    
    

    PS: Podemos declarar os hashes assim também:

    
    carro = {"marca" => "Volkswagen", "modelo" => "Fusca", "cor" => "Vermelho", "ano" => 1994, "potencia" => 1.6}
    
    carro.each_pair do |k, v|
        puts "#{k} é #{v}"
    end
    
    

    Métodos

    Basicamente, um procedimento é um método que não retorna nada, como este:

    
    def saudacao()
        puts "Olá, usuário! Bom dia!"
    end
    
    # Invocação do método, pode ser com ou sem parênteses:
    saudacao
    
    

    Com um parâmetro:

    
    def saudacao(nome)
        puts "Olá, #{nome}! Bom dia!"
    end
    
    # Invocação do método, pode ser com ou sem parênteses:
    saudacao "Fulano"
    
    

    Com isso podemos criar métodos para códigos grandes, por exemplo:

    
    def datas
        dataAtual = Time.now
    
        dia = dataAtual.strftime("%d/%m/%Y")
        ds = dataAtual.strftime("%w").to_i
        semana = ["Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"]
        hora = dataAtual.strftime("%H:%M:%S")
    
        puts "Hoje é #{dia}, #{semana[ds]}, e a hora atual é #{hora}."
    end
    
    datas
    
    

    Mas em alguns casos, como as funções que retornam valores, devemos usar os parênteses, por exemplo:

    
    def multi(n1, n2)
        return n1 * n2
    end
    
    puts multi(10, 5)
    
    

    Temos também as Lambdas, usadas da seguinte forma:

    
    mens = lambda {puts "Mensagem com Lambda!"}
    
    mens.call # Invocação de lambdas exige o call
    
    soma = lambda {|n1, n2| n1 + n2} # Com parâmetros e retorno (ele dispensa o "return")
    
    puts soma.call(10, 5)
    
    

    PS: Podemos salvar as funções em outro arquivo, e chamar eles por um include, dessa forma:

    
    require "./funcoes.rb"
    
    

    Tratamento de Erros

    Vamos considerar esse código para calcular uma divisão:

    
    print "Digite o numerador: "
    n1 = gets.to_i
    
    print "Digite o denominador: "
    n2 = gets.to_i
    
    res = n1 / n2
    
    puts "A divisão entre #{n1} e #{n2} é igual à #{res}."
    
    

    Se tentarmos dividir qualquer número por zero, ele dará erro e lançará a exceção "ZeroDivisorError".

    Para tratarmos esse erro, usamos o bloco begin rescue (equivalente ao try catch/except) assim:

    
    begin # Equivalente ao try, é obrigatório
        
    rescue # Equivalente ao catch/except, pelo menos um é obrigatório
    
    else # É opcional
    
    ensure # Equivalente ao finally, é opcional
        
    end
    
    

    No caso, colocamos o código suscetível a erro dentro do begin (equivalente ao try), ele executará ele todo ou parará quando encontrar um erro, e passará a executar o que está dentro do rescue (equivalente ao catch/except). O else (opcional) executa caso não exista erro. O ensure (equivalente ao finally) executará com erro ou não.

    O código acima ficaria assim:

    
    begin
        print "Digite o numerador: "
        n1 = gets.to_i
    
        print "Digite o denominador: "
        n2 = gets.to_i
    
        res = n1 / n2
    
        puts "A divisão entre #{n1} e #{n2} é igual à #{res}."
    rescue
        puts "O código deu erro."
    else
        puts "O código foi executado corretamente."
    ensure
        puts "Conclusão do código." 
    end
    
    

    Ou jogando o exception numa variável, assim:

    
    begin
        print "Digite o numerador: "
        n1 = gets.to_i
    
        print "Digite o denominador: "
        n2 = gets.to_i
    
        res = n1 / n2
    
        puts "A divisão entre #{n1} e #{n2} é igual à #{res}."
    rescue Exception => ex
        puts "ERRO: #{ex}."  
    end
    
    

    No geral, o Exception pega qualquer erro, já que todas as exceções herdam dele. No entanto, podemos ter vários blocos rescue, como podemos ver:

    
    def divisao(n1, n2)
        return n1 / n2
    end
    
    begin
        puts divisao(10, "a")
    rescue TypeError => ex
        puts "ERRO: Tipos Incompatíveis."
    rescue ZeroDivisionError => ex
        puts "ERRO: Divisão por zero."
    end
    
    

    Podemos lançar também nossas próprias exceções, utilizando o raise, assim:

    
    def contador(num)
        if num <= 0 then
            raise "O número deverá ser maior que zero"
        end
        
        cont = 0
    
        while cont <= num do
            puts cont
    
            cont += 1
        end
    end
    
    begin
        contador(0) # Tente trocar por uma string
    rescue Exception => ex
        puts "ERRO: #{ex}."
    end
    
    

    Lendo e Escrevendo Arquivos

    Para escrever arquivos em Ruby, podemos fazer assim:

    
    print "Digite algo para inserir no arquivo: "
    entr = gets.strip
    
    File.write("arquivo.txt", "#{entr}\n")
    
    

    Só que, caso o arquivo já exista, ele sobrescreverá o que está escrito. para ele não sobrescrever, faça assim:

    
    print "Digite algo para inserir no arquivo: "
    entr = gets.strip
    
    File.write("arquivo.txt", "#{entr}\n", mode: "a")
    
    

    Para ler também é simples:

    
    arq = File.readlines("arquivo.txt")
    
    puts arq