4.

Pequenas Folhas de Código Flutuando

[o]

Impossivelmente fundo, nas cavernas de Ambrose... o Gnomo com um presunto de estimação!
Tirinha: No fundo, do muito escuro e vil coração de Wyvrnn, passava o rio Selis, mascarando as cortes dos Grifos de Mal Abochny, sobre faixas de florestas selvagens, saturadas com os corpos de gigantes derrubados no 6o apocalipse, escavados e enterrados por unicórnios com chifres-brocas (e do vazio destes corpos nasciam mais unicórnios, preeenchendo as frágeis extremidades e forçando os gigantes sem vida a andar!), lá embaixo, embaixo da vegetação coberta por musgo, embaixo da verdadeira terra, no real, real, real (você sente o real? Em caso afirmativo, gostaria de saber), cavernas secretas em operação, pedras vetrificadas, 1400 pés quadrados com armários apertados, valorizados para o movimento, as cavernas de Ambrose, tudo na companhia de… O gnomo com um presunto de estimação!
Eu tenho um monte de animais legal!
todos os seus aniamis de estimação acabaram de partir em um ônibus!

...e o gato Negociador Blix.

Eu nunca vi o presunto fazer coisa alguma, a não ser mijar. Hoje, nosso negócio nas Cavernas Ambrose é com o gnomo. Ele é uma parte crucial das próximas lições. Vamos todos fazer com que ele se sinta bem-vindo. Comece a esquentar os neurônios! (E por favor, troque essa ridícula calça de caubói.)

Atenção: esta lição é mais vagarosa. Acompanhe-a. Isto será uma longa e profunda respiração. A fase mais crucial de sua instrução. Pode parecer que você não está aprendendo muito código a princípio. Você estará aprendendo conceitos. Ao final deste capítulo, você saberá a beleza do Ruby. O conforto do código irá se tornar um saco de dormir para o seu próprio alívio.

1. A Folha como um Símbolo de Status na Ambrose

Tudo certo, Gnomo. Dê-nos um rápido resumo dos problemas financeiros que você enfrentou lá no seu reino.

Cristais azuis foram maltratados.
Tirinha: Bem, nós uma vez usamos cristais azuis (como dinheiro). Mas é realmente muito escuro aqui nas cavernas para ver se algo é azul. Sim, mas você pode guardar dinheiro na sua sunga de natação sem se preocupar. de qualquer modo, todos os insetos e besouros usam folhas como dinheiro. e eles não carregam cristais azuis porque eles são muito pesados, então nós trocamos.
Realmente, não é o caminho que eu me lembro. Esse Gnomo estava me bipando constantemente. Quando me recusei a chamá-lo de volta, ele deixou uma mensagem no meu pager. Significado: ele bipou duas vezes e então exibiu uma pequena mensagem. A mensagem disse alguma coisa sobre, “Desça aqui, rápido!” e também, “Nós temos que livrar a terra destas pestes de lagartas empreendedoras, estes insetos insanos Vikings estão sufocando meus cristais azuis!”

Ultimamente, a taxa de câmbio já se estabelece entre as folhas e cristais. Uma nota de árvore velha vale cinco cristais. Então a situação monetária básica é semelhante a isto:

 cristal_azul = 1
 folha_macia = 5

Este exemplo é tão último capítulo. Ainda assim. Ele é um início. Nós estamos definindo duas variáveis. O sinal de igual é usado para atribuição.

Agora folha_macia representa o número 5 (tal como em: cinco cristais azuis.) Este conceito, até aqui, é metade de Ruby. Nós estamos definindo. Nós estamos criando. Isso é a metade do trabalho. Atribuição é a forma mais básica de definição.

Você não pode se queixar, pode Gnomo? Você construiu um império investindo seus cristais azuis no novo mercado livre entre as criaturas da floresta. (E apesar de ele ser um gnomo para nós, ele é um monstro grande para eles.)

Animal Perfeito, LLC
Tirinha: Sem dúvida, por quê…. Smotchkkiss pegou este caminho. Bem-vindo aos laboratórios subterrâneos da Animal Perfeito, LLC. Eu investi todos os cristais que tinha na Animal Perfeito. Quer me ver fazendo um macacoestrela?

Nananinanão. Pera um segundo. Você não está pronto para o que o Gnomo aqui faz em suas cavernas. Você pensará que é tudo positivamente desumano, doentio, pirado, yada yada.

Agora Você irá Escutar a Declaração da Animal Perfeito Porque Isto É Um Livro E Nós Temos Tempo e Nenhuma Pressa, Certo?

Há muito tempo atrás, muito, muito antes das lanchas motorizadas eu possuía uma égua de corrida premiada que levou um tropeção na pista. Ela capotou dez vezes e bateu num cara que carregava um vidro cheio de maionese. Nós tínhamos sangue e maionese para tudo quanto é lado da pista. Desnecessário dizer, ela era um desastre.

O veterinário deu uma olhada e jurou que ela nunca voltaria a andar. Tinha perdido as pernas e o veterinário não permitiria que uma égua sem pernas ficasse apenas sentada por aí. Nós precisamos abatê-la. Ele jurou por sua vida e por sua carreira nisto, insistindo que nos dividíssemos em duas linhas paralelas. As pessoas que não podiam refutar as afirmações do médico de um lado; aqueles muito cabeça-duras para aceitar seu raciocínio médico infalível do outro. O Gnomo, seu animal de estimação de presunto e eu éramos os únicos nesta segunda linha.

Então enquanto os outros empilhavam troféus e guirlandas de flores em volta da égua, despedindo-se com carinho antes que a bala viesse e a levasse para casa, o Gnomo e eu freneticamente vasculhamos a Internet por respostas. Nós lidamos com isso com nossas próprias mãos, cauterizando as feridas em sua perna com camarões de água doce vivos. E funcionou bem! Nós tínhamos uma égua de novo. Ou pelo menos: um corpo de égua com um abdominal de crustáceos congelantes.

