Escrevendo iteradores

Nesta seção, vamos adicionar nossos próprios iteradores à classe AddressBook. Vamos criar dois iteradores, AddressBook#each e AddressBook#each_address, que podem ser usados como de costume:


address_book.each do |person|
    ...
end

address_book.each_address do |address|  
    ...
end
                       

Chamando um bloco

Quando você escreve uma função ou método, você pode chamar um código com a palavra yield. Aqui está um exemplo.


def twice
    yield
    yield
end

twice { puts "Hello World" }  
                       

Isso mostra :


Hello World
Hello World
                       

Passando parâmetros

Você pode usar o yield como qualquer outro método. Para passar parâmetros para o código, você simplesmente enviá-los ao yield. Veja este exemplo:


def names
    yield("Joe")
    yield("Sandy")
    yield("Melissa")
end

names do |name|
    puts "Hello " + name + ", how are you?"  
end
                       

Isso mostra na tela :


Hello Joe, how are you?  
Hello Sandy, how are you?
Hello Melissa, how are you?  
                       

Você pode passar vários parâmetros para o bloco que você quiser. Por exemplo:


def full_names
    yield("Joe", "Smith")
end

full_names do |first,last|
    puts first + " " + last  
end
                       

Imprime:


Joe Smith  
                       

AddressBook#each

Agora podemos escrever o nosso primeiro iterator. AddressBook#each é o mais simples dos dois iteradores. Nós passamos por cada pessoa no array @persons e chamamos yield em cada um.


class AddressBook
    def each
        @persons.each { |p| yield p }  
    end
end
                       

É isso. Agora nossa classe tem um iterador.

AddressBook#each_address

Este iterator é quase tão simples como o que escrevemos acima. Nós vamos passar por cada pessoa e em seu endereço.


class AddressBook
    def each_address
        @persons.each { |p| yield p.address }  
    end
end
                       

Wrap up

Basta embrulhar tudo até agora. Aqui está toda a classe AddressBook juntamente com comentários. Trata-se de um pedaço de código bastante complexo, mas ao dividir a tarefa em partes menores nós a tornamos mais fáceis de gerenciar.


class AddressBook
    #
    #  Fundamental methods: initialize, add, remove
    #
    def initialize
        @persons = []
    end
    def add(person)
        @persons += [person]
        @persons = @persons.sort{|a,b| by_name(a,b)}  
    end
    def remove(person)   
        @address.delete(person)
    end
     

    #
    #  Iterators:  each, each_address
    #
    def each
        @persons.each { |p| yield p }
    end
    def each_address
        @persons.each { |p| yield p.address }
    end
        
    #  
    #  Sorting function.
    #
    def by_name(a,b)
        if  a.first_name  == b.first_name
            a.last_name  <=> b.last_name
        else
            a.first_name <=> b.first_name
        end 
    end
end
                       

topo da página

<< Página Anterior | índice | Próxima Página >>
Apostilas de Ruby e RGSS

nossos tutoriais

navegue

livros recomendados