taxe para declaração de classes, que no caso, é com a palavra-chave class:
class Purchase
end
Veja que, para a declaração de classes, usa-se o padrão CamelCase, porém co-
meçando com uma letra maiúscula. Isso deve-se ao fato que qualquer nome, seja de
variável ou de classe, que começa com uma letra maiúscula é uma constante.
A classe Purchase não tem nada de interessante. Vamos torná-la um pouco me-
lhor.
Construtores
class Purchase
def initialize(value)
@value = value
end
end
payment = Purchase.new(100.00)
payment # #<Purchase:0x007f97e14e61e8 @value=100.0>
No exemplo anterior acontecem algumas coisas interessantes. Primeiramente,
criamos um método de instância chamado #initialize. Métodos de instância são
métodos que podem ser executados em instâncias da classe Purchase.
51
2.6. Classes e módulos
Casa do Código
Mas esse método não é qualquer método. Ele é um construtor, ou seja, ele é cha-
mado quando um novo objeto é criado. Você pode observar porém que não chama-
mos o método #initialize diretamente, mas o .new. Por que? O Ruby implementa
no método de classe .new (ou seja, método relacionado diretamente à classe e não ao
objeto) as mágicas internas necessárias para se criar um novo objeto e, em seguida,
repassa tudo que recebeu para o método #initialize e retorna a nova instância do
objeto (independente do último valor).
Essa nova instância do objeto criada é chamada também de self. Dessa forma,
usando variáveis com arroba (@) é possível associar valores apenas àquela instância.
Por essa razão, elas são chamadas de variáveis de instância.
Declaração de métodos
Declarar métodos é bem simples, basta seguir o exemplo do #initialize:
class Purchase
def initialize(value, shipping)
@value = value
@shipping_cost = shipping
end
def total_cost
@value + @shipping_cost
end
end
purchase = Purchase.new(100.00, 9.50)
purchase.total_cost # 109.5
Accessors
Accessors são os famosos getters e setters do Ruby. Ou seja, são métodos
de leitura e escrita. Uma coisa interessante do Ruby é que chamada de métodos,
em muitas situações, não precisam de parênteses. Por essa razão, um método de
leitura de variáveis, por exemplo, se parece como um simples acesso a uma variá-
vel pública. Não há necessidade também de nenhuma forma de prefixo, tal como
getShippingCost, como faríamos em outras linguagens.
class Purchase
def initialize(value, shipping)
52
Casa do Código
Capítulo 2. Conhecendo Ruby
@value = value
@shipping_cost = shipping
end
def shipping_cost
@shipping_cost
end
end
purchase = Purchase.new(100.00, 9.50)
purchase.shipping_cost
# 9.5
O setter, ou método de escrita, é bem mais interessante. Como já vimos ante-
riormente, é possível escrever métodos com símbolos como ? e !. Mas também, é
possível escrever métodos terminando com = para criar expressões de associação:
class Purchase
def initialize(value, shipping)
@value = value
@shipping_cost = shipping
end
def shipping_cost=(new_shipping_cost)
@shipping_cost = new_shipping_cost
end
def shipping_cost
@shipping_cost
end
end
purchase = Purchase.new(100.00, 9.50)
purchase.shipping_cost
# 9.5
purchase.shipping_cost = 3 # é possível colocar espaço antes do '='
purchase.shipping_cost
# 3
53
2.6. Classes e módulos
Casa do Código
Cuidado com métodos de leitura e escrita
Métodos de leitura e escrita são para estes propósitos. Então tome cui-
dado com a sua implementação destes métodos. Se eles fizerem muito
mais do que escrever e ler variáveis de instância, talvez não fique óbvio
para quem esteja lendo o código o que o método está fazendo. Não sur-
preenda negativamente os leitores do seu código!
Para facilitar este tipo de construção, existe uma class macro que já cria esses mé-
todos para você. Basta chamar attr_accessor no corpo da classe, passando como
parâmetro uma lista de símbolos que representa o atributo a ser criado.
class Purchase
attr_accessor :shipping_cost
end
purchase = Purchase.new
purchase.shipping_cost = 10.0
purchase.shipping_cost # 10.0
O que é class macro?
Uma class macro é uma chamada de método no nível de classe e o resul-
tado dessa chamada é a alteração da classe, adicionando comportamento
e tornando algum comportamento mais conveniente ao programador.
Por exemplo, a macro attr_accessor gera métodos de leitura e escrita
para um certo atributo.
A macro attr_accessor já cria o método de leitura e escrita para você. É possível
porém ter apenas o método de leitura via a macro attr_reader e o método de escrita
via attr_writer.
Cuidado com acessores de escrita
Existe um problema muito comum que os accessors de escrita geram e que é bas-
tante complicado de depurar, portanto preste atenção! Imagine a seguinte situação:
54
Casa do Código
Capítulo 2. Conhecendo Ruby
1 class Purchase
2
attr_accessor :shipping_cost, :weight, :distance
3
4
def calculate_shipping_cost
5
shipping_cost = distance * weight
6
end
7 end
8
9 purchase = Purchase.new
10 purchase.weight = 0.5