Ela correu para todo lado depois disso e viveu por anos em cavernas úmidas no subsolo.

A Animal Perfeito é agora o futuro do melhoramento de animais. Eles criam novos animais e salvam animais velhos por partes. É claro, levou um longo tempo para isso. Quando o Animal Perfeito começou, você via um urso crescido adentrar o Animal Perfeito e via um urso crescido de óculos de sol sair. Completamente cafona.

Fique por aí e você verá um caranguejo com sua própria mochila foguete Esse é um novo modelo caranguejet 2004.

Mas agora, a operação está a todo vapor. E a limpeza do lugar é impressionante. Todo o equipamento é tão brilhoso. Tudo é cromado. Ah, e toda a equipe tem armas escondidas. Eles são treinados para matar qualquer um que entre sem ser anunciado. Ou, se eles ficarem sem balas, eles são treinados para acertar com as armas qualquer um que entre sem ser anunciado.

Gnomo, me faça uma macacoestrela.

Primeiro, a estrela é capturada.

Um pouco de Ruby imaginário para você:

tubo.pegue_uma_estrela

Variável tubo. Método pegue_uma_estrela. Muitos Rubistas gostam de pensar em métodos como mensagens. A quem vier antes do método é dada a mensagem. O código acima diz ao tubo: pegue_uma_estrela.

Esta é a segunda metade do Ruby. Colocar as coisas em movimento. Estas coisas que você define e cria na primeira metade começam a agir na segunda metade.

  1. Definindo coisas.
  2. Colocando essas coisas em ação.

Então e se o código de pegar estrelas funcionar? Pra onde a estrela vai?

estrela_presa = tubo.pegue_uma_estrela

Veja, você que deve coletar a coitada da estrelinha. Se não o fizer, ela vai simplesmente desaparecer. Toda vez que você usa um método, você recebe algo de volta. Você pode ignorá-lo ou usá-lo.

Se você conseguir aprender a usar as respostas que os métodos lhe dão, então você irá dominar.

A estrela é ajustada na cara do macaco.
Tirinha: Preste atenção! Macaco & Estrela! Então, uma catraca dentro da máquina apenas ajusta a estrela na cara do macaco. Gira, gira e gira até que eles fiquem juntos.
Rapidamente então.

macacoestrela = ajuste.conecta( macaco_preso, estrela_presa )

O ajuste recebe uma mensagem conecta. O que precisa ser conectado? Os argumentos do método_: o macaco_preso e a @estrelapresa@. Nós recebemos de volta um macacoestrela, em quem decidimos nos pendurar.

Sapo na mão.

Este tem se mostrado um programinha tão curto e pequeno que eu vou apenas colocá-lo todo em uma única declaração.

macacoestrela = ajuste.conecta( macaco_preso, tubo.pegue_uma_estrela ) + sapo_de_mao_decorativo

Vê como o tubo.pegue_uma_estrela está nos argumentos do método? A estrela pega será passada diretamente ao ajuste. Não é necessário encontrar um lugar para colocá-la. Apenas deixe-a ir.

2. Pequeno e Quase Sem Valor

Law-va.

O hotel aqui em Ambrose não é nem um pouco bom. As camas são todas tortas. O elevador é minúsculo. Um cara pôs toda sua bagagem no elevador e não sobrou mais lugar para ele. Ele apertou o botão e as perseguiu pelas escadas. Mas as escadas eram muito estreitas e ele ficou entalado tentando subir.

Os mini-sabonetes que eles te dão são dimensionados para gnomos, então é impossível fazer uma espuma. Eu odeio isso. Toda hora eu confundo eles com lentes de contato.

Eu abri a torneira e nada saiu. O caso é o seguinte: Ambrose é um lugar com propriedades mágicas, então eu me arrisquei. Coloquei minha mão embaixo da torneira. Invisível, umidade morna. Eu senti a sensação de água corrente, passando pelos meus dedos. Quando tirei minha mão de lá, elas estavam secas e limpas.

Foi uma incrível experiência de vazio total. Foi como nil.

Nil (Nada)

No Ruby, o nil representa o vazio. Ele representa falta de valor. Ele não é zero. Zero é um número.

É um morto-vivo do Ruby, uma palavra chave falecida. Você não pode adicionar à ele, ele não evolui. Mas ele é terrivelmente popular. É este esqueleto sorrindo nas fotos.

copo_plastico = nil

No código acima copo_plastico está vazio. Você pode argumentar que o copo_plastico contém algo, um nil. O nil representa vazio, logo, então, adiante-se e chame-o de vazio.

Alguns de vocês que já programaram antes estarão tentados a dizer que copo_plastico está indefinido (undefined). Que tal não. Quando você diz que uma variável está indefinida, você está dizendo que o Ruby simplesmente não tem lembrança da variável, ele não a conhece, ela absolutamente não existe.

Mas o Ruby está sabendo do copo_plastico. Ruby pode facilmente olhar dentro do copo_plastico. Está vazio, mas não está indefinido.

False (Falso)

Forma de um gato.

O gato Blix Negociador. Congelado no vazio. Rígido e refinado bigode. Serenos olhos de lago. Rabo de morno sincelo. Patrocinado por um Botão de Pausa Bastante Poderoso.

A escuridão que circunda o Blix pode ser chamada de espaço negativo. Atente-se nessa frase. Deixe ela sugerir que o vazio tem conotação negativa. De um jeito similar, nil tem uma nota levemente amarga que ele assobia.

Generalizando, tudo no Ruby tem uma carga positiva. Esta fagulha corre por strings, números, regexps (expressões regulares), todos eles. Somente duas palavras reservadas vestem uma capa sombria: nil e false nos trazendo para baixo.

Você pode testar essa carga com a palavra chave if (se). Ela se parece muito com o o bloco do que vimos no último capítulo, no qual ambas terminam com um end.

 if copo_plastico
   print "O copo de plástico está transbordando!"
 end

Se copo_plastico contiver nil ou false, você não vai ver nada impresso na tela. Eles não estão na lista de convidados do if. Então o if não vai rodar nada do código que ele está protegendo.

