:web_design
livros = Set.new [teste_e_design, web_design_responsivo]
for livro in livros do
p livro
end
# => Autor: Mauricio Aniche, Isbn: 123454,
Páginas: 247, Categoria: :testes
4.8
E agora?
No próximo capítulo veremos maneiras mais elegantes de iterarmos coleções,
usando características funcionais da linguagem Ruby. Exploraremos diversos mé-
todos úteis que existem nas APIs do Ruby.
64
Capítulo 5
Ruby e a programação funcional
Ruby é conhecida por ser uma linguagem relacionada ao paradigma Orientado a
Objetos, porém, também possui suporte ao paradigma funcional. Neste capítulo
mostrarei os conceitos gerais relacionados a programação funcional, e explicar como
a linguagem Ruby suporta estes conceitos e nos ajuda a criar códigos mais legíveis,
com manutenção mais fácil e principalmente mais eficiente.
5.1
O que é programação funcional
Fundamentalmente, a programação funcional é um paradigma de programação que
trata a computação como a avaliação das funções matemáticas e a capacidade de evi-
tar a mutabilidade de estado. O paradigma funcional enfatiza o uso das funções que
não alteram estado, ao contrário da programação imperativa. O paradigma foi fun-
damentado no ano de 1930 com o lambda calculus, um sistema formal desenvolvido
para investigar a definição de funções, aplicação delas e também a recursão.
5.2. Funções puras
Casa do Código
5.2
Funções puras
A principal diferença entre as funções matemáticas e as funções criadas nas lingua-
gens imperativas, é que na segunda, funções podem causar efeitos colaterais, alte-
rando o valor já calculado anteriormente. Na prática isso que dizer que ao criarmos
um função e a invocarmos, o seu resultado vai depender do estado atual no momento
em que ela for executada. No paradigma funcional as funções dependem apenas dos
argumentos que foram recebidos em sua chamada, sendo assim, invocar a função N
vezes resulta sempre no mesmo valor, por este motivo chamamos estas funções de
puras.
Eliminar estes efeitos colaterais facilita o entendimento do comportamento do
programa e também evita preocupações quando temos código sendo executado pa-
ralelamente, pois nosso código naturalmente se tornou Thread Safe.
A linguagem Ruby contempla várias características das funções puras. Vamos
tomar como exemplo a String, que possui vários funções (métodos) puras:
nome = "Lucas"
puts nome.upcase # => LUCAS
puts nome # => Lucas
No código acima criamos uma variável nome que possui o valor Lucas. A cha-
mada do método upcase ao invés de alterar a variável para guardar o valor LU-
CAS, retorna uma nova String com o valor em caixa alta. Você pode confirmar
este comportamento na linha criada após a chamada do método upcase que im-
prime o valor da variável nome, que é exatamente o mesmo valor que definimos na
declaração da variável.
O método upcase é uma função pura, porque não importa quantas vezes seja
invocado, retornará sempre o mesmo valor e também não causa efeitos colaterais.
O símbolo !
Ao mesmo tempo que Ruby contempla o paradigma funcional, ela também é
uma linguagem imperativa, ou seja, possui funções que focam em alterar o estado
dos dados. Existem vários métodos na API da linguagem que possuem o caractere !
após seus nomes. O caractere
! no final do nome do método é uma convenção, que
significa que o método deve ser usado com moderação, porque pode causar efeitos
colaterais. Por exemplo o método upcase!:
66
Casa do Código
Capítulo 5. Ruby e a programação funcional
nome = "Lucas"
puts nome.upcase! # => LUCAS
puts nome # => LUCAS
Como você pode notar ao executar este código, o método upcase! não é um
método funcional puro, porque possui efeitos colaterais que alteram a String den-
tro da variável nome. Por isso, sempre que utilizar algum método com ! no final,
tenha cuidado. O lado bom é que se precisarmos definir um método que irá alte-
rar o estado de um determinado objeto, podemos defini-los com o caractere ! no
final para que outros desenvolvedores estejam cientes do cuidado ao utilizar aquele
método.
5.3
Comandos que retornam valores
Literais, chamada de métodos, variáveis, estruturas de controle, todos estes coman-
dos são avaliados como expressões pelo interpretador Ruby. Vamos tomar como
exemplo o caso onde desejamos atribuir um determinado valor a uma variável se
uma condição for verdadeira e outro valor caso a condição seja falsa. Podemos criar
esse código em Ruby da seguinte maneira:
valor = nil
numero = "dois"
if numero == "um" then valor = 1
elsif numero == "dois" then valor = 2
else valor = 3
end
p valor # => 2
Porém o código acima pode ficar mais legível se aproveitarmos o poder da lin-
guagem Ruby de avaliar tudo como uma expressão:
numero = "dois"
valor = if numero == "um" then 1
elsif numero == "dois" then 2
else 3
end
p valor # => 2
67
5.3. Comandos que retornam valores
Casa do Código
Podemos nos aproveitar desta habilidade da linguagem de avaliar tudo como
uma expressão no momento que precisamos declarar várias variáveis com o mesmo