aluno: Fabio Eigi Imada
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 04/11/2008 (6)
Introdução
O objetivo do lab foi introduzir a linguagem de programação Ruby. O laboratório consistiu em portar o código do lab2, feito em Java, para Ruby.
Desenvolvimento
O desenvolvimento do lab foi relativamente tranquilo por não haver nenhuma dificuldade em entender e projetar o programa, focando-se apenas nas dificuldades da nova linguagem.
Uma das grandes facilidades observadas no Ruby foi decorrente do fato de a linguagem ser interpretada, assim os erros podiam ser encontrados e corrigidos instantaneamente. Esta característica do Ruby o torna bastante didático, pois é muito fácil testar diversas codificações de um determinado método através de sobreposição de métodos feitas no interpretador antes de se chegar à codificação definitiva.
Portanto observa-se que a característica do desacoplamento é bem mantida em Ruby. É possível modificar e criar métodos de classes sem precisar conhecer o código-fonte da própria classe.
Outra característica muito interessante do Ruby é a facilidade com que o código é escrito. Por não haver a necessidade de utilizar parênteses e chaves a todo instante, o tempo de escrita do código é razoavelmente reduzido. Por outro lado, não se perde organização no código se for respeitada uma identação adequada.
A seguir será feito um breve resumo das facilidades encontradas em cada "arquivo"
* Classe.rb
A utilização de attr_accessors, readers e writers tornou o código muito mais legível e o diminuiu em muitas linhas.
O controle de acesso do Ruby também agiliza o desenvolvimento do programa, pelo fato de a grande maioria dos métodos serem públicos, foi praticamente esquecida a necessidade de declarar o controle de acesso dos métodos.
Outra característica que ajudou bastante foi o fato de os métodos retornarem o último resultado encontrado.
* Simulador.rb
Inicialmente houve a dúvida se seria necessário criar uma classe main como é feito nas outras linguagens, mas a forma como o programa foi executado mostrou que seria desnescessária a criação dessa classe, exceto se fosse utilizado para explicitar qual a classe principal de um projeto.
* Teste.rb
O portabilidade dos testes de Java para Ruby foram muito facilitadas, pelo fato de os códigos serem muito parecidos e repetidos.
Particularmente, a possibilidade de utilizar assert_raise para recolher exceções reduziu muito esta parte do código pelo fato de não haver a necessidade de utilizar begin-fail-rescue-end comparado com o Java.
Códigos
Classe
class Aluno ... def dedicacao @comportamento.dedicacao end def inteligencia @comportamento.inteligencia end attr_reader :conhecimento, :nome attr_writer :comportamento end class Relatorio ... end class Professor def initialize( queue ) @queue = queue end def corrige_relatorios () @queue.each do |rela| puts rela.aluno.nome + ": " + corrige_relatorio( rela ).to_s end end private def corrige_relatorio( rela ) ( rela.qualidade + rela.originalidade + rand ) / 0.3 end end class Comportamento def initialize (aluno) @aluno = aluno end attr_accessor :dedicacao, :inteligencia end #Os métodos de RelaQueue são os mesmos de Array #Foi adicionado queue e dequeue para que o código se mantesse parecido com o lab2 RelaQueue = Array class RelaQueue def queue(obj) push(obj) end def dequeue shift end end class Safo < Comportamento def initialize (aluno) super(aluno) @inteligencia = 1 end def dedicacao; 0.5*rand; end end ... class Aluno_Unicamp < Aluno def comportamento=(novo_comportamento) if(novo_comportamento.class == Safo || novo_comportamento.class == Summa) raise "Comportamento Invalido!!!" else @comportamento = novo_comportamento end end end ...
Simulador
require 'classe' puts "\n\t\t\tSimulador de Entrega de Relatorios\n\n" puts 'Qtd de alunos: ' n_alunos = gets().to_i queue = RelaQueue.new n_alunos.times do |i| puts 'Digite o nome: ' nome = gets().chomp puts "Qual a faculdade?\n\t1-ITA\n\t2-Unicamp\n\t3-USP\n\t*-Outros" opcao = gets().to_i case opcao when 1 aluno = Aluno_ITA.new(nome, queue) when 2 aluno = Aluno_Unicamp.new(nome, queue) when 3 aluno = Aluno_USP.new(nome, queue) else aluno = Aluno.new(nome, queue) end puts "Qual o comportamento do aluno?\n\t1-Safo\n\t2-Esforcado" puts "\t3-Pemba\n\t4-Summa\n\t5-Imprevisivel\n\t6-Burro" opcao = gets().to_i begin case opcao when 1 aluno.comportamento = Safo.new(aluno) when 3 aluno.comportamento = Pemba.new(aluno) when 4 aluno.comportamento = Summa.new(aluno) when 5 aluno.comportamento = Imprevisivel.new(aluno) when 6 aluno.comportamento = Burro.new(aluno) else aluno.comportamento = Esforcado.new(aluno) end rescue puts "Comportamento inexistente para esse aluno, esse aluno sera Imprevisivel" aluno.comportamento = Imprevisivel.new(aluno) end aluno.faz_e_entrega_relatorio end professor = Professor.new(queue) puts "\n\nAs notas dos alunos sao:" professor.corrige_relatorios
Teste
require 'classe' require 'test/unit' class TestAluno < Test::Unit::TestCase def test_funciona_como_o_lab1 ... #teste de alunosafo assert_equal(1.0, aluno3.inteligencia(), 0.01); assert(aluno3.dedicacao != aluno3.dedicacao); #deve ser randomica assert(aluno3.dedicacao() < 0.5); ... def test_as_sub_classes_de_aluno_tem_restricoes ... begin alunoITA.comportamento = ( Safo.new(alunoITA) ); alunoITA.comportamento = ( Summa.new(alunoITA) ); alunoUSP.comportamento = ( Burro.new(alunoUSP) ); alunoUnicamp.comportamento = ( Burro.new(alunoUnicamp) ); rescue fail("Não deveria lançar erro!"); end assert_raise(RuntimeError) { alunoITA.comportamento = ( Burro.new(alunoITA) ) } ... end
Resultado dos testes e do simulador

Conclusão
Após este primeiro contato com o Ruby, foi possível perceber que a linguagem é bastante prática e eficiente.
Fora o que foi utilizado neste lab, foi observado que a programação em Ruby possui muitas outras facilidade. No entanto, é preciso gastar algum tempo para aprender a utilizar as facilidades do Ruby.
Como este lab foi a portagem de um código em Java para Ruby, a linguagem não foi tão explorada quanto poderia.