Mas nil e false não precisam ir embora constrangidos. O caráter deles pode ser meio questionável, mas o unless (ao menos) gerencia um estabelecimento que preza ser fuleiro. A palavra chave unless tem por regra só deixar aqueles com carga negativa entrar. Aqueles são: nil e false.

 unless copo_plastico
   print "O copo plástico está vazio."
 end

Você também pode usar if e unless no fim de uma linha de código, se apenas aquela linha estiver sendo protegida.

 print "Yeah, o copo plástico está cheio de novo!" if copo_plastico
 print "Dificilmente. Ele está vazio." unless copo_plastico

E mais uma manha: empilhar o if e unless.

 print "Estamos usando copos de plástico pois não temos de vidro." if copo_plastico unless copo_vidro

Este truque é um lindo jeito de expressar: Faça isso só se a for verdadeiro e b não for verdadeiro.

Agora que você já conhece o false, tenho certeza que pode ver o que vem a seguir.

True (Verdadeiro)

sujeito_aproximando = true

Eu vi o true no Buffet do hotel hoje. Eu não suporto aquele cara. Ele aparece demais. E você nunca encontrou alguém que plantou os pés com tanta força no solo. Ele usa esse colar brega feito de conchas. Sua face exibe uma confiança insolente. (Você pode dizer que ele está exercendo toda sua repressão só para evitar de explodir num vôo do Neo.)

Para ser honesto, não consigo ficar do lado de alguém que sempre tem de estar certo. Esse true está sempre dizendo, “A-OK.” Chacoalhando as duas mãos. E é sério, ele ama aquele colar. Ele o usa constantemente.

Como suspeitava, ele está por trás dos bastidores para toda a agenda de eventos do if.

print "Hugo Boss" if true se comporta como print "Hugo Boss".

Ocasionalmente, o if vai puxar as cordas vermelhas para exercer algum controle de massas. O par de iguais dá a aparência de uma passagem, como cordas dos lados de um carpete vermelho onde só é permitida a passagem de true.

 if sujeito_aproximando == true
   print "Esse colar é clássico."
 end

O par de iguais é simplesmente uma checagem de identidade. Os cavalheiros das pontas opostas desta corda parecem ser iguais?

Desse jeito, você controla quem o if deixa entrar. Se você não suporta o true assim como eu, receba de peito aberto o false (falso).

 if sujeito_aproximando == false
   print "Chega mais, seu diabo conivente."
 end

Mesma coisa para unless. O portão é seu. Tome o controle dele.

Novamente, Eu Quero Que Você Domine

Agora, está afim de uma viagem mental? O sinal de dois iguais é um método. Você consegue adivinhar como ele funciona? Aqui, dê uma olhada nele com ponto e parênteses:

sujeito_aproximando.==( true )

Ruby permite o atalho, sem problemas. Abandone o ponto e recue, vagarosamente.

Agora, você se lembra o que deve fazer para dominar no Ruby? Use as respostas que os métodos lhe dão.

 if nil.==( true )
   print "Isto nunca vai acontecer."
 end

No exemplo acima, como a resposta do método esta sendo usada?

Pegue a afirmação nil == true. Isso falhará o tempo todo. Não são iguais. Quando não há igualdade, o método do duplo igual responde com false. Uma balançada de cabeça. Esta resposta é dada ao if, que não pode aceitar um false. O print nunca acontecerá.

 no_hotel = true
 email = if no_hotel
           "why@hotelambrose.com"
         else
           "why@drnhowardcham.com"
         end

Mesmo que if não seja um método, o if retorna uma resposta. Observe o exemplo acima e imagine o que acontece quando no_hotel é true.

O if retornará a resposta dada pelo código que ele decidir rodar. No caso de no_hotel ser true, a primeira string, meu endereço de e-mail no Hotel Ambrose, será retornada. A palavra reservada else marca o código a ser rodado, uma vez que o if falhe. Se no_hotel é false, o if responderá com meu endereço de e-mail do escritório do Dr. N. Howard Cham, onde eu recebo meu aprendizado.

Você deve ter várias linhas de código dentro de um if ou unless, mas somente a resposta oriunda da última afirmacão completa será usada.

 email = if no_hotel
           endereco = "why"
           endereco << "@hotelambrose"
           endereco << ".com"
         end

Três linhas de código dentro do if. A primeira linha atribui uma string contendo meu nome a uma variável. A segunda e terceira linha adicionam o resto do meu endereço de e-mail no fim. O menor que duplo << é o operador da concatenação. Concatenar é o mesmo que apender, ou adicionar ao fim.

Assim como vimos com o checador de igualdade ==, o concatenador é um método. Após acrescentar ao fim da string, o concatenador ainda responde com aquela mesma string. Então, a terceira linha, que pode ser lida como endereco.<<( ".com" ), retorna endereco, que o if então devolve para a atribuição email.

Uma pergunta: E se o if falhar? E se no_hotel for falso no exemplo acima? Alguma coisa será retornada? Nada é atribuído a email, certo?

Sim, nada é retornado. Que significa que: nil é retornado. E, muitas vezes, nil é uma resposta bastante útil.

 print( if no_hotel.nil?
          "Sem pistas se ele está no hotel."
        elsif no_hotel == true
          "Definitivamente sim."
        elsif no_hotel == false
          "Ele saiu."
        else
          "O sistema está traaaaavad-iz"
        end )

Você pode usar o método nil? em qualquer valor no Ruby. Novamente, pense nele como uma mensagem. Para o valor: “Você é nil? Você está vazio?”

Se no_hotel estiver vazia, o Ruby não tem idéia se eu estou no hotel ou não. Então o if responde com a string “Sem pistas”. Para tratar as possibilidades de true ou false, a palavra reservada elsif é usada. Enquanto você pode ter apenas um if e um else, você pode encher as entranhas com um exorbitante número de palavras chave elsif. Cada elsif age como um outro teste if. Checando por uma carga positiva.

