Git Product home page Git Product logo

ht-rmp's Introduction

Ruby Metaprogramming
====================

Aqui estão os exercícios do workshop de Ruby Metaprogramming.
Para executá-los, você precisará ter o Ruby instalado. Utilize,
preferencialmente, a versão 1.9; afinal, não queremos que o Ruby
se torne o PHP4 pelos próximos 5 anos.

Todos os exercícios possuem testes, que foram divididos por dia de
workshop. O arquivo test_day_1.rb se refere ao dia 1, o arquivo
test_day_2.rb se refere ao dia 2, e assim sucessivamente.

Os testes podem ser executados com o comando

  rake spec

Cada um dos arquivos pode ser executado individualmente com

  rake spec:day_1
  rake spec:day_2
  rake spec:day_3
  rake spec:day_4
  rake spec:day_5

Faça os testes passarem, criando arquivos equivalentes como

  files/day_1.rb
  files/day_2.rb

e assim sucessivamente.

Você pode ver os testes para fazer a sua implementação. As soluções
propostas dos exercícios estão no branch `solution`.

--------------------------
Instalando as dependências
--------------------------

Para instalar as dependências, instale o
Bundler (http://rubygems.org/gems/bundler) e execute o comando

  bundle install

-------------------------------------
Dia 1: self, classe Singleton e Class
-------------------------------------

1.      O Ruby 1.9 implementa o método BasicObject#singleton_class,
        que retorna a classe Singleton de um objeto. Adicione o método
        Object#metaclass de modo que ele faça a mesma coisa.

        Teste: test_day_1.rb#test_exercise_1



2.      Defina um módulo que implemente os métodos App.description e App.description= utilizando
        a classe Singleton.

        Teste: test_day_1.rb#test_exercise_2



3.      Implemente um método no namespace global chamado new_class, que deve retornar
        uma classe criada dinamicamente. Esta classe deve herdar de uma outra classe
        chamada Person. O comportamente seria semelhante a

          class SomeClass < Person
          end

        Teste: test_day_1.rb#test_exercise_3



4.      Crie uma nova classe dinâmica, cujo nome deve ser "Awesome".

        Teste: test_day_1.rb#test_exercise_4



5.      Crie um método no namespace global chamado new_method, que deve adicionar
        um método chamado hello à instância do objeto que ele receberá como argumento.
        Este método hello deve retornar uma string como "Hello from <CLASSE> instance".
        A string <CLASSE> deve retornar o nome da classe do objeto.

        Você deve utilizar apenas o receiver; não use os métodos instance_eval, class_eval,
        eval ou define_method.

        A assinatura deste método é

          def new_method(object)
          end

        Teste: test_day_1.rb#test_exercise_5



--------------
Dia 2: Methods
--------------

1.      Crie um método no namespace global chamado send_message. Este método deverá
        instanciar a classe Message e executar o método Message#deliver dinamicamente.

        Esta classe é definida pelo teste.

        A assinatura deste método é

          def send_message
          end

        Teste: test_day_2.rb#test_exercise_1



2.      Crie um método no namespace global chamado send_message_with_args. Este método deverá
        executar dinamicamente o método Message.send, que sobrescreveu a implementação
        original.

        O método Message.send espera dois argumentos; uma instância da classe Message e um
        número inteiro de 1 a 3, que indica a prioridade da mensagem.

        A assinatura deste método é

          def send_message_with_args
          end

        Teste: test_day_2.rb#test_exercise_2



3.      Crie um método no namespace global chamado send_private_method. Este método deverá
        executar dinamicamente o método privado Message#prepare.

        A assinatura deste método é

          def send_private_method
          end

        Teste: test_day_2.rb#test_exercise_3



4.      Crie um método no namespace global chamado send_public_method. Este método deverá
        executar dinamicamente apenas métodos públicos; você deve executar o método
        Message#prepare e esta chamada deverá lançar a exceção `NoMethodError`.

        A assinatura deste método é

          def send_public_method
          end

        Teste: test_day_2.rb#test_exercise_4



5.      Crie uma classe chamada Song, que possui 3 atributos:

        - title
        - artist
        - duration

        O método construtor desta classe pode receber um hash e cada um dos itens
        desse hash deve ser definir o atributo de mesmo nome.

        Um exemplo de uso desta classe pode ser

          Song.new(
            :title => "Linoleum",
            :artist => "NOFX",
            :duration => "2:10"
          )

        Teste: test_day_2.rb#test_exercise_5



6.      Adicione um método String#to_leet, que irá converter uma string para sua versão
        Leet (http://en.wikipedia.org/wiki/Leet).
        Utilize o mapeamento abaixo para substituir cada um dos caracteres pelo seu equivalente.

          LEET = {
            "a" => "4",
            "e" => "3",
            "i" => "1",
            "o" => "0",
            "u" => "μ"
          }

        Ao executar `"banana".to_leet` devemos receber como resultado a string `b4n4n4`.

        Teste: test_day_2.rb#test_exercise_6



7.      Adicione o método Object.leet_attr, que permitirá criar atributos como os
        exemplos abaixo.

          class Person
            leet_attr :name, :blog, :twitter
          end

        seria o equivalente a definir os atributos como

          class Person
            attr_accessor :name, :blog, :twitter

            def n4me
              name.to_s.to_leet
            end

            def bl0g
              blog.to_s.to_leet
            end

            def tw1tt3r
              twitter.to_s.to_leet
            end
          end

        Você deve utilizar o método define_method para adicionar o método que retorna a string em
        leet.

        Teste: test_day_2.rb#test_exercise_7



8.      Semelhante ao exercício anterior, adicione o método Object.reverse_attr, que permitirá criar
        atributos como os exemplos abaixo.

          class Person
            reverse_attr :name, :blog, :twitter
          end

        seria o equivalente a definir os atributos como

          class Person
            attr_accessor :name, :blog, :twitter

            def eman
              name.to_s.reverse
            end

            def golb
              blog.to_s.reverse
            end

            def rettiwt
              twitter.to_s.reverse
            end
          end

        Você deve utilizar o método class_eval para adicionar o método que retorna a string reversa.

        Teste: test_day_2.rb#test_exercise_8



9.      Remova o método Car.useless, já que ele não faz nada.

        A classe Car foi definida pelo teste.

        Teste: test_day_2.rb#test_exercise_9



10.     A classe Ferrari, que herda da classe Car, implementa o método color, sobrescrevendo a
        implementação original.
        Remova o método Ferrari#color de modo que o retorno seja a implementação original.

        Teste: test_day_2.rb#test_exercise_10



11.     Assim como o exercício anterior, a classe Ferrari também implementa o método Ferrari#engine.
        Remova o método Ferrari#engine de qualquer chamada ao método, mesmo que presente em uma
        superclasse, lance a exceção NoMethodError.

        Teste: test_day_2.rb#test_exercise_11



12.     O método Calc.sum, implementado pelo teste, soma dois números. No entanto, este método lança
        uma exceção se passando um valor nil. Redefina este método convertendo qualquer valor não
        numérico 0 antes de enviar estes números para a implementação original.

        Utilize o método define_method em conjunto com os métodos instance_method e bind.

        Teste: test_day_2.rb#test_exercise_12



ht-rmp's People

Contributors

fnando avatar mariannareis avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.