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

Шрифт
Фон

usados estão exemplifica-

dos em seguida:

frequency = { "hello" => 1, "world" => 2 }

frequency.keys

# ["hello", "world"]

frequency.values

# [1, 2]

frenquency.has_key?("hello")

# true

frequency.has_value?(3)

# false

Menção honrosa

É comum lidarmos com integrações com outros sistemas e APIs que retornam

construções complexas em hashes e quase sempre não são consistentes. Vejamos um

exemplo fictício abaixo:

20

Casa do Código

Capítulo 2. Conhecendo Ruby

user_data = {

'email' => 'cicrano@example.com',

'full_name' => 'Cicrano'

}

Imaginemos agora que queiramos acessar os atributos email, full_name e

address. address, porém, não está presente no exemplo de hash acima. Dessa

forma, ao fazermos o código abaixo, temos um problema:

address = user_data['address']

address.strip

# NoMethodError: undefined method `strip' for nil:NilClass

Por esse motivo, é bastante comum fazermos proteção contra nil usando uma

expressão idiomática. Dessa forma, nosso código fica mais limpo pois não temos

que ficar checando a existência de dados. Aplicando a expressão idiomática, temos

o resultado abaixo (para mais detalhes sobre essa expressão, veja na seção 2.4):

address = user_data['address'] || 'vazio'

address.strip

# "vazio"

Este caso é muito comum. Através do pouco usado método #fetch, temos uma

outra maneira de retornar um valor default, muito mais legível e sem problemas com

confusão de precedência de parâmetros:

address = user_data.fetch('address', 'vazio')

address.strip

# vazio

Notação para métodos

A comunidade Ruby adotou duas notações importantes quando se tra-

tam de documentação de métodos. Métodos começando com # indicam

que são aplicados à instâncias daquela classe, por exemplo Hash#fetch.

Métodos começando com : : ou . indicam métodos de classe, por exem-

plo Time::now.

O Ruby tem um comportamento às vezes indesejável de retornar sempre nil

quando a chave não existe:

21

2.3. Tipos e estrutura de dados

Casa do Código

user_data = {

'email' => 'cicrano@example.com',

'full_name' => 'Cicrano'

}

user_data['address']

# nil

Este caso é o que chamamos de falha silenciosa, ou seja, o código falhou, po-

rém, como não há erro, a execução do código segue adiante, ficando difícil perceber

quando há bugs. Dessa forma, quando fizer sentido tornar essa falha mais aparente,

podemos usar o #fetch sem fallback, disparando uma exceção KeyError quando a

chave não existe:

user_data = {

'email' => 'cicrano@example.com',

'full_name' => 'Cicrano'

}

user_data.fetch('address')

# KeyError: key not found: "address"

Símbolos

Símbolos são strings especiais. Símbolos são usados internamente pelo inter-

pretador MRI para localizar o método a ser executado em um objeto, portanto sua

implementação é tal que a torna imutável e única na instância do interpretador Ruby.

Ou seja, uma vez um símbolo mencionado e criado, ele vai existir por todo o período

de vida de execução do interpretador e nunca vai ser coletado pelo garbage collector:

a = "123"

b = "123"

a.object_id

# => 7022...7060

b.object_id

# => 7022...1360

a = :hello

b = :hello

22

Casa do Código

Capítulo 2. Conhecendo Ruby

a.object_id

# => 456328

b.object_id

# => 456328

O que é Garbage collector?

O garbage-collector é um mecanismo importante e complexo que faz

parte do interpretador do Ruby. Ele é capaz de rastrear todos os recursos

usados e não usados no sistema, de forma a liberar memória não utili-

zada ou alocar mais memória para seu programa quando necessário.

Em termos práticos, no Ruby 1.9.3, versão que usamos, isso não significa muita

coisa. Porém, símbolos possuem outro valor: são usados no lugar de strings para

serem identificadores especiais quando estamos nos referindo a métodos:

"string".respond_to? :upcase

# true

Também acontece para chaves de Hash, com

uma pequena diferença:

Símbolos devem ser usados quando nos tratamos de metadado e não dado em

si. O que isso quer dizer? Usamos símbolos quando estamos descrevendo o

tipo do dado e não dando um valor possível;

Strings devem ser usadas quando a chave é um valor e não um descritor de

dados.

Exemplificando as duas regras:

# Exemplo 1 - usando símbolos

{

:name => 'Fulano',

:email => 'fulano@example.com',

}

# Exemplo 2 - usando ambos

{

:people => {

'Fulano' => {

23

2.3. Tipos e estrutura de dados

Casa do Código

:email => 'fulano@example.com'

}

}

}

Podemos facilmente converter strings em símbolos e vice-versa:

"um_simbolo".to_sym

# :um_simbolo

:um_simbolo.to_s

# "um_simbolo"

"E se a palavra for muito grande?".to_sym

# :"E se a palavra for muito grande?"

# Ainda é possível usar a notação de string para fazer interpolação!

method = 'flatten'

:"#{method}!"

# :flatten!

Ranges

Já vimos Ranges algumas vezes em outros exemplos. Range é um tipo interes-

sante e simples. Um objeto Range possui um início, um fim e dois ou três pontos

entre eles:

1..5 # Números inteiros entre 1 a 5, com o 5 inclusive

1...5 # Números inteiros entre 1 a 4, o 5 fica de fora

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

0
Шрифт
Фон

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