Se você está indo bem até este ponto, então está em boa forma para o restante do livro. Você viu um código bem difícil nos últimos exemplos. Forte companheiro.

3. Encadeando Desilusões

55.000 macacoestrelas e um espirituoso esperança de medalha Olímpica.

Você termina de ler a tirinha acima e se retira para seu sofá-cama para reflexão. É um daqueles assuntos encobertos que são sempre obstruídos por travesseiros. Você se senta sobre a pilha, observando o mundo lá do alto. Você vê as altas chaminés expelindo largos cilindros de fumaça e névoa. Nas complicadas junções das auto-estradas, um trânsito ligeiro, nada é cintilante senão um músculo ocular pulsando do seu ponto de vista superior.

É tudo tão fantástico. Como as cores do horizonte se espalham através da paisagem como uma grande mistura de manteiga e gordura com uma colher de sopa de extrato de baunilha.

Mesmo com toda a beleza que lhe chama a atenção, as imagens do Gnomo e sua Esperança Olímpica retornam. E especialmente, aquele pedido por 55.000 macacoestrelas. 55.000 macacoestrelas, pensa você Cinqüenta-e-cinco Mil.

Você pensa somente no próprio número. 55.000 Ele está descendo uma rua. Ele pode estar numa floresta, você não sabe ao certo a medida que seus olhos estão fixos nos próprios números. Está parando e falando com pessoas. Com jogadores de tênis, com um grupo de coral masculino. Há alegria e uma boa sensação. Quando ele ri, os seus zeros agitam-se com alegria.

Você quer falar com ele. Você quer saltitar por aquele caminho da floresta com ele. Você quer embarcar num jato com destino ao Brasil com ele. E depois de cinco dias e quatro noites no prazeroso Spa & Resort Marriot da Costa do Sauípe, quererá casar com ele, para sustentar uma família de 55.000 macacoestrelas com ele.
Com uma voadora, você derruba sua pilha de travesseiros de isolamento. Mexendo com a chave, você destrava a gaveta de cima de sua escrivaninha e puxa uma folha de papel, segurando-a firmemente sobre a escrivaninha. Você começa a escrevinhar.

Tome posse da Nigéria com meus 55.000 macacoestrelas
Com ela, construa um casino somente para vegetarianos casino e uma arena de kart
Asas… nós poderíamos ter nosso próprio molho especial nelas, que seja diferente
Mostarda + codeína = O Molho Estrelado Macacoestrelado Brilhante do Smotchkkiss
Franquia, franquia… logos
Vídeos de instrução para funcionários
Quando você dá o troco para o consumidor, deixe que ele alcance o sapo que está na sua mão para pegá-lo
Se ele não tiver troco, pelo menos ponha a nota dele em um lugar onde ele tenha que tocar no sapo
Nós estamos passando este campo para um próximo nível
Faça propaganda de pizza barata, vamos lucrar com o refrigerante
Colecione todos os 4 copos congelados

Uau, as idéias estão mesmo saindo. Você teve que literalmente se beijar para parar. Nós precisamos colocá-las num lugar seguro. Na verdade, deveríamos armazená-las no seu computador e deformar as palavras. Mantenha os olhos na janela e vigie para ver se o FBI não vem. Eu vou começar esse script.

O Script Invertedor

print "Digite e seja diabólico: "
ideia_contrario = gets.reverse

Deixe este script ser seu confidente. Ele perguntará por planos malignos e reverterá suas letras de trás para frente. O método gets é construído dentro de Ruby. É um método de kernel como o print. Este método gets pausará o Ruby para deixar que você digite. Quando você apertar o Enter, gets irá então parar de prestar atenção aos seus esmurros no teclado e responderá de volta ao Ruby com uma String contendo tudo o que você digitou.

O método reverse é então usado na String que o gets está devolvendo. O método reverse é parte da classe String. O que significa que tudo que for uma string tem o método reverse disponível. Mais sobre classes no próximo capítulo, por enquanto saiba apenas que alguns métodos só estão disponíveis para certos tipos de valores.

Eu não acho que o reverse dará muito certo. As autoridades só precisam pôr um espelho na frente de “airégiN ad elortnoc o emoT.” Prenderão a gente quando os macacoestrelas começarem a pousar em Lagos.

As letras maiúsculas estão nos entregando. Talvez se passássemos todas as letras na string para maiúsculas antes de inverter.

 ideia_ao_contrario = gets.upcase.reverse

Sua Repetitividade Compensa

Você me entrega um bloco de notas, cheio de garranchos ilegíveis. Analisando, começo a notar padrões. Notar que você parece usar as mesmas palavras repetidamente em suas reflexões. Palavras como macacoestrela, Nigéria, bomba. Algumas frases até. Ponha um fim nisso. Que são ditas toda hora.

Vamos disfarçar esses termos bobos, meu irmão. Vamos ofuscá-los de olhos ardentes que choram para saber nossos delicados planos e para nos demover de termos grande prazer e muitos karts. Vamos trocá-los pela mais inocente linguagem. Novas palavras com significado secreto.

Eu comecei uma lista de palavras, um Hash do Ruby, que contém estas suas palavras tão freqüentes e perigosas. No Hash, cada palavra perigosa é comparada contra uma palavra código (ou frase). A palavra código será então trocada pela palavra real.

 palavras_codigo = {
   'macacosestrela' => 'Phil e Pete, aqueles chanceleres de pavio curto do Novo Reich', 
   'catapulta' => 'chucky go-go', 'bomba' => 'Vida Assistida por Calor', 
   'Nigeria' => "Ny e Jerry's Lavagem a Seco (com Donuts)",
   'Ponha um fim nisso' => 'Ponha um fio nisso'
 }

As palavras que são colocadas antes da seta são chamadas chaves. As palavras depois das setas, as definições, geralmente são simplesmente chamadas de valores.

