Fuentes Vinícius Baggio - Ruby on Rails: coloque sua aplicação web nos trilhos стр 16.

Шрифт
Фон

objeto de mesma classe ou subclasse chame o método (igual ao friend, do C++).

Vejamos o exemplo

a seguir:

class Person

attr_accessor :name

def befriend(people)

people.each { |friend| friend.add_friend(self) }

end

protected

def add_friend(friend)

puts "#{name} diz: Olá meu novo amigo #{friend.name}!"

end

end

joao = Person.new; joao.name = 'João'

pedro = Person.new; pedro.name = 'Pedro'

joaquim = Person.new; joaquim.name = 'Joaquim'

joao.befriend([pedro])

# Pedro diz: Olá meu novo amigo João!

joaquim.add_friend(joao)

# NoMethodError: protected method àdd_friend' ...

Exercício para você leitor! Altere o protected para private e veja o que acon-

tece. Depois, public.

Módulos

Módulos em Ruby são basicamente agrupadores de métodos, constantes, clas-

ses e variáveis. O uso é quase o mesmo de classes, porém não podemos criar uma

59

2.6. Classes e módulos

Casa do Código

instância de um módulo e usamos a palavra chave module, ao invés de class. Ou-

tra diferença é que não existe hierarquia de módulos, ou seja, não faz sentido um

módulo herdar de outro.

Módulo são usados de duas maneiras, usados como namespaces, ou seja, uma

boa maneira de agrupar classes, constantes e métodos quando pertinente (por exem-

plo, agrupar todas as classes que fazem parte do meio de pagamento de um site) ou

como mixins, uma forma de adicionar um comportamento comum a qualquer classe.

Veremos mais exemplos sobre essa importante funcionalidade.

Módulos como namespaces

Quando um sistema se torna grande, é importante agrupar diversas classes que

fazem parte de um componente em um namespace. Esta funcionalidade é de extrema

importância, por exemplo, quando temos diversas classes com o mesmo nome, seja

por um código que escrevemos ou por alguma biblioteca que usamos. Se não criar-

mos namespaces, comportamentos estranhos podem acontecer.

Para construir um módulo, basta usar uma sintaxe muito parecida com a de clas-

ses:

module Payment

class Purchase

end

end

Purchase.new # NameError: uninitialized constant Purchase

Payment::Purchase.new # => #<Payment::Purchase:0x007fac81d0b0f8>

No exemplo anterior podemos notar duas importantes características de módu-

los:

Módulos devem também ser nomeados como constantes, ou seja, CamelCase

com a primeira letra em maiúscula;

Quando declaramos uma constante ou classe dentro de um módulo, é neces-

sário explicitar o escopo via ::.

O uso do :: pode ser omitido no caso de estarmos dentro do módulo. Vejamos

um exemplo:

60

Casa do Código

Capítulo 2. Conhecendo Ruby

module Payment

MIN_COST_FOR_FREE_SHIPPING = 10.00

class Purchase

attr_accessor :total_cost

def calculate_shipping!

if total_cost >= MIN_COST_FOR_FREE_SHIPPING

puts "Parabéns, frete grátis para você!"

else

puts "Sem frete grátis :-("

end

end

end

end

purchase = Payment::Purchase.new

purchase.total_cost = 15.00

purchase.calculate_shipping! # Parabéns,

# frete grátis para você!

puts MIN_COST_FOR_FREE_SHIPPING # uninitialized constant

puts Payment::MIN_COST_FOR_FREE_SHIPPING # 10.0

Em algumas situações é possível que duas classes de mesmo nome sejam acessí-

veis em um escopo. Para isso, é possível explicitar integral ou parcialmente o escopo

usando o ::. Caso o escopo seja o escopo raiz, é possível declarar da seguinte forma:

::File. Isso irá fazer com que a resolução de nomes do Ruby vá buscar a classe ou

módulo File no nível raiz, sem nenhum módulo.

Para entender melhor como organizar projetos e escopos, veja o Capítulo 8 do

livro Ruby Best Practices [3].

Módulos como mixins

Mixins é uma das funcionalidades mais importantes do Ruby. Além de classes,

é possível declarar métodos de instância dentro de um módulo. Assim, é possível

misturar esses métodos em qualquer classe ou objeto. Dessa forma, é possível fazer

diversas classes obterem um conjunto de comportamento comum com apenas uma

linha de código.

61

2.6. Classes e módulos

Casa do Código

Dois exemplos básicos de mixins em Ruby são os módulos Comparable e

Enumerable.

O módulo Comparable, ao ser incluído em uma classe, basta que a

classe implemente o método <=> (também conhecido como spaceship method) e

ela ganha diversos outros comportamentos de graça, como <, <=, ==, >, >= e

between?. Com o Enumerable, implementar o método each faz com que a classe

ganhe várias funcionalidades, como all?, any?, map, count, detect e outros.

Veja a documentação do Ruby sobre Enumerable para mais detalhes (http://www.

ruby-doc.org/core-1.9.3/Enumerable.html).

Contudo, vamos a um exemplo simples para entender como mixins funcionam:

module Shipping

CUBED_WEIGHT_FACTOR = 167

def dimensional_weight

width * depth * height * CUBED_WEIGHT_FACTOR

end

end

class ShippingPrice

include Shipping

attr_accessor :width, :depth, :height

end

shipping = ShippingPrice.new

shipping.width = 0.5;

shipping.depth = 0.8;

shipping.height = 0.3;

shipping.dimensional_weight # 20.04

Para criar mixins, basta declarar um módulo e construir métodos diretamente

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке