Implementando o livro de endereços
Agora que temos as classes Address e Person, vamos criar o AddressBook.
Primeiro passo
O primeiro passo é muito fácil . AddressBook tem um array que possui todos os nossos contatos. Não usaremos attr_accessor porque não queremos que o usuário acesse diretamente esse array. Vamos escrever nosso próprio método de acesso.
class AddressBook
def initialize
# Empty array.
@persons = []
end
end
|
Isso foi fácil. Vamos acrescentar dois métodos de acesso: AddressBook#add e AddressBook#remove
class AddressBook
def initialize
@persons = []
end
def add(person)
@persons += [person]
end
def remove(person)
# Use Array#delete
@persons.delete(person)
end
end
|
O método Array#delete irá apagar todas as entradas que correspondam ao informado. Por exemplo:
>> a = [ 1, 3, 3, 3, 3, 5]
=> [1, 3, 3, 3, 3, 5]
>> a.delete(3)
=> 3
>> a
=> [1, 5]
|
Como @persons é um array, vamos usar Array#delete
Classificação automática
Agora vamos adicionar um recurso muito bom em nossa classe AddressBook: classificação automática. O que quero dizer é que quando você digitar:
addr_book = AddressBook.new
addr_book.add mary
addr_book.add joe
addr_book.add sandy
|
Todas as entradas serão automaticamente classificadas. Esta característica torna a nossa classe muito melhor do que uma array regular. Agora, vamos ver essa tarefa um passo de cada vez.
Como vamos classificar array?
Podemos classificar um array alfabeticamente, pelo primeiro nome, depois o último. Na seção Classificando o livro de endereços vimos algo assim:
# p_a == "person a"
addressbook.sort do |p_a, p_b|
p_a["first name"] <=> p_b["first name"]
end
|
Vamos adaptá-lo à nossa classe AddressBook:
@persons.sort do |a, b|
a.first_name <=> b.first_name
end
|
Se você fez os exercícios daquela seção, você também sabe como classificar por nome completo. Aqui está uma maneira de o fazer:
@persons.sort do |a, b|
if a.first_name == b.first_name
a.last_name <=> b.last_name
else
a.first_name <=> b.first_name
end
end
|
Se os primeiros nomes são os mesmos, nós comparamos os últimos nomes. Caso contrário, nós comparamos os primeiros nomes.
Simplificando coisas
A base da simplificação consiste em dividir o problema em várias componentes. Vamos começar por colocar o código em um método:
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
|
Agora vamos escrever:
@persons.sort do |a, b|
by_name(a,b)
end
|
Isto é muito mais curto. Agora, você vai aprender algo sobre blocos de código. Observe que no lugar disso:
@persons.sort do |a, b|
...
end
|
Você pode escrever isso:
@persons.sort { |a, b|
...
}
|
As duas notações significam exatamente a mesma coisa. A diferença é que a notação do...end é mais clara, e a notação {...}é mais curta. Mas significa que você pode escrever:
@persons.sort { |a, b| by_name(a,b) }
|
Você quase pode ler isto como "classificar por nome". Este código é muito legível. Sugiro que, por hora, você use somente a notação {...} quando puder colocar tudo na mesma linha.
Finalizando
Chegou o momento de pôr isso em nossa classe AddressBook e implementar a nossa característica de auto-classificar.
class AddressBook
def add(person)
@persons += [person]
@persons = @persons.sort{|a,b| by_name(a,b)}
end
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
|
Agora, sempre que você adicionar uma pessoa, o AddressBook irá classificá-la automaticamente.
book.add sandy
book.add joe
book.add mary
book.add melissa
# 'book' is sorted.
|