Note as aspas duplas em volta de Ny e Jerry's Lavagem a Seco (com Donuts). Já que nas aspas está sendo usado um apóstrofo (aspas simples), nós não podemos usar aspas simples em torno da string. (Todavia, você pode usar aspas simples se colocar uma barra invertida antes do apóstrofo como em: 'Ny e Jerry\'s Lavagem a Seco (com Donuts)'.)

Se você precisar procurar por uma palavra em específico, pode usar o método dos colchetes.

palavras_codigo['catapulta'] irá responder com a string 'chucky go-go'.

Olhe os colchetes como se fossem paletas de madeira nas quais as palavras estão em cima. Uma empilhadeira poderia usar suas pás em cada lado da palete e a trazer da prateleira de volta ao depósito. A palavra na palete é chamada de indexador. Estamos pedindo para a empilhadeira achar o indexador para a gente e nos trazer de volta o valor correspondente.

Se você nunca esteve num depósito, você pode ver as chaves como alças. Imagine um trabalhador industrial colocando suas luvas e levando o índice de volta à sua custódia. Se você nunca usou uma alça, vou lhe dar cerca de trinta segundos para achar uma e usar antes que eu estoure meus miolos.

Assim como os vários operadores que você viu recentemente, os colchetes indexadores são simplesmente um atalho para um método.

palavras_codigo.[]( 'catapulta' ) responderá com a string 'chucky go-go'.

Fazendo a Troca

Eu me adiantei e salvei o Hash de código em um arquivo chamado listadepalavras.rb.

 require 'listadepalavras'

 # Pegar a idéia do mal e converter em palavra código
 print "Entre com sua nova idéia: " 
 ideia = gets
 palavras_codigo.each do |real, codigo| 
   ideia.gsub!( real, codigo )
 end

 # Salva o papo-furado num novo arquivo
 print "Arquivo codificado.  Favor entrar com um nome para essa idéia: "
 nome_ideia = gets.strip
 File::open( "ideia-" + nome_ideia + ".txt", "w" ) do |f|
   f << ideia
 end

O Script começa puxando nossa lista de palavras. Assim como gets e print, o método require é um método do kernel, você pode usá-lo em qualquer lugar. Eu dei a ele a string 'listadepalavras' e ele vai procurar um arquivo chamado listadepalavras.rb.

Depois disso, há duas seções. Estou marcando estas seções com comentários, as linhas que começam com o símbolo cerquilha (jogo-da-velha) #. Comentários são notas úteis que acompanham seu código. Colegas que vierem ver seu código vão apreciar tal ajuda. Você mesmo, quando olhar para seu código novamente depois de algum tempo, comentários vão te ajudar a retomar o fio da meada. E ainda existe softwares por aí que pegam seus comentários e fazem documentação à partir deles. (RDoc e Ri — veja o Pacote de Expansão #1!)

Eu gosto de comentários porque posso passar os olhos por uma grande pilha de código e identificar pontos importantes.

Como os comentários nos dizem, a primeira seção pergunta por uma idéia maléfica e a troca por uma palavra código. A segunda seção salva a idéia codificada num novo arquivo de texto.

 palavras_codigo.each do |real, codigo| 
   ideia.gsub!( real, codigo )
 end

Você viu o método each? O método each está em todo lugar no Ruby. Está disponível para Arrays, Hashes, até Strings. Aqui, nosso dicionário palavras_chave é mantido numa Hash. Este método each corre entre todos os pares da Hash, cada palavra perigosa é comparada com sua palavra código, mandando cada par para o método gsub! para a troca atual.

No Ruby, gsub é abreviação de global substitution (substituição global). O método é usado para procurar e substituir. Aqui, queremos achar todas as ocorrências de palavras perigosas e substitui-las com a segura palavra código. Com gsub, você provê a palavra a ser achada como primeiro argumento, depois a palavra que tomará o lugar como segundo argumento.

Por que nós não estamos aguardando a resposta do gsub? O gsub não nos dá um resposta que devemos guardar? Você acha que a linha deveria ser assim:

 ideia_segura = ideia.gsub( real, codigo )

Sim, com gsub nós temos que ficar com a resposta. Estamos usando uma variação do gsub que é totalmente hiper. Notou a exclamação no gsub! usada dentro de cada bloco each? A exclamação é um sinal de que gsub! é meio radical. Veja, gsub! vai mais longe e troca as palavras em ideia diretamente. Quando ele termina ideia vai conter a nova string alterada e você não vai mais achar a string velha.

Pode chamar gsub! de método destrutivo. Ele faz suas modificações no valor diretamente. Enquanto gsub deixa o valor intacto, apenas respondendo com uma nova string que contém as alterações. (Por que o gsub! tem que gritar quando ataca sua presa? Assaltante cruel!)

Arquivos de Texto de um Louco

Vamos salvar a idéia codificada em um arquivo.

 # Salva as palavras sem sentido em um novo arquivo
 print "Arquivo codificado.  Favor entrar com um nome para essa idéia: "
 nome_ideia = gets.strip
 File::open( 'ideia-' + nome_ideia + '.txt', 'w' ) do |f|
   f << ideia
 end

Esta seção começa perguntando por um nome pelo qual a idéia possa ser chamada. Este nome será usado para se fazer o nome do arquivo quando salvarmos a idéia.

O método strip serve para todas as strings. Este método corta espaços e linhas vazias do começo e do fim de uma string. Isso removerá o Enter no fim da string que você digitou. E também removerá espaços caso você tenha acidentalmente deixado algum.

Depois que temos o nome da idéia, vamos abrir um novo arquivo de texto em branco. O nome do arquivo é construído adicionando-se strings. Se você digitou 'mostarda-mais-codeina', nossa matemática será: 'ideia-' + 'mostarda-mais-codeina' + '.txt'. O Ruby pressiona isso em uma única string. 'ideia-mostarda-mais-codeina.txt' é o arquivo.

Estamos usando o método de classe File::open para criar um novo arquivo. Até agora, nós usamos vários métodos do kernel para fazer nosso serviço. Nós damos uma string para o método print e ele a imprime na nossa tela. Um segredo sobre métodos do kernel como o print: eles são na verdade métodos de classe.

Kernel::print( "55.000 Macacosestrelas o Saúdam!" )

O que isso significa? Por que isso importa? Significa que o Kernel é o centro do universo Ruby. Sempre que você está no seu código, o Kernel estará do seu lado. Você nem precisa dizer Kernel pro Ruby. O Ruby sabe checar o Kernel.

A maioria dos métodos são mais especializados que print ou gets. Pegue File::open por exemplo. O criador do Ruby, Matz, nos deu vários métodos diferentes que lêem, renomeiam, ou deletam arquivos. Eles estão todos organizados dentro da classe File.

File::read( "ideia-mostarda-mais-codeina.txt" ) responderá com uma string contendo todo o texto do seu arquivo de idéias. (Read significa ler.)

File::rename( "arquivo_antigo.txt", "arquivo_novo.txt" ) renomeará o arquivo_antigo.txt.

File::delete( "arquivo_novo.txt" ) explodirá o novo arquivo.

Esses métodos File estão todos dentro do Ruby. Estão apenas armazenados num contêiner chamado Classe File. Então, enquanto você pode seguramente chamar os métodos do kernel sem precisar digitar Kernel, o Ruby não checa automaticamente a classe File. Você precisa dizer o nome do método completo.

 File::open( 'ideia-' + nome_ideia + '.txt', 'w' ) do |f|
   f << ideia
 end

Nós passamos dois argumentos dentro de File::open. O primeiro é o nome do arquivo para abrir. O segundo é uma string contendo o modo do arquivo. Usamos 'w', que significa escrever em um novo arquivo. (Outras opções são: 'r' para ler o arquivo ou 'a' para adicionar no fim do arquivo.)

O arquivo está aberto para escrita e nos é dado na forma da variável f, que pode ser vista descendo a calha para dentro do nosso bloco. Dentro do bloco, nós escrevemos no arquivo. Quando o bloco se fecha com end, nosso arquivo é fechado também.

Note que nós usamos o concatenador << para escrever no arquivo. Podemos fazer isto porque arquivos têm um método chamado <<, assim como as Strings.

Acalme-se, Suas Idéias Não Estão Presas

Aqui, vamos pegar nossas idéia de volta em seus verbos originais, para que você possa ruminar sobre o brilhantismo delas.

 require 'listadepalavras'

 # Imprima cada idéia com as palavras corretas
 Dir['ideia-*.txt'].each do |nome_arquivo|
   ideia = File.read( nome_arquivo )
   palavras_codigo.each do |real, codigo| 
     ideia.gsub!( codigo, real )
   end
   puts ideia
 end

A esta altura, você já deve estar sabendo o que este exemplo faz. Não vou te incomodar com detalhes mundanos. Veja se você consegue entender sozinho como isso funciona.

Contudo, temos um método de classe interessante aqui. O método Dir::[] procura em um diretório (alguns de vocês podem chamá-lo de “pasta”). Assim como você viu com os Hashes, os colchetes indexadores podem ser métodos de Classe. (Você começa a ver o brilho e suntuosidade cintilante do Ruby?)

Então nós estamos usando a empilhadeira para pegar os arquivos no diretório que coincidem 'ideia-*.txt'. O Dir::[] irá usar o asterisco como um coringa. Estamos basicamente dizendo, “Encontre tudo que comece com ideia- e termine com .txt.” A empilhadeira vai para o diretório e volta com uma lista de arquivos encontrados.

Esta lista de arquivos vem na forma de Array, a Centopéia, com uma String para cada arquivo. Se você está curioso e quer brincar com Dir::[], tente isto:

p Dir['ideia-*.txt'] irá imprimir:

['ideia-mostarda-mais-codeina.txt'] (um Array de nomes de arquivos!)

Sim, o método p funciona igual print. Mas print é para se imprimir strings, enquanto p irá imprimir qualquer coisa. Veja isso.

p File::methods irá imprimir:

["send", "display", "name", "exist?", "split",a lista completa dos nomes dos métodos! ]

4. O Milagre dos Blocos (Blocks)

Entregadores de flores?  Já ouvi essa antes.

Já que estamos ficando íntimos enquanto compartilhamos este tempo juntos, eu provavelmente deveria te falar um pouco mais sobre a história que aqui se passa. É uma boa hora para uma pausa, eu diria.

Primeiramente, você deve saber que o Blix é meu gato. Meu segundo animal de estimação é o Bigelow. E digo, nós dificilmente nos vemos mais. Ele é totalmente auto-suficiente. Eu não sei exatamente onde ele mora hoje em dia, ele não mora mais na ante-sala do meu quarto. Ele esvaziou sua conta bancária há cerca de sete meses.

Ele tem uma cópia da chave de casa e uma do Cadillac Seville. Se algum dia quiser voltar, eu alegremente deixarei de lado nossas diferenças e me entreterei novamente com suas travessuras em torno de casa.

Mas não se engane. Eu sinto falta dele por perto. Não sei se ele sente falta da minha companhia, mas eu sinto a dele.

Uma Sirene e Uma Oração

Eu vi o Blix pela primeira vez na televisão quando eu era um garoto. Ele estrelava um drama policial empoeirado chamado Uma Sirene e Uma Oração. O seriado era sobre um esquadrão policial religioso que fazia seu serviço, e o fazia bem, e tinham suas cotas de milagres nas ruas. Quero dizer, os oficiais no show eram ótimas pessoas, muito religiosos, praticamente um sacerdote. Mas, você sabe, até sacerdotes não têm o bom senso de matar um cara que tenha ido longe demais. Esses caras sabiam onde traçar a linha. E chegavam nessa linha todos os dias.

Então, aquilo era um seriado bem sangrento, mas eles sempre tinham uma boa lição de moral no final. Na maioria das vezes algo como, “Nossa, escapamos dessa bem rápido.” Há uma séria camaradagem numa declaração como essa.

O show basicamente girava em torno deste policial. Dick Robinson “O Doidão”. As Pessoas o chamavam de “O Doidão” porque basicamente ele era insano. Não me lembro se isso foi diagnosticado clinicamente, mas as pessoas sempre questionavam suas decisões. O Doidão regularmente estourava e mordia alguns policiais, a maioria deles personagens de moral inquestionável. Mas todos sabemos que esse é um mundo cão, as apostas são altas, e todos que assistiam ao seriado tinham O Doião com grande estima. Eu penso que todos no esquadrão cresceram bastante como pessoas, graças à determinação do Doidão.

Todavia, os policiais não conseguiam dar conta do serviço por si mesmos. Em cada um dos episódios eles imploravam por uma ajuda maior. E, em cada um dos episódios, eles conseguiam ajuda de um gato chamado Terry (encenado pelo meu gato Blix). Ele era apenas um gatinho na época, e como um garoto novo ávido por Uma Sirene e Uma Oração, me encontrei na busca do meu próprio gato-solucionador-de-crimes. Terry levava aqueles caras por túneis subterrâneos, marinas abandonadas, imensos galpões industriais.

Algumas vezes ele aparecia o episódio inteiro, indo e vindo, fazendo armadilhas e controlando o trânsito. Mas outras vezes você quase não o via no episódio. Então você rebobinava e assistia e assistia e assistia. Você desistia. Ele não estava naquele episódio.

Ainda assim, você não desistia, você ia quadro por quadro com o jog do controle, analisando cada cena. E lá estava ele. No alto atrás do holofote que foi acionado com muita força. O que deixou o Doidão com danos permanentes nos olhos. Por quê? Por que queimar as retinas do seu companheiro, Terry?

Mas a pergunta nunca foi respondida pois a série foi cancelada. Eles começaram a fazer efeitos especiais com o gato e tudo foi por água abaixo. No último episódio, houve um momento em que Terry estava preso em cima de um guindaste, preste a cair na fornalha de uma fundição de ferro. Ele olha para trás. Não dá para voltar. Ele olha para baixo. Tapa os olhos com as patas (sério!), ele pula do guindaste e, no meio do vôo, agarra uma corda e se salva, pousando num macio antílope oculto que um dos trabalhadores tinha aparentemente bronzeado naquela tarde.

As pessoas desligavam a televisão na hora que o seriado ia ao ar. Tentaram mudar o nome. Primeiro foi Deus nos Deu um Esquadrão. Beijo de Dor. Então, Beijo de Dor em Maine, já que o distrito policial inteiro acabou se mudando para lá. Mas a mágica se fora. Eu voltei para escola no verão daquele ano para algumas aulas e as crianças todas já estavam na onda dos lápis de futebol.

Blocos (Blocks)

Há alguns anos, eu comecei a ensinar o Blix sobre Ruby. Quando nós chegamos nesta parte, a parte que cobre blocos, ele me disse, “Blocos me lembram o Dick Robinson Doidão.”

“Mesmo?” Eu não ouvia esse nome faz tempo. “Não sei como você se lembrou disso.”

“Bem, você disse que blocos são difíceis de entender.”

“Eles não são difíceis”, eu disse. “Um bloco é apenas código agrupado.”

“E o Doidão era apenas um policial, que jurou cumprir seu dever,” ele disse. “Mas ele era um verdadeiro milagre ambulante. E agora, este primeiro exemplo que você me mostrou…” Ele apontou para um exemplo que eu havia escrito para ele.

 brinquedos_do_gatinho =
   [:formato => 'meia', :material => 'caxemira'] +
   [:formato => 'rato', :material => 'calico'] +
   [:formato => 'bolinho-primavera', :material => 'chenilha']
 brinquedos_do_gatinho.sort_by { |brinquedo| brinquedo[:material] }

“Isto é um pequeno milagre”, ele disse. “Não posso negar sua beleza. Olhe, lá estão meus brinquedos, junto com suas características. Abaixo deles, o bloco, ordenando-os por material.”

“Peço desculpas se a sua lista de brinquedos parece um pouco complicada,” eu disse. Assim como você, ele já havia aprendido sobre Array, a centopéia caída no código, colchetes de cada lado e cada item separado por vírgulas. (Ah, aqui está uma: ['meia', 'rato', 'bolinho-primavera'].) Ele também sabia sobre a Hash, que é como um dicionário, com chaves de cada lado que parecem livrinhos abertos. Vírgulas na Hash entre cada par. Cada palavra no dicionário encontra seu par por uma seta. (Estupefa-se: {'blix' => 'gato', 'why' => 'humano'}.)

“Sim, perturbante,” ele disse. “Isso tem colchetes como se fosse Array, mas com as setas é uma Hash. Você vai ter que explicar isso.”

“Subversivo ele, não?” Eu disse, cutucando-o com uma colher. “Eu fiz sua lista de brinquedos misturando os dois. Estou usando um atalho. Que é: Se você usar a seta (=>) dentro de um Array, você terá uma Hash ao invés de um Array.

“Ah, entendi,” ele disse. “Você cruzou eles. Que bacana!”

“Sim, sim, você está entendendo,” eu disse. Ele era muito bom com um transferidor também. “Eu tenho três Arrays, cada um contém uma Hash. Notou o sinal de mais? Eu os estou adicionando num Array maior. Aqui está outro jeito de escrever isto…” Eu rabisquei.

 brinquedos_do_gatinho = [
   {:formato => 'meia', :material => 'caxemira'},
   {:formato => 'rato', :material => 'calico'},
   {:formato => 'bolinho-primavera', :material => 'chenilha'}
 ]

Um Array, que age como uma lista de brinquedos de mastigar. Três Hashes estão no Array descrevendo cada brinquedo.

Ordenando e Iterando Para Salvar Vidas

“Vamos ordenar seus brinquedos por forma agora,” Eu disse. “E depois, imprimí-los nesta ordem.”

 brinquedos_do_gatinho.sort_by { |brinquedo| brinquedo[:formato] }.each do |brinquedo|
   puts "Blixy tem um #{ brinquedo[:formato] } feito de #{ brinquedo[:material] }"
 end

“Como sort_by funciona?” perguntou Blix. “Eu sei que é um método que você pode usar com Arrays. Pois brinquedos_do_gatinho é um Array. Mas e quanto a brinquedo?”

“Okay, brinquedo é um argumento de bloco,” Eu disse. “Lembre-se: os corrimãos magrelos de cada lado do brinquedo fazem dele uma calha.”

“Claro, mas parece que você está usando-o como um Hash. Dentro do bloco você tem brinquedo[:formato]. Isto se parece com um Hash.”

“O método sort_by é um iterador, Blix. Ele itera, ou faz o ciclo, com a lista de coisas. Você se lembra daquele episódio quando o Doidão…”

“Episódio?” ele disse. Sim, ele não consegue entender o conceito de seriados de TV. Sim, eu tentei explicar.

“Ou, sim, lembra daquele O caso da testemunha ocular que nós assistimos que o Doidão estava tentando conversar com aquele concorrente do soletrando que queria pular do alto da biblioteca do colégio?”

“Eu me lembro melhor do que você porque eu estava voando num avião de controle remoto.” Sim, foi um daqueles episódios.

“Você se lembra como o Doidão fez para o cara descer?” Eu indaguei.

“Pessoas que concorrem ao soletrando adoram cartas,” disse Blix. “Então o Doidão teve uma idéia de gênio. Ele começou uma carta com a letra A e deu razões, para cada letra do alfabeto, de por que o cara deveria sair do beiral do prédio e voltar a salvo ao chão.”

“‘A’ é para Arquitetura de prédios como esse,’” eu disse, com a voz rude do Doidão. “‘Que nos dá esperança num mundo a ruir.’”

“‘B’ é para Brutamontes, assim como seu amigo O Policial Doidão,’” disse Blix. “‘Caras que ajudam pessoas todo o tempo e não sabem escrever muito bem, mas mesmo assim ajudam caras que escrevem muito bem.’”

“Viu, ele passou por todas as letras, uma a uma. Ele estava iterando por elas.” I Tee Rann Do.

“Mas o cara desistiu, Why. Ele desistiu na letra Q eu acho.”

“‘Q’ é para momentos Quietos que nos ajudam a relaxar e pensar sobre todos os pequenos prazeres da vida, assim nós não ficamos tensos e começamos a fazer besteira andando na ponta do pé na beira de algum edifício alto e maligno.’”

“Aí ele pulou,” disse Blix. Ele balançou a cabeça. “Você não pode culpar o Doidão. Ele fez o melhor que pode.”

“Ele tinha um coração grande, isso é verdade,” eu disse, dando um tapinha no ombro do Blix.

 brinquedos_do_gatinho.sort_by { |brinquedo| brinquedo[:formato] }.each do |brinquedo|
   puts "Blixy tem um #{ brinquedo[:formato] } feito de #{ brinquedo[:material] }"
 end

“Quanto ao seu sort_by, ele começa no topo da lista e vai descendo até o ultimo item, um de cada vez. Então brinquedo é um destes itens. Em cada item, o sort_by pára e joga aquele item pela calha, sob o nome de brinquedo, e deixa você decidir o que fazer com ele.”

“Ok, então brinquedo será, a cada momento, um dos brinquedos que eu tenho.”

“Correto,” eu disse. “Você sabe como eu tenho batido na mesma tecla usando as respostas que os métodos lhe dão_? Aqui, nós estamos apenas olhando a forma do brinquedo dentro do bloco. O bloco então responde para o @sortby@ uma frase contendo o formato, algo como @”rato"@ ou "meia". Uma vez que ele passe por toda a lista, o sort_by terá comparado alfabeticamente o texto de cada forma e retornará um novo Array, agora ordenado."

Uma Lição Inacabada

“Tá bom por hoje,” disse o Blix. “Que tal um pires de leite fresco, por favor?”

Eu enchi o pires dele até a borda e ele se esbaldou daquilo por algum tempo enquanto eu jogava pôquer e golpeava os carvões na lareira. Minha mente vagou e eu não pude não pensar mais sobre blocos. Eu pensei no que ensinar para Blix em seguida.

Eu provavelmente o teria ensinado sobre next. Quando você está iterando uma lista, você pode usar next para pular para o próximo item. Aqui estamos contando brinquedos que não tenham forma de bolinho-primavera, pulando eles com next.

 nao_bolinho_primavera = 0
 brinquedos_do_gatinho.each do |brinquedo|
   next if brinquedo[:formato] == 'bolinho-primavera'
   nao_bolinho_primavera = nao_bolinho_primavera + 1
 end

Eu poderia também tê-lo ensinado sobre break, que joga você para fora de um loop. No código abaixo, vamos imprimir (usando p) cada brinquedo até encontrarmos o brinquedo cujo material seja chenilha. O break fará com que o each termine abruptamente.

 brinquedos_do_gatinho.each do |brinquedo|
   break if brinquedo[:material] == 'chenilha'
   p brinquedo
 end

Eu nunca cheguei a ensinar a ele estas coisas. Eu continuei viajando num pedaço de carvão em particular que acabou preso na proteção da lareira e quase caiu no meu tapete de pele de antílope.

Assim que me esquivei ferozmente daquela pedra negra, Blix sumiu, presumo que para o ônibus para Wixl, a capital econômica dos animais. Quem sabe, ele pode ter parado em Ambrose ou Riathna ou qualquer outra vila pelo caminho. Meu instinto me diz que Wixl era definitivamente sua última parada.

Sem nenhum estudante para instruir ou prosear, encontrei-me sozinho, enfurnado em casa. Na quietude dos corredores mortos, eu comecei a rascunhar uma biografia na forma deste guia.

Eu trabalhei nisso sempre que me sentia entendiado. E quando não estava entendiado, eu ia assistir A Ameaça Fantasma para ficar no clima.

Alguém deixou que todos eles escapassem.

Virar a página.