6.

Centro da Cidade

[o]

Perdido em Wixl
Este roubo continua até o final
Concentrados em seus envolvimentos no plano de expansão de “Os Originais”, as raposas alta e a bem mais baixa tinham viajado direto para a zona de alerta vermelho, a cidade de Wixl. Eu desejava uma espátula para colocá-las juntas lado à lado, arrastá-las para a costa próximo as incubadoras da praia, escondendo-as nos montes de ovos de peixes, puxando-as para baixo através de suas enormes orelhas, ocultando assim suas luxuosas peles. E acima delas eu ficaria parado formando uma sombra imóvel, mantendo-as na mira do meu rifle.
Eu não posso. Eu tenho você para ensinar. Eu tenho que me arrumar e cuidar de mim. As lâmpadas lá de cima precisam ser trocadas. Uma caixa de lâmpadas halógenas simplesmente apareceram pelo correio. Alguém lá fora obviamente está tentando me fazer usá-las. Sendo assim eu vou instalá-las o quanto antes. E depois ficarei lá, formando uma sombra imóvel, segurando meu rifle.
Aquela sombra deveria ser legal e bem definida, sendo assim vou deixá-la assim mesmo.

1. Se Eu Estivesse Procurando Por um Veículo

Sentado por um momento.
Eu gosto de ver estes dois em estado selvagem. Eles ficam bastante entendiados aqui no estúdio. Começaram fazendo slogans estranhos e coisas assim. Eles tinham frases que insistiam em repetir, formando fixações. Você não pode se expôr a todas estas besteiras de raposa.
Vamos apenas dizer: Eu realmente estou tentando dar o meu melhor para manter as coisas num nível acadêmico. Como nunca estive na faculdade, não posso dizer ao certo se cada passagem escrita está de acordo com o severo critério exigido academia.
Eu tenho vários amigos universitários, alguns que viajam o mundo em suas buscas, e eu tento inflexionar minha voz com a mistura de alta cultura deles.
Às vezes eu aplaudo a mim mesmo por ir além do trabalho dos meus amigos educados – apenas em corredores vazios, nós nunca somos arrogantes em público – porque na verdade eu me inscrevi em uma escola intelectual enquanto eles ainda estão em seus livros, virando e virando.
Eu sou um “pré-eventualista” (para saber mais: http://preeventualist.org/). Eu tenho me interessado por isto por tempo suficiente e me orgulho disto ter acontecido. Inevitavelmente, alguns de vocês já devem ter começado a vasculhar este livro atrás de simbologia Marxista. Sinto muito em matar estas interpretações, mas acredito que qualquer conclusão niilista que você possa ter, será mantida sobre vigilância.
De qualquer modo, vou deixar a retórica de lado. Eu apenas menciono o “pré-eventualismo” porque além de ser uma alternativa renovada e fácil ao pós-modernismo com que nascemos, isto oferece um serviço de achados e perdidos gratuito para os residentes de Wixl.


require ‘open-uri’
open( “http://preeventualist.org/lost” ) do |perdido|
puts perdido.read
end

Não tenho como alertar os raposos sobre este serviço. E tenho certeza que ainda é muito cedo para que seu caminhão seja listado. Ainda assim, as boas intenções estão aqui.
Se você está conectado à Internet, o código Ruby acima deve ter baixado a página da Internet e impresso na tela uma mensagem que se parece com isto: (Parece que a página em questão foi alterada, o resultado será o conteúdo da página atual.)

              REGISTRO DE ACHADOS E PERDIDOS DOS "PRÉ-EVENTUALISTAS"
      (um serviço gratuito para os ESCLARECIDOS que foram  ILUMINADOS)

                                      ---
           atualizações são feitas diariamente, por favor, verifique!
                                      ---


                   este serviço é comissionado e subsidiado
                       em parte pelo Clã de Estudo Jovem
                                Ashley Raymond


                                      ...
                 todos os selos e privilégios são apresentados
               sob a notável autoria de Perry W. L. Von Frowling,
       Magistrado Polywaif de Desapropriação.  Também vencedor sete vezes
         seguidas da respeitada Copa Comunitária do Mendigo Insistente
                                      ...


  SOBRE O REGISTRO
  ==================
  Olá, se você é novo, por favor fique conosco. A seguir, uma breve explicação sobre nossos serviços.  
  Em primeiro lugar, algumas notícias do nosso amado magistrado.
  (As crianças o chamam de Tio Von Besteirotio.  Haha!)

  NOTÍCIAS IMPORTANTES
  =======================
  / 15 de Abril de 2005 /
  oi, grandes novidades. estivemos no canal 8 em wixl e ordish.  o cory viu. eu e o jerry
  mathers aparecemos. 
  se você não viu, mande um e-mail pro cory. ele conta o melhor.  tudo o que posso dizer é que
  aquilo não são os movimentos das MINHAS mãos!! (piada para quem assiste o canal 8.)
  obrigado harry e toda a equipe de notícias do canal 8!!

                                                   - perry

  / 7 de Abril de 2005 /
  todos nós estamos lidando com o carpete aqui na central, mas se vocês puderem ficar de olho 
  na prancheta da caitlin, ela está muito sossegada para publicar, e eu sei que isto é realmente
  importante para ela. Ela tinha algumas radiografias panorâmicas bem caras dos dentes tortos de
  seu marido, que estavam anexas à algumas fotos insubstituíveis do seu marido com traje de robocop,
  na época em que seus dentes tortos eram mais visíveis, ela disse (para mim), "Eles saberão o que eu
  quis dizer quando virem isto". eu não sei o que isso significa :(

  eu verifiquei: * a mesa da frente * o corredor * a sala de espera * o banheiro * a dispensa * a 
  grande sala de TV * o balcão * a sala de alunos * a antiga sala do gaff (aquela com a pintura de pé
  de cereja) * o quarto de empregada * escadaria * eu irei atualizar isto, assim que eu encontrar
  mais cômodos.
                                                   - com amor, perry

  / 25 Fev 2005 /
  servidor caiu às 3 horas. estou puto assim como vocês caras. o gaff tá lá embaixo e ele vai ficar lá
  até consertar. :O -- ATUALIZAÇÃO: consertado, de volta na ativa!!
                                                   - perry

  / 23 de fevereiro de 2005 /
  eu sei que tem muito barulho hoje.  o circo stanley bros perdeu doze lhamas, um trailer, um monte de
  cadeados e cinco tendas. eles ainda estão procurando as coisas perdidas. por favor mantenham suas
  cabeças no lugar, eu preciso da ajuda de todos. esses comediantes não têm nada. eu falo sério.
  hoje eu dei um adesivo roxo para um cara (é só uma coisa que eu gosto de fazer como gesto
  de solidariedade) e ele praticamente dormiu nele e nele cultivou os ingredientes para molho de pizza.
  eles estão no fundo do poço. então doem por favor. eu sei que não temos paypal nem nada.
  se você quiser doar, divulgue que você encontrou alguma coisa (uma bicicleta de criança, uma
  compra do mês) e que isso tenha o nome do pessoal do circo escrito nele ou algo do gênero.

                                                  - ótimo, perry

  /15 de novembro de 2004 /
  promoção do dia dos "esperançosos". se você perdeu algo hoje, pode escolher um item grátis
  (no valor de $40 ou menos) da casa de alguém que encontrou algo.
  nós estamos nos divertindo tanto com isso!! é EXATAMENTE assim que eu consegui minha máquina
  de remar no ano passado e eu a AMO!

                                                   - perry

Acho que o Youth Study Clan está fazendo um ótimo trabalho com esse serviço. Está meio piegas e meio basicão, mas se conseguir fazer os animais pararem de usar seus meios mais instintivos de demarcar território, então eu tiro meu chapéu.

Mesmo assim, um grupo de jovens pré-eventualistas? Como é que pode? Você tem que ter pelo menos flertado com cinismo de verdade antes de poder se tornar um pré-eventualista. E definitivamente, não pode ir ao colégio. Portanto, eu não sei.

Voltando à lista de instruções do Registro de Achados e Perdidos Pré-eventualista.

 USANDO O SERVIDOR A&P
 =====================

 O A&P é um serviço gratuito. Os atos de perder e achar são qualidades essenciais para
 a construção de um estilo de vida pré-eventualista. Esperamos atender a sua crença.


 Não usamos HTML, para simplificar as coisa por aqui. Nosso pessoal já trabalha quinze
 horas por dia. (Valeu, Terk!! Valeu, Horace!!)


 Você pode usar nosso serviço para procurar coisas que você perdeu. Ou pode adicionar
 coisas que você perdeu (ou achou) ao nosso registro. Isso é feito digitando o endereço
 correspondente no seu browser.

 PESQUISANDO
 ===========
 Para procurar coisas perdidas, use o seguinte endereço:

   http://preeventualist.org/lost/search?q={palavra chave}

 Você pode substituir {palavra chave} pela sua pesquisa. Por exemplo, para pesquisar por
 "xícara"

   http://preeventualist.org/lost/search?q=xicara

 Assim, você receberá uma lista das xícaras que foram achadas ou perdidas.

 Se você quer pesquisar somente por xícaras perdidas ou somente por xícaras achadas, use as
 páginas 'searchlost' e 'searchfounds':

   http://preeventualist.org/lost/searchlost?q=xicara

Não estou de brincadeira. Eu sei onde está o caminhão. Sério, não estou só provocando. Vou mostrar em um segundo. Só estou dizendo, olhe os raposos:

Hummmmm.

Elas estão indefesas. E mesmo assim, aqui está essa ótima ferramenta. Possivelmente, a chave para sair dessa confusão. Só quero dar uma fuçada, ver se há alguma pista por aqui.

 require 'open-uri'

 # Pesquisar todos os itens achados contendo a palavra 'caminhao'.
 open( "http://preeventualist.org/lost/searchfound?q=caminhao" ) do |truck|
   puts truck.read
 end

Não vejo nada sobre o caminhão da raposa grande nessa lista. Tudo bem. Os raposos estão perdidos mesmo. Temos algum tempo.

Você aprendeu uma técnica simples para recuperar uma página da Internet. O código usa a biblioteca OpenURI, que foi escrita por um dos meus Rubistas preferidos, Akira Tanaka. Ele simplificou a leitura de arquivos Internet, tornado-a igual leitura de arquivos do seu computador.

Num capítulo anterior, armazenamos suas idéias diabólicas em um arquivo texto. Você lê esses arquivos em Ruby usando open.

 require 'open-uri'

 # Abrindo um arquivo em um diretório do seu computador.
 open( "diretorio/ideia-sobre-esconder-alface-nas-cadeiras-da-igreja.txt" ) do |ideia|
   puts ideia.read
 end

Files (arquivos) são objetos de entrada-e-saída. Você pode ler e escrever em um arquivo. Em Ruby, todo objeto IO (input-output) tem os métodos read e write. O método open passa um objeto IO para num bloco para você usar. IO é a sua passagem para o mundo exterior. É como os raios do sol passando através das barras da prisão. (Entretanto, você não pode escrever (write) em uma página web usando OpenURI. Você terá que achar um ferramenta para copiar para o seu Web Server. Um cliente FTP, por exemplo.

Se alguém quiser ler sua idéia diabólica de esconder alface nas cadeiras da igreja, presumindo que você tenha colocado isso numa página web:

 require 'open-uri'

 # Abrindo um arquivo disponível num Web Site.
 open( "http://sua.com/ideia-sobre-esconder-alface-nas-cadeiras-da-igreja.txt" ) do |ideia|
   puts ideia.read
 end

A biblioteca OpenURI também entende endereços de FTP. Isso amplia as possibilidades de onde você pode armazenar arquivos. No seu computador ou em algum outro lugar na Internet.

Lendo arquivos linha a linha

Quando você usa OpenURI para obter informações da web com os métodos open and read, a página é enviada como um String. Você também ler a página uma linha de cada vez, se está procurando algo. Ou se a página é muito grande e você quer economizar memória do seu computador.

 require 'open-uri'
 open( "http://preeventualist.org/lost/searchfound?q=caminhao" ) do |caminhao|
   caminhao.each_line do |linha|
     puts linha if linha['picape']
   end
 end

O código acima recupera a lista de caminhões achados por pré-eventualistas e exibe somente as linhas que contenham a palavra ‘picape’. Dessa maneira podemos limitar as descrições e procurar somente as linhas pertinentes.

Acima, os colchetes são usados em uma string, de forma que seja pesquisado nessa string o que quer que esteja dentro dos colchetes. Como a string 'picape' está dentro dos colchetes, a palavra ‘picape’ é pesquisada na string line.

Sobre ser legal.

Quando uma página web é carregada com read, toda a página é carregada na memória. Normalmente isso ocupa somente alguns kbytes. Mas se a página é grande (vários megabytes), é melhor usar each_line, que carrega uma linha de cada vez, evitando ocupar toda memória.

Yielding é como blocos de montar

Ruby frequentemente usa iteradores dessa forma. Sim, iteradores são usados para percorrer cada um dos itens de uma collection (coleção), como um Array ou um Hash. Então, olhe para uma fonte de IO como uma coleção de linhas. O iterator (iterador) pode percorrer essa coleção de linhas.

 class IO
   # Definição do método each_line.  Veja que ele não tem
   # uma lista de argumentos. Blocos não precisam ser listados como argumentos.
   def each_line
     until eof?        # até chegarmos ao final do arquivo...
       yield readline  # passe a linha para o bloco
     end
   end
 end

A palavra-chave yield (produzir) é a maneira mais fácil de se usar um bloco. Uma palavra. Da mesma forma que uma cortina tem um puxador ou como uma maleta tem uma alça. Dentro de um método, você pode apertar o botão piscante yield e ele irá rodar o bloco anexado a esse método. Ele ficará brilhando em vermelho até que o bloco seja executado. Então voltará a piscar de novo e você poderá o botão novamente se quiser.

 def yield_thrice
   yield
   yield
   yield
 end

Aperte o botão yield três vezes rapidamente e o bloco ganha vida por três vezes.

 irb> a = ['primeiro, o nascimento', 'depois, uma vida cheia de imagens bonitas', 'e finalmente, o fim']
 irb> yield_thrice { puts a.shift }
 # prints out:
 #   primeiro, o nascimento
 #   depois, uma vida cheia de imagens bonitas
 #   e finalmente, o fim

O método shift tira o primeiro item de um Array. O barbeiro shift corta o cabelo fora e o entrega. Depois o escalpo. E assim segue, reduzindo o pobre coitado a nada.

Você viu blocos anexado a métodos. Qualquer método Ruby pode ter um bloco anexado no final.

 # O estilo compacto de anexar um bloco a um método.
 # Aqui o bloco é demarcado por chaves.
 open( "idea.txt" ) { |f| f.read }

 # O estilo verboso de anexar um bloco.
 # Aqui o bloco é demarcado por 'do' e 'end'
 open( "idea.txt" ) do |f|
   f.read
 end

Se você passar argumentos para o yield, esse argumentos também serão passados ao bloco. O bloco vai num pequeno sidecar preso à motocicleta do método. O método vocifera uma lista de argumentos, gritando para o bloco mesmo com todo o vento enquanto eles estão dirigindo pelo deserto. O bloco bate no capacete com se dissesse: “Ok, entendi. Meu cérebro captou tudo.”

 # O método abre dois arquivos e repassa os objetos IO resultantes
 # para o bloco anexo
 def double_open filename1, filename2
   open( filename1 ) do |f1|
     open( filename2 ) do |f2|
       yield f1, f2
     end
   end
 end

 # Imprime os arquivos lado a lado
 double_open( "idea1.txt", "idea2.txt" ) do |f1, f2|
   puts f1.readline + " | " + f2.readline
 end

Você pode se perguntar o que o yield tem a ver com sinais de trânsito. Na verdade, essa é uma boa pergunta, e que eu acredito que tenha uma boa resposta. Quando você executa um método, você está a esse método o controle do seu programa. Controle para fazer o seu trabalho e retornar com uma resposta.

Com yield, o método está parando nessa intersecção, devolvendo o controle para você, para o seu bloco. O método está permitindo que você faça o seu trabalho antes de retornar ao trabalho dele. Então, enquanto o método each_line faz o trabalho de ler linhas de um arquivo, o bloco anexado ao método each_line recebe a linha e tem a chance de dar um passeio com ela no sidecar.

Pré-eventualismo numa Caixinha Dourada

Você já aprendeu o bastante sobre OpenURI e yield para escrever os seus próprios iteradores. Você já sabe como usar o serviço de achados e perdidos. Na verdade, você já pode começar a se aventurar nos achados e perdidos de Wixl sem mim.
Vamos encapsular elegantemente todo o serviço em uma única classe.

 require 'open-uri'
 module PreEventualista
   def self.open page, query
     qs = 
       query.map do |k, v|
         URI.escape "#{ k }=#{ v }"
       end.join "&"
     URI.parse( "http://preeventualist.org/lost/" + page + "?" + qs ).open do |lost|
       lost.read.split( "--\n" )
     end
   end
   def self.search word
     open "search", "q" => word
   end
   def self.searchlost word
     open "searchlost", "q" => word
   end
   def self.searchfound word
     open "searchfound", "q" => word
   end
   def self.addfound seu_nome, item_perdido, achado_em, descricao
     open "addfound", "name" => seu_nome, "item" => item_perdido, 
                      "at" => achado_em, "desc" => descricao
   end
   def self.addlost seu_nome, item_achado, visto_em, descricao
     open "addlost", "name" => seu_nome, "item" => item_achado,
                     "seen" => visto_em, "desc" => descricao
   end
 end

Em algum momento, você tem que começar a modelar seu código em algo mais elegante. Salve o módulo acima em um arquivo chamado preeventualista.rb.

Esse módulo é uma biblioteca muito simples para usar o serviço dos Pré-eventualistas. É exatamente assim que bibliotecas são escritas. Você constrói um módulo ou uma classe, grava em um arquivo, e, se ficou feliz com o resultado, disponibiliza na web para o resto do mundo poder utilizar.

Esses vagabundos podem então usar o seu módulo da mesma forma que eu usei OpenURI anteriormente.

 irb> require 'preeventualista'
 irb> puts PreEventualist.search( 'caminhao' )
 irb> puts PreEventualist.addfound( 'Why', 'conhecimentos em Ruby', 'Parque Wixl',
        "Eu posso lhe dar conhecimentos em Ruby!\nVenha visitar poignantguide.net!" )

2. Enquanto Isso, O Porco-Espinho Faz uma Parada Para Abastecer

O porco-espinho paga por gasolina.  Pipas?

3. Um Assassinato de Dragão Patrocinado

O assassino pula adentro.

“Olhe em Volta,” disse Raposinho. “Alguns de nós não tem tempo para buscas. Alguns de nós tem maiores responsabilidades, trabalhos, assim por diante. Sustento, Entendeu?”

Eiiii, meu TRABALHO era assassinar o dragão!!” gritou o coelho Wee, piscando seus olhos e e pulando furioso de galho em galho de lagoa em lagoa. “Seu focinho era uma GRANDE responsabilidade!! Seu hálito de fumaça era problema meu!!!. Eu gastei cinqüenta dólares em um táxi APENAS para sair daqui, que foi outro ENORME ENORME sacrifício. Você não tem nada sobre mim, nem uma simples acusação, todo a minha HEROICIDADE é absoflautamente impessegável, toda a minha ABORDAGEM é clarinentemente indamascável, disse o Lester.”

“Quem é Lester?” falou Raposinho.

“Lester é meu taxista! Ele está estacionado na entrada do Array de Dwemthy!!” O Coelho ricocheteou enlouquecidamente como um screensaver para um Super-Computador. “Pergunte ao Dwemthy!!”

“Bom,” disse Raposinho. Ele se virou para olhar para Raposão, que estava sentada olhando longe no horizonte. “Espera aí, eles tem um estacionamento no Array de Dwemthy?”

SIM!! E um quiosque de Pretzel!!"

“Mas é um Array? Eles vendem churros?”

CHOCOLAVA!!” berrou o coelho.

“E aquelas cordas que brilham no escuro que você pode prender no cabelo? Ou pode apenas ficar segurando elas ou—”

BRAIDQUEST!!”

“Você devia receber uma parte da comissão do vendedor,” afirmou Raposinho. “O pessoal veio ver você matar o dragão, certo?”

MAS!! Eu não opero os braços-mecânicos que extraem o chocolava."

“Eu só estou tentando dizer que você faz funcionar a máquina de matar. Então você deve ter uma parte nisso.”

“AH NÃOO!! Deixei minha folha de alface favorita no Array de Dwemthy!!” gritou o coelho, girando feito um peão. Ao fundo: “Ou quem sabe no carro do Lester?”

“Quer saber— meu deus, dá para parar quieto??” Pediu raposinho.

“Meu rádio,” disse Raposinho, voltando à vida por um instante, “na minha picape.” Aquele olhar ainda distante. Seu olhar parece voltar, mas logo se distancia, lembranças de outros lugares e outros momentos. Uma viagem de carro para Maryland. A voz de Lionel Richie ao fundo. Os limpadores de pára-brisas ligados meio rápidos demais. Ele para em uma casa. Sua mão abre a porta. Ele é uma raposa bem peluda. Lágrimas e maquiagem.

Bem, voltando: “Aquele porco-espinho está trocando as estações”

O coelho subiu no braço do banco e falou de perto. MAS!! Logo eu vou fazer um banquete com a cabeça do dragão e com os sucos da língua do dragão." O coelho sentou e ajeitou suas patas delicadamente.

“(Que eu espero que tenha o mesmo gosto de ursos de canela)” sussurrou o coelho para si mesmo.

“Adoro canela,” disse Raposinho. “Eu devia sair para matar dragões com você um dia desses.”

“Você devia, mesmo” disse o coelho, com brilho nos olhos.

“Mas salivar por uma língua?. Você não saliva por uma língua, não é?”

CLARO QUE SIM!!” e o coelho ficou tão excitado que Sticky Whip saiu pelo seus olhos. (Mais sobre Sticky Whip posteriormente em uma sidebar. Não me deixem esquecer. Veja também: _O Compêndio do Purista para novos Cremes para Retina, por Jory Patrick Sobgoblin, disponível onde quer que vendam presilhas de animais.)

“Ok, você me ganhou. Quero ouvir toda a história,” disse Raposinho. “Por favor, fale a vontade sobre o ‘chaminé’. Ah, e Dwemthy. Quem é ele? Quais são suas motivações? Então talvez, se eu ainda estiver por perto depois disso, você poderá me dizer sobre o que faz os coelhos se motivarem, e talvez você possa segurar nossas mãos através deste calvário. Eu preciso de consolo mais do que ninguém. Provavelmente eu poderia usar religião agora. Eu poderia usar sua bravura e este sentimento de realização que você exala. Você fuma cachimbo? Poderia ser uma ferramenta proveitosa para trazermos nesta pontificação em que estamos metidos.”

E o coelho começou a divagar sobre Dwemthy e a lenda do Dwemthy e as formas de Dwemthy. Tal como a maioria das estórias de Dwemthy, o relato do coelho era particularmente ornamentado. Cara pálida, existem delícias que somente eu devo abordar.

Por favor, nunca pergunte quem é Dwemthy. Obviamente ele é um gênio e nunca revelaria sua localização ou verdadeira identidade. Ele tem dinastias. Ele deu vidas a ogros. Em toda a parte, em todo o tempo, cavalos sentem seu cheiro. Acima de tudo, ele conhece prazeres carnais. E pensar que este…

Este é o Array dele.

O Array de Dwemthy

O Array de Dwemthy tem encantado e tormentado a vila folk por séculos.

Você está na entrada do Array do Dwemthy. Você é um coelho que está prestes a morrer. E mergulha fundo no Array:

 class Dragao < Criatura
   vida 1340     # escamas duras
   forca 451     # veias rígidas
   carisma 1020  # sorriso escancarado
   arma 939      # bafo de fogo
 end

Uma escaldante LAVA BORBULHANTE infiltrou a cacofônica MINA adentrando as antigas copas da FLORESTA DWEMTHY… calcários e noturnos gritos da barriga SELVAGEM E VORAZ STORKUPINE… que come gansos molhados LOGO DEPOIS ele que comeu alguns biscoitos Graham e um cochilo ao meio dia… entre hipopótamos famintos TECNICAMENTE ÓRFÃOS mas veridicamente abrigados sobre sombrinhas de revendas de carros… abaixo ampolas destampadas de mínimas polpas ELIXIR AZULque devem permanecer… doravante… QUIETODWEMTHY!!!

Sorte e a mãe natureza.

Se você não entendeu o Array de Dwemthy, a culpa é dele. Ele projetou o jogo para complicar nossas vidas e seria mais simples, não fosse a inspiradora jornada que temos que prezar em nossos braços precisamente agora.

O Array de Dwemthy tem uma história sinuosa e de grande impacto. Não basta simplesmente dizer “Labirinto de Dwemthy” mais e mais e esperar ter subsídios apenas a partir deste ato. Venha comigo, posso te levar de volta a alguns anos atrás, de volta ao anos sessenta onde tudo começou com metaprogramação e golfinhos.

Você pode estar inclinado a pensar que metaprogramação é mais uma palavra hacker e que inicialmente foi utilizada incessantemente em ligações privadas entre máquinas de fax. Juro por Deus, estou aqui para lhe dizer que isso é mais estranho que possa parecer. Metaprogramação começa com usando drogas na companhia de golfinhos.

Nos anos sessenta, um prolífico cientista chamado John C. Lilly começou a fazer experiências com seus próprios sentidos para descobrir o funcionamento de seu corpo. Eu posso atestar isto. Faço frequentemente quando estou de pé, no meio de uma estrada, segurando uma torta ou quando estou me escondendo dentro de uma catedral. Faço uma pausa para me examinar. Isto provou que é quase impossível. Tenho preenchido três páginas de caderno com notações algébricas, nenhuma delas conseguiu explicar nada. A torta, aliás, foi muito de fácil de expressá-la matematicamente.

Mas o cientista Lilly passou por cima de suas experiências. Ele tomou LSD na companhia de golfinhos. Muitas vezes em um lamentável tanque de isolamento, escuro, cheio de água salgada quente. Muito sombrio. Mas isto era ciência! (Antes de você achá-lo um criminoso: até 1966, LSD era fornecido pelos laboratórios Sandoz a qualquer cientista interessado, sem encargos.)

Drogas, golfinhos e privação. O que levou Lilly a fazer uma incursão em coisas meta. Ele escreveu livros sobre programação mental, comparando seres humanos e computadores. Você pode escolher ingerir qualquer substância que queira durante esta próxima citação — é muito provável que você pegará um grão de sal — mas eu te asseguro que não haverá um show do Grateful Dead num gramado e nenhum ‘raver’ no porão.

Quando alguém aprende a aprender, este alguém está fazendo modelos, usando símbolos, fazendo analogias, metáforas, em resumo, inventando e usando linguagem, matemática, arte, política, negócio, etc. No lado crítico do cérebro (córtex), estão as linguagens e suas conseqüências. Para evitar a necessidade da repetição de aprender para aprender símbolos, metáforas, modelos, eu simbolizo a idéia subjacente nestas operações como metaprogramação.

John C. Lilly, Programming and Metaprogramming in the Human Biocomputer, Nova Iorque, 1972.

Nós aprendemos. Mas primeiro aprendemos a aprender. Montamos programação na nossa mente que é o atalho para mais programação. (Lilly é um grande palestrante sobre programação cerebral e do sistema nervoso, o que ele coletivamente chama de biocomputador.)

A metaprogramação de Lilly era mais sobre dar asas ao seu imaginário, reinventando você mesmo. Este tipo de pensamento nos remete diretamente a pessoas que se interessam por Xamanismo, colocam suas mãos sobre cartas de tarot e que levantam cedo para aulas de karatê. Eu acho que você pode dizer que Metaprogramação é uma coisa New Age, mas tudo isso foi enfiado recentemente em um saco de dormir juntamente com a “nerdice” antiquada. (Se você chegou até aqui a partir de uma procura no Google por “Metaprogramação em C++”, fique à vontade, a única coisa que eu te peço é que você queime aqueles atalhos neuronais que originaram a busca. Muito obrigado.)

A própria Meta, não é falada de maneira diferente, hoje em dia, por seu autor.

Toda resposta sensitiva à realidade é uma interpretação dela própria. Besouros e macacos claramente interpretam seu mundo, e agem baseados no que vêem. Nossos sentidos físicos são, eles mesmos, órgãos de interpretação. O que nos distingue de nossos companheiros animais é que somos capazes de interpretar estas interpretações. Neste sentido, toda linguagem humana é uma meta-linguagem. É uma reflexão de segunda ordem sobre a ‘linguagem’ de nossos corpos — sobre nosso aparato sensorial.

Terry Eagleton, After Theory, Londres, 2003, ch. 3.

Para todo efeito, você pode dizer que programação, por si só, é uma meta-linguagem. Todo código fala a linguagem da ação, de um plano que ainda não foi colocado em prática, mas que brevemente irá. Instruções para o jogadores dentro da sua máquina. Eu tenho um sentimento lacrado sobre este assunto.

Mas agora estamos avançando nossos estudos, nos aventurando em metaprogramação, mas não fique ansioso, é apenas o Ruby que você já viu, é a razão pela qual Dwemthy não hesitou em mostrá-lo imediatamente a você. Em pouco tempo será tão fácil como perceber uma adição ou subtração. À primeira vista isto pode parecer brilhante, como se você tivesse encontrado seu primeiro vagalume, que de repente apareceu voando na sua frente. Então, isto se torna apenas uma pequenina luz cintilante que torna viver em Ohio muito mais legal.

Metaprogramação é a escrita de código que escreve código. Mas não como M. C. Escher rascunharia. O programa não fica voltando e se escrevendo e nem o programa fica pulando de seu monitor e arrancando o teclado de suas mãos. Não, é bem menor que isso.

Vamos dizer que é parecido com uma pílula laranja que você ganhou no circo. Quando você chupa ela e o sabor vai embora, atrás do seu dente esconde um grande, esponjoso brontossauro. Ele escorrega por sua língua e pula livremente, brincando sobre as pastagem e gritando: “Papai!” E a partir desse momento, sempre que ele enlouquecer vai atacar uma van, bem, essa van vai ficar brilhante depois.

Agora, vamos dizer que alguém coloque aquela pequena pílula laranja debaixo da torneira. Não na língua, debaixo da torneira. E isso aciona uma catalisação diferente, que cria um grupo de sêxtuplas esponjas choramingantes, com cordão umbilical e tudo mais. Ainda assim muito prático para se limpar a van. Mas um grupo totalmente diferente de camurça. E, um dia, esses seis irão fazer o papai chorar quando tocarem em um concerto de violino.

Metaprogramação é um conjunto de código dentro de um formato de pílula, que uma pequena gota de água pode acionar para se expandir. Mais importante, você pode controlar a reação da pílula, de uma forma que o brontossauro pode ser criado magro e desajeitado. Ou sêxtuplos, CERTAMENTE, ou costureiras, ou cérebros de gato, ou dragões.

 class Dragao < Criatura
   vida 1340    # escamas duras
   forca 451    # veias ressaltadas
   carisma 1020 # sorridente
   arma 939     # cospe fogo
 end

Isso ainda não é metaprogramação. Apenas a pílula. O produto da metaprogramação. Estamos fazendo uma pausa, olhando para a besta antes de descer abaixo o seu tecido muscular com um bisturi e um microscópio.

O Dragao é uma classe. Você já viu muitas vezes. O Dragao é descendente da classe Criatura.

Agora, olhe para cima. Preste atenção. A classe Criatura contém o código de metaprogramação. Você pode escreve código de metaprogramação que pode ser usado em qualquer lugar, ao longo de todo Ruby, em Criatura ou Dragao, em String ou em Object, qualquer lugar. O nosso exemplo aqui, uma vez que esta é a forma mais comum de meta-código, foca em metaprogramação dentro de classes apenas.

Cada uma das características de Dragao são apenas métodos de classe. Você também poderia escrever assim:

 class Dragao < Criatura
   vida( 1340 )    # escamas duras
   forca( 451 )    # veias ressaltadas
   carisma( 1020 ) # sorridente
   arma( 939 )     # cospe fogo
 end

Removendo os parênteses remove-se a confusão, então vamos deixar sem. Apenas use parênteses quando estiver usando muitos métodos juntos e você quer ser bem claro.

Código da Criatura

Agora, com um corte lateral em todo o diafragma, nos mostraremos as entranhas da classe Criatura. Salve esse código em um arquivo chamado dwemthy.rb.

 # As vísceras da força vital do Array de Dwemthy
 class Criatura

   # Obtém uma metaclasse para esta classe
   def self.metaclass; class << self; self; end; end

   # Avançado código de metaprogramação para boas 
   # e claras características
   def self.caracteristicas( *arr )
     return @caracteristicas if arr.empty?

     # 1. Define 'accessors' para cada variável
     attr_accessor *arr

     # 2. Adiciona um novo método para cada característica.
     arr.each do |a|
       metaclass.instance_eval do
         define_method( a ) do |val|
           @caracteristicas ||= {}
           @caracteristicas[a] = val
         end
       end
     end

     # 3. Para cada monstro o método 'initialize'
     #    deve usar um número padrão para cada característica.
     class_eval do
       define_method( :initialize ) do
         self.class.caracteristicas.each do |k,v|
           instance_variable_set("@#{k}", v)
         end
       end
     end

   end

   # Os atributos da Criatura são somente leitura
   caracteristicas :vida, :forca, :carisma, :arma
 end

Preste atenção no fechamento das linhas do código, especialmente na linha onde caracteristicas está sendo definido. Todo o código antes dessa linha determina o método caracteristicas. Isto é semelhante ao básico do bilhete de loteria do capitulo anterior.


class BilheteLoteria
attr_reader :numeros_escolhidos, :data_compra
end

Tanto caracteristicas como attr_reader são apenas métodos de classe. Quando attr_reader é usado em BilheteLoteria, a metaprogramação inicia por trás dos bastidores e começa a estourar balões, criando métodos leitores para as variáveis de instância @numeros_escolhidos e @data_compra acima.

O código para o método caracteristicas é a metaprogramação que eu tenho feito referência. Comentários no código revelam os três estágios que o método passa quando adiciona as características.

  1. A lista de características é passada para attr_accessor, que constrói código leitor e escritor para as variáveis de instância. Um para cada característica.
  2. Métodos de classe são adicionados para cada característica. (O método vida é adicionado para a característica :vida). Esses métodos de classe são usados na definição da classe assim como você usaria caracteristicas ou @attr_acessor. Dessa maneira, você pode especificar a característica, de acordo com os pontos dados de uma característica para uma determinada criatura.
  3. Adicione um método de inicialização que cria um novo monstro corretamente, com os pontos certos e GANHANDO FORÇA! GANHANDO FORÇA! o monstro está vivo!

A beleza desses três passos é que você ensinou ao Ruby como criar monstros para você. Então quando o Ruby obtém as características:

 class Criatura
   caracteristicas :vida, :forca, :carisma, :arma
 end

O Ruby preenche com o código dos bastidores e transplanta um pulsante coração verde e da ignição no corpo dando corda. O Ruby vai usar a metaprogramação da classe Criatura e irá construir todos os variados métodos, expandindo caracteristicas em uma lista como essa:

 class Criatura

   # 1. define métodos leitores e escritores
   attr_accessor :vida, :forca, :carisma, :arma

   # 2. adiciona novos métodos de classe para usar na criatura
   def self.vida( val )
     @caracteristicas ||= {}
     @caracteristicas['vida'] = val
   end

   def self.forca( val )
     @caracteristicas ||= {}
     @caracteristicas['forca'] = val
   end

   def self.carisma( val )
     @caracteristicas ||= {}
     @caracteristicas['carisma'] = val
   end

   def self.arma( val )
     @caracteristicas ||= {}
     @caracteristicas['arma'] = val
   end

   # 3. estabelece pontos padrões para
   #    cada característica
   def initialize
     self.class.caracteristicas.each do |k,v|
       instance_variable_set("@#{k}", v)
     end
   end

 end

Agora, o Ruby vai aceitar gradativamente essas seis linhas de código da classe Dragao, curto o bastante para aparecer legal em cartas de jogos:

 class Dragao < Criatura
   vida 1340    # escamas duras
   forca 451    # veias ressaltadas
   carisma 1020 # sorridente
   arma 939     # cospe fogo
 end

Eval, o Menor Metaprogramador

Embora o código de metaprogramação acima seja simplesmente Ruby, ainda assim pode ser difícil de seguir. Eu compreendo totalmente, caso você tenha chegado a esse ponto e seus olhos estejam girando em suas cavidades e seus joelhos emperrados. A parte mais complicada de tudo isso acima são as linhas que chamam os métodos instance_eval e class_eval. Passe pomada nas suas juntas enquanto eu falo sobre eval.

Viemos falando sobre metaprogramação. Escrevendo código que escreve códigos. O método eval reside neste beco. O vagabundo eval pega o código que você havia guardado em uma string e executa o código.

 drgn = Dragao.new
 # é identifo a...
 drgn = eval( "Dragao.new" )
 # ou alternativamente...
 eval( "drgn = Dragao.new" )

Aqui, vamos escrever um programa que tem um buraco. Ao invés de escrever um programa que cria um novo Dragao, vamos deixar um buraco onde seria o Dragao.

 print "Que classe de monstro você veio combater? "
 classe_monstro = gets
 eval( "monstro = " + classe_monstro + ".new" )
 p monstro

O programa pede por um monstro. Se você digitar Dragao, então a variável da classe_monstro irá conter a string "Dragao". Dentro do eval algumas strings serão adicionadas juntas para formar a string "monstro = Dragao.new". E quando o eval executa essa string, a variável monstro contém um objeto Dragao. Pronto para batalha.

Isso é maravilhoso! Agora podemos deixar que o jogador escolha um monstro! Claro, estamos confiando no jogador para que ele forneça uma classe real de monstro. Se eles digitarem BruxaBotanica e não existe a classe BruxaBotanica, eles terão uma exceção jogada na sua cara.

Então, em resumo, o eval permite que você crie um código a medida que prossegue. O que pode ser útil e pode ser perigoso ao mesmo tempo.

Os métodos instance_eval e class_eval usado na metaprogramação para a classe @Criatura são levemente diferente do normal eval. Esses dois métodos especiais passam o código assim como o eval faz, mas eles mergulham em classes e objetos e passam o código lá.

 # O método instance_eval executa o código como se ele fosse executado dentro
 # do objeto do método de instância.
 irb> drgn = Dragao.new
 irb> drgn.instance_eval do
 irb>   @nome = "Tobias"
 irb> end

 irb> drgn.instance_variable_get( "@nome" )
   => "Tobias"

 # O método class_eval executa o código se estiver dentro da definição de classe.
 irb> Dragao.class_eval do
 irb>   def nome; @nome; end
 irb> end

 irb> drgn.nome
   => "Tobias"

Como você pode ver acima, os métodos instance_eval e class_eval também podem pegar um bloco de código ao invés de uma string. O que é exatamente como as coisas foram feitas no Array de Dwemthy.

Bastante instrução depreciante e Ardilosa Justaposição — Onde está o Array de Dwemthy??

Vá com cuidado — aqui está a outra metade do ARRAY DE DWEMTHY!! Adicione essas linhas a dwemthy.rb.

 class Criatura

   # Este método aplica um golpe recebido durante uma luta.
   def golpear( dano )
     aumento_poder = rand( carisma )
     if aumento_poder % 9 == 7
       @vida += aumento_poder / 4
       puts "[Aumento de poderes mágicos de #{ self.class } #{ aumento_poder }!]"
     end 
     @vida -= dano
     puts "[#{ self.class } está morto.]" if @vida <= 0
   end

   # Este método obtém uma rodada em uma luta.
   def lutar( inimigo, arma )
     if vida <= 0
       puts "[#{ self.class } está muito morto para lutar!]"
       return
     end

     # Ataca o oponente
     seu_golpe = rand( forca + arma )
     puts "[Você golpeia com #{ seu_golpe } pontos de dano!]"
     inimigo.golpear( seu_golpe )

     # Retaliação
     p inimigo
     if inimigo.vida > 0
       inimigo_golpe = rand( inimigo.forca + inimigo.arma )
       puts "[Seu inimigo golpeia com #{ inimigo_golpe } pontos de dano!]"
       self.golpear( inimigo_golpe )
     end
   end

 end

 class ArrayDeDwemthy < Array
   alias _inspect inspect
   def inspect; "#<#{ self.class }#{ _inspect }>"; end
   def method_missing( meth, *args )
     resposta = first.send( meth, *args )
     if first.vida <= 0
       shift
       if empty?
         puts "[Uauu.  Você dizimou o Array de Dwemthy!]"
       else
         puts "[Prepare-se. #{ first.class } surgiu.]"
       end
     end
     resposta || 0
   end
 end

Esse código adiciona dois métodos a Criatura. O método golpear que reage ao golpe de outra Criatura. E o método lutar que permite que você coloque os seus próprios golpes contra aquela Criatura.

Quando a sua Criatura leva um golpe, um pouco da defesa contribui e o seu valor carisma é usado para gerar um aumento de poder. Não me peça para explicar os segredos por trás deste fenômeno. Um número aleatório é escolhido, uma matemática simples é feita e se você tiver sorte, você consegue alguns pontos vitais. @vida += aumento_poder / 4.

Então o golpe do inimigo está dado. @vida -= dano. É assim que o método da Criatura#golpear trabalha.

O método lutar checa se a sua Criatura está viva. Em seguida, um golpe aleatório é dado no seu oponente. Se o seu oponente sobreviver a este golpe, ele ganha uma chance de atacar de volta. Estas são as atividades do método Criatura#lutar.

Irei explicar o ArrayDwemthy em um segundo. Realmente explicarei. Estou me divertindo fazendo isso. Por hora, vamos nos concentrar em golpear e lutar.

Apresentando: Você.

Você pode certamente experimentar derivações deste coelho. Mas o oficial Paradigma de Dwemthy explicitamente denota o código -– e o personagem em geral -– escrito abaixo. Salve isto como coelho.rb.

 class Coelho < Criatura
   caracteristicas :bombas

   vida 10
   forca 2
   carisma 44
   arma 4
   bombas 3

   # bumeranguinho
   def ^( inimigo )
     lutar( inimigo, 13 )
   end
   # a espada do herói é ilimitada!!
   def /( inimigo )
     lutar( inimigo, rand( 4 + ( ( inimigo.vida % 10 ) ** 2 ) ) )
   end
   # alface irá formar a sua força e fibra alimentar extra
   # voará na cara de seu oponente!!
   def %( inimigo )
     alface = rand( carisma )
     puts "[Alface saudável lhe dá #{ alface } pontos de vida!!]"
     @vida += alface
     lutar( inimigo, 0 )
   end
   # bombas, mas você possui somente três!!
   def *( inimigo )
     if @bombas.zero?
       puts "[HUMM!! Você está sem bombas!!]"
       return
     end
     @bombas -= 1
     lutar( inimigo, 86 )
   end
 end

Você tem quarto armas. O bumerangue. A espada do herói. A alface. E as bombas.

Para fazer acontecer, abra o irb e carregue as bibliotecas que criamos acima.

 irb> require 'dwemthy'
 irb> require 'coelho'

Agora, mostre-se.

 irb> c = Coelho.new
 irb> c.vida
   => 10
 irb> c.forca
   => 2

Bom, bom.

O Coelho Luta com a ScubaArgentina!

Você não pode ir apressadamente para o Array de Dwemthy, sem cinto de segurança e simplesmente perfumado!! Você deve avançar deliberadamente para o demoníaco cotilhão. Ou ao sul, pelos bosques e pelo labirinto de carvão.

Neste momento, vamos nos esconder dissimuladamente pelo resíduo leitoso ao lado dos aquedutos e seguir o ScubaArgentina.

 class ScubaArgentina < Criatura
   vida 46
   forca 35
   carisma 91
   arma 2
 end

Para começar a luta, certifique-se de que criou um de você e um do ScubaArgentina.

 irb> c = Coelho.new
 irb> s = ScubaArgentina.new

Agora use o bumeranguinho!

 irb> c ^ s
 [Você golpeia com 2 pontos de dano!]
 #<ScubaArgentina:0x808c864 @carisma=91, @forca=35, @vida=44, @arma=2>
 [Seu inimigo golpeia com 28 pontos de dano!]
 [O Coelho morreu.]

Por Cristo de Deus!! Nosso exemplar de coelho morreu!!

Duras perspectivas. Eu não posso te pedir para retornar ao reino dos coelhos, no entanto, basta fingir como se você não tivesse morrido e fazer um novo coelho.

 irb> r = Coelho.new

 # atacando com bumerangue!
 irb> r ^ s

 # os golpes de espada do herói!
 irb> r / s

 # comendo alface lhe dá vida!
 irb> r % s

 # você possui três bombas!
 irb> r * s

Muito claro, você não diria? O código em coelho.rb modifica alguns símbolos matemáticos que trabalham somente com Coelho. Ruby lhe permite alterar o comportamento dos operadores matemáticos. Afinal, operadores matemáticos são apenas métodos!

 # o bumerangue é normalmente um operador XOR.
 irb> 1.^( 1 )
   => 0

 # a espada do herói normalmente divide números.
 irb> 10./( 2 )
   => 5

 # o alface dá o resto da divisão.
 irb> 10.%( 3 )
   => 1

 # a bomba é para multiplicação.
 irb> 10.*( 3 )
   => 30

Quando faz sentido, você pode optar por utilizar operadores matemáticos em algumas de suas classes. Ruby usa esses operadores matemáticos em muitas de suas próprias classes. Arrays, por exemplo, têm uma porção de operadores matemáticos que você poder ver na lista de instância dos métodos quando você digita: ri Array.

 # o operador mais combina dois arrays em um único array
 irb> ["D", "W", "E"] + ["M", "T", "H", "Y"]
   => ["D", "W", "E", "M", "T", "H", "Y"]

 # menos remove todos os itens do segundo array encontrados no primeiro
 irb> ["D", "W", "E", "M", "T", "H", "Y"] - ["W", "T"]
   => ["D", "E", "M", "H", "Y"]

 # o multiplicador repete os elementos de um array
 irb> ["D", "W"] * 3
   => ["D", "W", "D", "W", "D", "W"]

Você deve estar se perguntando: afinal, o que isso significa para a matemática? E se eu adicionar o número três para um array? E se eu adicionar uma string e um número? Como Ruby irá reagir?

Por favor, lembre-se, esses operadores são apenas métodos. Mas, uma vez que esses operadores não são palavras legíveis, fica difícil dizer o que eles fazem. Use o ri, muitas vezes você verá que os operadores são idênticos a outros métodos legíveis. Você pode optar por utilizar o operador ou o método, o que for mais claro para você.

 # divida com um método operador ...
 irb> 10 / 3
   => 3

 # ... ou um método legível?
 irb> 10.div 3
   => 3

Esta é forma que a espada do coelho divide.

A Dura Realidade do Array de Dwemthy TE AGUARDA PARA LHE ESMAGAR !!

Depois que você terminou de brincar de afogar o último cara com o tubo de oxigênio dele, é hora de entrar No Array. Eu duvido que você possa fazer isso. Você deixou sua machadinha em casa. Eu espero que você não tenha usado todas as suas bombas com o cara fácil.

Você possui seis inimigos.

 class MacacoIndustrialEntusiasmante < Criatura
   vida 46
   forca 35
   carisma 91
   arma 2
 end

 class AnjoDosAnoes < Criatura
   vida 540
   forca 6
   carisma 144
   arma 50
 end

 class TentaculoViceAssistenteEOmbudsman < Criatura
   vida 320
   forca 6
   carisma 144
   arma 50
 end

 class CervoDeDentes < Criatura
   vida 655
   forca 192
   carisma 19
   arma 109
 end

 class IntrepidoCiclistaDecomposto < Criatura
   vida 901
   forca 560
   carisma 422
   arma 105
 end

 class Dragao < Criatura
   vida 1340     # escamas duras
   forca 451     # veias ressaltadas
   carisma 1020  # sorriso dentado
   arma 939      # cospe fogo
 end

Estes são os exemplos vivos da monstruosidade do Array de Dwemthy. Eu não sei como eles chegaram lá. Ninguém sabe. Na verdade, eu acho que o @ IntrepidoCiclistaDecomposto@ pedalou até aqui a toda velocidade. Mas os outros: NINGUÉM sabe.

Se isso é realmente importante para você, vamos apenas dizer que os outros nasceram lá. Podemos seguir em frente??

Conforme o Array de Dwemthy vai ficando mais complexo, o desafio se torna mais difícil.

 dwary = ArrayDeDwemty[MacacoIndustrialEntusiasmante.new,
                       AnjoDosAnoes.new,
                       TentaculoViceAssistenteEOmbudsman.new,
                       CervoDeDentes.new,
                       IntrepidoCiclistaDecomposto.new,
                       Dragao.new]

Combata o Array e os monstros aparecerão ao passo que você continua. Boa sorte, e que você retorne com histórias horríveis e nenhuma garra de anjo cravada através de seus ombros.

Começa aqui:

 irb> r % dwary

Ah, e nada deste negócio “Eu sou muito jovem para morrer”. Estou farto desta besteira. Não vou mais tolerar seus insultos aos nossos jovens que ainda nos restam. Eles são nosso futuro. Assim que nosso futuro estiver terminado, ai sim.

O coelho nos modificou.

Por Trás do Array de Dwemthy

Avance para o tempo onde os ventos já tenham se acalmado. O Dragão foi derrotado. Os impuros se curvarão. Nós amamos você. Nós somos leais a você.

Mas o que esta centopéia está mordiscando seu tímpano? Você enfia o dedo para tirá-lo, mas não consegue! Maldito! É aquele infernal Array de Dwemthy novamente. Se explique Dwemthy!

Aqui, eu revelo o próprio Array para você.

 class ArrayDeDwemthy < Array
   alias _inspect inspect
   def inspect; "#<#{ self.class }#{ inspect }>"; end
   def method_missing( meth, *args )
     answer = first.send( meth, *args )
     if first.vida <= 0
       shift
       if empty?
         puts "[Uouuu.  Você dizimou o Array de Dwemthy!]"
       else
         puts "[Prepare-se. #{ first.class } surgiu.]"
       end
     end
     answer || 0
   end
 end

Até agora, provavelmente você está se sentido muito familiarizado com herança. A classe DwemthysArray herda de Array, portanto se comporta como um. Para tal sendo um mistério, é assustadoramente curto, não?

Portanto é um Array. Preenchido com monstros. Mas o que este código extra faz?

Inspect

O método inspect não é realmente uma parte necessária do Array de Dwemthy. É algo adicionado a Dwemthy como uma cortesia para seus visitantes. (Muito o chamam de pervertido, muitos o chamam de austero, mas todos nós somos ignorantes para ir sem admirar o trabalho que ele despendeu por nós.)

Cada objeto em Ruby possui um método inspect. Isto está definido na classe Object, então ele adiciona através da genealogia para cada pequenino objeto que nasce.

 irb> o = Object.new
   => #<Object:0x81d60c0>
 irb> o.inspect
   => "#<Object:0x81d60c0>"

Você percebeu? Sempre que criamos um objeto no irb, essa chamativa palavra #<Object> é apresentada! Isto é um pequeno nome identificador para o objeto. O método inspect cria este identificador, que é apenas uma string.

 irb> class Coelho
 irb>   attr_accessor :slogan
 irb>   def initialize s; @slogan = s; end
 irb>   def inspect; "#<#{ self.class } diz '#{ @slogan }'>"; end
 irb> end

 irb> class FalsoCoelho < Coelho
 irb> end

 irb> Coelho.new "eu arrebentei a cara do dragão!!"
   => #<Coelho diz 'eu arrebentei a cara do dragão!!'>
 irb> FalsoCoelho.new "Assim, assim e assim..."
   => #< FalsoCoelho diz 'Assim, assim e assim...'>

O fato é: irb está respondendo. Cada vez que você executa algum código no irb, o valor de retorno daquele código é inspecionado. Que prático. É uma conversinha entre você e o irb. E irb está apenas reiterando o que você está dizendo, então você mesmo pode ver.

Você poderia escrever seu próprio prompt Ruby de uma forma muito fácil:

 loop do
   print ">> "
   puts  "=> " + eval( gets ).inspect
 end

Este prompt não irá permitir que você escreva código Ruby mais longo do que uma única linha. No entanto, esta é a essência do Ruby interativo. Como que você gosta? Dois de seus conceitos recentemente aprendidos vieram juntos de um modo mais saboroso. O eval pega o código digitado e o executa. A reposta de eval é então inspecionada.

Agora, como você está combatendo monstros no irb, o Array de Dwemthy será inspecionado e respondido com os monstros que você deixou de lutar.

Os raposos comem fora.

Method Missing

Você não odeia quando grita “Deirdre!” e aproximadamente dez pessoas respondem? Isto nunca acontece em Ruby. Se você chamar o método deirdre, somente um método deirdre responde. Você não pode ter dois métodos com o mesmo nome. Se você adicionar um segundo método deirdre, o primeiro desaparece.

Você pode, no entanto, ter um método no qual responde para muitos nomes.

 class ChamadorDeNome
   def method_missing( nome, *args )
     puts "Você está chamando '" + nome + "' e você diz:"
     args.each { |diz| puts "  " + diz }
     puts "Mas ninguém está lá ainda."
   end
   def deirdre( *args )
     puts "Deirdre está bem aqui e diz:"
     args.each { |diz| puts "  " + diz }
     puts "E ela ama cada segundo disso."
     puts "(Eu acho que ela pensa que você é poético.)"
 end

Quando você chamar o método deirdre acima, eu tenho certeza que você sabe o que vai acontecer. Deirdre vai amar cada segundo disto, você e suas fascinantes poesias.

Mas e se você chamar simon?

 irb> ChamadorDeNome.new.simon( Olá?', 'Olá? Simon?' )
 Você está chamando `simon' e você diz:
   Olá?
   Olá? Simon?
 Mas ninguém está lá ainda.

Sim, method_missing (método faltando) é como uma secretária eletrônica, que intercepta a chamada de seu método. No Array de Dwemthy nos usamos um desvio, então quando você ataca o Array, ele passa o ataque diretamente para o primeiro monstro no Array.

 def method_missing( meth, *args )
   resposta = first.send( meth, *args )
   # ... código recortado aqui ...
 end

Veja! Veja! Aquele magrelinho method_missing passa a responsabilidade para outro!

4. Então, Sejamos Claros: O Porco-Espinho Está Agora Rumo Ao Mar

O porco-espinho e sua pipa.

5. Caminhando, Caminhando, Caminhando, Caminhando e Assim por Diante

A tardinha escureceu ao redor do par de raposos. Eles fizeram seu caminho através das vielas lotadas de gambás cantantes, e ruas onde girafas em casacos esportivos passavam por eles batendo com suas maletas. Eles continuaram caminhando.

E agora as lojas fechavam desenrolando suas portas de metal. Grilos cantavam das calhas e acotovelavam-se diante da relaxante mudança.

Por que tantos ressentimentos?

“De qualquer maneira, vocês devem admitir que ele é um péssimo Presidente,” disse Raposinho. “Por que o Presidente Marcos tem um coelho como Vice Presidente das Raposas."

“O Vice Presidente? o coelho com as sobrancelhas?”

“Não, o coelho com os enormes lábios de salsicha,” disse Raposinho.

Mas sua conversa foi abruptamente interrompida por um gato sardento que surgiu do céu em cima da calçada.

Pelo menos eles ainda estão no livro...

O que isto significa?!

O livro vai acabar?

Ah, qual é? Isto é interessante. Mais foco.

Eu não vou aporrinhar ilustrando esta discussão que Blixy teve com os raposos neste momento! É tudo um punhado de _conjectura_*. Como eles podem presumir que sabem o cenário do meu drama familiar? Eu amo minha irmã. Por um longo tempo, eu a adorei. (Esta é minha irmã Quil.)

Eu admito que houve um dia realmente doloroso há alguns meses atrás e eu meio que me apavorei. Eu estava deitado na cadeira de piscina no quintal da minha mãe. Eu tinha uma latinha de Dr. Pepper e um pedaço de torta alemã de chocolate. Estava comendo com um garfinho de criança. Todo o resto estava na lava-louças, isso era tudo que eles tinham. Três dentes.

Minha mãe começou a falar sobre Quil. Tudo sobre quanto dinheiro ela estava esbanjando em calças e bolsas. Uma bolsa de quinhentos dólares. Então ela disse, “Ela está perdendo isto. Ela parecia totalmente dopada no telefone.” (Ela cismou com isto, Quil estava fumando maconha e gostando.)

Então passei a notar o quão observadora minha mãe podia ser. Por isto que, quando ela disse, “Na verdade acho que ela está na cocaína,” Eu fisicamente levantei e arremessei meu refrigerante do outro lado do quintal.

Ele foi parar navegando entre os troncos em algum lugar. Nós ficamos conversando por um tempo, estava escuro quando a latinha voou. Eu marchei um pouco. Então gritei a plenos pulmões.

Meu tio Mike estava parado com a porta de vidro aberta, me encarando. Ele disse algo totalmente nervoso como, “Ah, ok. Bem, eu vou—” E o chá no seu copo estava balançando para frente e para trás, derramando tudo. Ele desapareceu. Ele não é muito bom em falar coisas para as pessoas. Ele é mais um assoviador. E ressonante.

Continuando.

Então, sendo completamente honesto, sim, eu fiquei um pouco bravo. Eu fiquei bravo. Você sabe. Eu lidei com isto. Quil me liga regularmente. Por alguma razão estúpida, raramente ligo para ela.

E mais, ela não acabou se matando. Então isto não é assunto. Quem pode saber se isso era real. Ela apenas tomou muita vodca. E ela é pequena. Então foi apenas assustador ver a Quil embebedar-se daquele jeito. Quer dizer forçar-se a isso.

Mas por que falar sobre isso? Isso fará apenas ela sentir que estou desapontado. Ou que sou um idiota.

Bem, saí um pouco da linha. Onde eu estava? Blix está basicamente ajudando os raposos, colocando-os na trilha do seu caminhão. Sim voltando aquilo tudo.

Sapos que guardam acentos no ônibus.
Tirinha: Sapos que guardam acentos no ônibus.

“Não podemos nos apertar para ir neste ônibus” disse Raposinho.

“Pessoal, subam,” disse Blix. “O que está impedindo? Ah, os sapos. Sim, apenas se apertem.” Blixy empurrou por trás.

“Ei,” disse Raposão. “Estou comprimido neste pequeno degrau! Alguém se mexa!”

“Você conseguiu— jovem raposa??” disse o gato.

“Não,” disse Raposinho, “não pode ver? O motorista continua balançando a cabeça e isso realmente me deixa nervoso. Eu não acho que ele nos queira.”

“Vai,” disse Blix. Desceu do seu degrau e andou pelo ônibus, espreitando através das janelas de acrílico. “Bem, eu não sei pessoal. Eu não sei. Eu acho que tem muitos sapos.” Ele bateu na janela. “Ei! Mexam-se!”

E esta é a realidade de andar no trânsito intermunicipal em Wixl. É terrivelmente competitivo. O ônibus da manhã é tão cheio que a maioria dos animais de colarinho branco conseguem sapos para guardar seus lugares durante o período da noite. Por qualquer razão, isto funciona. Se tornou mercadoria do fluxo de trabalho de sua economia.

Se você consegue reunir um pouco de imaginação, pode ver um sinal de percentagem como um rosto inclinado de um sapo. Visualizou a figura em sua cabeça? Agora deixe-me mostrar os sapos que acampam em strings.

 # O formato %s serve para posicionar strings cheias.
 irb> "Assentos são ocupados por %s e %s." % ['um sapo', 'um sapo com dentes']
   => "Assentos são ocupados por um sapo e um sapo com dentes."

 # O %d formato serve para colocar números, enquanto o formato %f serve para
 # floats (números decimais).
 irb> sapos = [44, 162.30]
 irb> imediatamente = "Os sapos preencheram %d assentos e pagaram %f cristais azuis."
 irb> imediatamente % sapos
   => "Os sapos preencheram 44 assentos e pagaram 162.30 cristais azuis."

 # A formatação é flexível com tipos, você pode transmitir em strings
 # e formatá-los como números.
 irb> sapos = ['44', '162.30']
 irb> imediatamente % sapos
   => "Os sapos preencheram 44 assentos e pagaram 162.30 cristais azuis."

O que você está vendo acima usa o método % nas classes String. Este método pega um string e um array e mastiga-os para criar uma nova string. Os itens da lista são puxados (em ordem) e colocados em seus lugares reservados. É o começo de um dia de negócios e os sapos já fizeram seu trabalho.

 # Observe, aqui está o método String#% chamado como os outros métodos.
 irb> "Mexa-se por favor, %s.".%( 'sapo desdentado' )
   => "Mexa-se por favor, sapo desdentado"

 # Agora vamos chamar da maneira mais bonita, com o sinal de porcentagem
 # entre o string e o array.
 irb> "Aqui está sua frase 1098 para o ano, %s." % ['sapo com dentes']
   => "Aqui está sua frase 1098 para o ano, sapo com dentes."

Isto também está disponível como o método Kernel::format ou o método Kernel::sprintf (Na linguagem C, tem um método sprintf que opera assim.)

 irb> format "Sapos são empilhados %d de profundidade e viajam a %d mph.", [5, 56]
   => "Sapos são empilhados 5 de profundidade e viajam a 56 mph."

Para a maioria das partes, você precisará somente %s (strings), %d (números inteiros) ou %f (números float) especificadores de formato. O símbolo %p irá executar inspect num objeto.

Sim, então, o formato sapo é realmente útil para construir strings que são montados por diferentes tipos de dados. Você pode aprender todos os vários tipos de especificadores de formatos lendo a pagina ri sprintf. Só te darei alguns rápidos indicadores.

Vamos dizer que você tem um array mas quer que os itens apareçam em uma ordem diferente na string. Numa situação como esta, você pode identificar itens específicos (colocando 1$ para o primeiro item, 2$ para o segundo, e assim por diante) depois do sinal de porcentagem.

 irb> "Este ônibus tem mais %1$d paradas antes das %2$d horas.  Isto são mais %1$d paradas." % [16, 8]
   => "Este ônibus tem mais 16 paradas antes das 8 horas.  Isto são mais 16 paradas."

A segunda dica que tenho para você é que pode destinar um certo número de caracteres para cada item, uma largura. E se um item é menor que a largura, espaços extras serão usados antes do item. Para preenchê-lo. Se a largura é um número negativo, o item será forçado para esquerda e o preenchimento virá depois dele.

 # Dê a um item 30 caracteres de largura
 irb> "Na traseira do ônibus: %30s." % ['sapos']
   => "Na traseira do ônibus:                          sapos."

 # Dê a um item justificado a esquerda 30 caracteres de largura
 irb> "Na parte da frente do ônibus: %-30s." % ['sapos']
   => "Na parte da frente do ônibus: sapos                         ."

Raposinho continuou olhando para o motorista do ônibus. Lembre-se, ele não entraria no ônibus!

“Qual o problema?” disse Raposão. “Você não pode entrar e ficamos no corredor?”

“Você realmente quer entrar neste ônibus? Aquele motorista não tem mãos,” disse Raposinho, falando perto de maneira a aquietar Raposão, “e tudo o que ele tem, ao invés de mãos, são copos com canudos.”

“E então? Você não acha que animais com tentáculos podem dirigir?”
“Bem, não é só ele que vai se dar mal ao volante, mas ele tem todas essas pernas em cima dos pedais. Isso não é inteligente. Vamos pegar outro ônibus. Vamos lá.”
“Você sabe, ele provavelmente está sendo conduzido como todos os dias. Será que ele vai realmente começar a bater nesta fase da carreira dele?”
“Os ônibus batem”, disse Raposinho. “Alguns fazem. Isto cheira a batida”.

“Desvia ,merda!” e Raposão gritou para o motorista, “Ei, motorista, há quanto tempo você dirige este ônibus?”
O motorista do ônibus olhou misteriosamente por baixo da aba do seu boné e começou a virar-se em direção a eles, mas os seus tentáculos ficaram presos à roda. Ele rapidamente sacudiu suas pernas da frente e, falhando em soltá-las, virou-se para a direção e concentrou as suas energias em ordenhar de suas glândulas um pouco de ótimas secreções. Bolhas de muco gotejaram.
“Vamos cair fora daqui”, disse Raposão e os dois correram para fora da rua, batendo direto no gato Blix.

“Está bem, bem, o ônibus está cheio,” disse Blix. “Eu não sei por que o motorista parou se ele sabia que o ônibus estava cheio de gafanhotos.”

“Nós estamos pensando que ele estava prestes a bater contra nós,” disse Raposão, “e ele abriu a porta para fazer parecer como uma parada planejada.”

“Tenha em mente, Blix, nós não tínhamos realmente discutido essa possibilidade em voz alta, então eu não tive uma chance para concordar formalmente,” disse Raposinho. “No entanto, isto parece racional para mim.”

“Eu estou pensando que todos os ônibus vão estar cheios como este.” Blix mordeu seu lábio, pensando e piscando os olhos. “Vamos apenas—” Ele apontou abaixo o circuito de edificações de apartamento que mudariam para o sul. “Mas talvez—” Ele olhou para cima e avaliou as estrelas, coçando a cabeça e contando as constelações com leves toques na pontas de seu dedo.

“Você está obtendo nossa orientação a partir das estrelas e planetas?” perguntou Raposinho.

Blix não falava, ele abaixou a cabeça para o norte através de uma avenida uma avenida mal colocada voltar atrás da loja de tinta. Mas antes que nós os sigamos em baixo nessa estrada de serviço, cara pálida, Eu tenho mais um sapo para você, empoleirados sobre uma longa vitória régia que esticadas para fora para prender alguma coisa em tudo.

 irb> gato = "Blix"
 irb> puts "O #{ gato } vê o que esta rolando? Está o #{ gato } prevenido??"
   => "O Blix vê o que esta rolando? Está o Blix prevenido??"

Os pequenos sapos de anteriormente (%s ou %d) eram apenas incógnitas para strings únicas. Guardando lugares na string.

As vitórias-régia começam com um broto de uma flor, a cerquilha (sustenido ou jogo-da-velha). Você também já o viu como um sinal da libra em telefones. Depois dos brotos das flores, duas folhas formam as bordas da vitória-régia. As folhas são braços enrolados (chaves), também vistas muitas vezes antes como (as garras do caranguejo) para um bloco de código.

Uma vitória-régia vazia "#{}" se torna uma string vazia "".

Quando a vitória-régia é encontrada em uma string com aspas duplas, Ruby executa algum código encontrado entre as duas folhas da vitória-régia. A vitória-régia é erguida e o resultado do código é colocado numa string. Esta troca da vitória-régia é chamada de interpolação de string.

 irb> companheiros = ['Blix', 'Raposão', 'Raposinho']
 irb> puts "Deixe-nos seguir #{ companheiros.join ' e ' } em sua viagem."
   => "Deixe-nos seguir Blix e Raposão e Raposinho em sua viagem."

A vitória-régia é muito estável e pode armazenar qualquer tipo de código em seu interior. Acima estamos usando Array#join, mas você pode fazer qualquer coisa que queira. Chamar métodos de objeto, condicional de declarações if ou case, até mesmo definir classes.

 irb> blix_foi = :norte
 irb> puts "Blix não falou, ele curvou a cabeça para o #{ blix_foi } voltando-se para #{
             if blix_foi == :norte
               'uma avenida mal colocada atrás da loja de tinta'
             elsif blix_foi == :sul
               'o circuito de edificações de apartamento'
             else
               '... bem, quem sabe onde ele foi.'
             end }. Mas antes que os sigamos..."
 => "Blix não falou, ele curvou a cabeça para o norte voltando-se para uma avenida mal colocada
     atrás da loja de tinta. Mas antes que os sigamos..."

Os raposos seguiram Blixy por trás da loja de tinta pelo asfalto rachado e irregular. Todas as lojas na pista dilapidada se inclinaram em ângulos entre elas. Em alguns lugares, placas da calçada sobressaíam da terra, formando uma arriscada passagem, uma desordenada pilha de bordas. Quase como se os planejadores da cidade tinham esperado para pagar tributo para as placas tectônicas. Uma pequena farmácia tinha deslizado para baixo da superfície, quase longe de vista.

Verdadeiramente, embora era colorido. A loja de tinta tinha jogado para fora as tintas velhas diretamente em seus vizinhos. As lojas mais próximas da loja de tinta foram obstruídas com centenas de cores, ao longo dos parapeitos das janelas e nas calhas de chuva. Sim, nas paredes e calçamento.

Basicamente, começando com a entrada da loja de tintas, a avenida entrou em erupção em uma gigantesca incongruente mercado infelizmente colorido.

Mais a diante, um escritório de um dentista foi preparado com a tinta vermelha, um artista inexperiente descreveu um grande bebê que tinha caído através de uma chaminé e chegado em um lareira completamente de fuligem. Levantou uma nuvem grossa e preta de cinzas durante o impacto, facilmente confundido pelo cabelo grosso sobre os braços e costa da criança. A criança olhou longe e viu que era nova para ter muito cabelo, mas lá eles eram: rico, ondas loiras qual caíram generosamente da cabeça da criança. Sob as pernas da criança foi pintado a palavra BREWSTER.

O mesmo artista tinha batido na biblioteca próximo a loja e tinha batido com pressa junto a um mural de carro esportivos verde sendo puxado da lama por uma equipe de bebês sem perna puxando-os com correntes brilhante. Outra vez, a drástica onda loira!

“Eu preciso de respostas,” disse Raposão, que tinha terra para uma parada em frente de vista.

“Eu estou começando acreditar que não existe,” disse Raposinho. “Talvez estes são as respostas.”

“Brewster?” disse Raposão. Ele caminhou mais próximo a biblioteca e tocou o mordente de um dos crianças sem perna que estava mais próximo do ponto de vista. O mordenite da criança apareceu com a mandíbula de baixo.

Blix foi a outras duas casas para baixo, navegando através da construção torta de alvenaria, a sarjeta pavimentada que o conduziu para R.K.’s Gorilla Mint, com a etiqueta metálica leu sobre a porta. O edifício foi emplastrado com logotipos miniaturas para a variedade de opções de pagamento e uma aceitável identificação em R.K.’s Gorilla Mint. Mesmo as barras sobre a janela foram alinhadas com divulgações de seguro e avisos de seguranças e selos de autorização do governo, assim como adicionando a todos estas, etiquetas coberta com papel carbono cobrindo posteres rasgados e propagandas. E tudo misturado com respingos de tinta que penetrou-os satisfatoriamente.

R.K.'s Gorilla Mint.

“Eu gosto da maneira que sinto o papel fresco contra minha língua,” disse o gorila no caixa. os dedos dele esfregaram silenciosamente as notas. Ele aproximou seu rosto em direção a moeda fresca e passou em seu nariz o dinheiro macio.

“O R.K. está aqui nessa noite?” perguntou Blix.

“R.K não está,” disse o caixa gorila. ele voltou-se para os três viajantes e espalhou o seu dinheiro na superfície do caixa, espaçando-os igualmente e alinhando todos os cantos impecavelmente. “Agora, qual destes vocês acham que vale mais?”

Os raposos olharam sobre as diferentes notas e Raposinho murmurou a si mesmo, “Bem,” talvez— não, mas eu apostarei— Espere, uma dessas tem bananas nela? Por que esta não, nenhuma fruta ou corda de pular ou— terrível, isto é difícil!" e em uma voz mais baixa, “Tão difícil ler. O que isso quer dizer?” Símbolos ou alguma coisa? Se todas essas notas têm símbolos, será impossível para nós compreender qual é a de maior valor."

“Foi por isso que eu disse, ‘Adivinhe.’” O gorila bateu cada nota em ordem. “Veja, você tem” uma em cinco chances."

“A menos que os símbolos signifiquem alguma coisa, disse Raposão. “A não ser que nós pudermos compreender”

“Nós podemos compreender,” disse a Raposinho.

“Não,” disse o gorila. “os símbolos não têm significado algum.”

“Seja quem for que criou o dinheiro pensou em algum significado para eles,” disse Raposinho. “Por que usar _este_símbolo?” Ele apontou para uma conjunção (e comercial) impressa em tinta escura.

“Sim, nós vimos você cheirando o dinheiro e fantasiando a respeito lá atrás,” disse Raposão. “Eu aposto que estes símbolos significam todo tipo de coisas para você!”

“Não, Eu acho que não,” disse o gorila.

Se eu puder avaliar por este ponto, eu acho que os símbolos têm significado. Eles podem não ser carregados com significado, eles podem não estar transbordando significado através das rachaduras, mas eu estou certo que existe uma lasca de significado.

 irb> $:
   => ["/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i686-linux", "/usr/lib/ruby/site_ruby", 
       "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i686-linux", "."]

Variáveis que começam com o símbolo monetário são variáveis globais. Elas podem ser vistas de qualquer lugar do programa, de dentro de qualquer escopo. (Dr. Cham usava esta variável enquanto bisbilhotava em volta da baia do computador dos Originais.)

Então porque o sinal de dinheiro seguido por dois ponto representa um array de todos os diretórios onde Ruby irá procurar quando você tenta carregar um arquivo com @require@*? O símbolo de dinheiro significa “global.” Mas por que os dois pontos?

Historicamente, em muitos sistemas operacionais, uma lista de diretórios continham os dois pontos que separava cada entrada. Eu gosto de ver os dois pontos como um par de olhos, vasculhando os diretório por arquivos. Nós armazenamos nossa lista de observação atrás destes olhos.

Aqui estão mais algumas variáveis globais especiais:

 irb> $"      # A variável $" contem todos os arquivos que foram carregados com 'require' 
   => ["irb.rb", "e2mmap.rb", "irb/init.rb", ... "rbconfig.rb"]
              # Estes arquivos estão armazenados em outros lugares, mas seus 
              # códigos estão sendo usados neste programa. Como se estivéssemos
              # referenciando o trabalho de outra pessoa  -- estas são as notas de rodapé
              # -- por isso as aspas duplas.

 irb> $0      # A variável $0 o nome do arquivo do programa que está sendo rodado.
   => "irb"   # Um zero pode ser considerado como o início da contagem de números.
              # Esta variável responde a seguinte questão, "Onde este programa começou?"

 irb> $*      # A variável $* contem todos os argumentos passados para um programa.
   => ['--prompt', 'simple']
              # Este aqui é fácil de se lembrar, se você se lembrar que os métodos Ruby
              # também usam asteriscos para capturar argumentos em um array.

 # O $! contem a exceção atual que foi levantada.
 # A exclamação indica um estado de alerta.  Uma exceção!
 irb> begin
 irb>   raise TypeError, "Não acredito nesta informação."
 irb> rescue
 irb>   p $!
 irb> end
   => #<TypeError: Não acredito nesta informação.>

 # O $@ contem o backtrace atual, caso uma exceção tenha sido provocada.
 # O backtrace apresenta onde o Ruby _estava_ quando a exceção foi provocada.
 irb> begin
 irb>   raise TypeError, "Não acredito nesta informação."
 irb> rescue
 irb>   p $@
 irb> end
   => ["(irb):25:in `irb_binding'", "/usr/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'", 
       "/usr/lib/ruby/1.8/irb/workspace.rb:52"]

“Eu não me lembro de você.” Blix olhou para o gorila com muito interesse. “Você é um dos filhos de R.K. ou algo parecido?”

“Ah, vamos lá!” disse Raposinho, segurando uma nota com uma exclamação no nariz do gorila. “Não me diga que isso não significa nada para você! Esta aqui é provavelmente muito importante já que tem uma exclamação nela. Talvez ela pague por coisas de emergência! Contas de hospital ou algo do gênero!”

“Sim, cirurgia!” disse Raposão.

O gorila olhou para os raposos com desgosto sob a borda de seu boné. “Não, vocês estão errados. Vocês não podem pagar por cirurgias com isso.”

“Mas você entende nosso ponto de vista”, disse Raposinho. Ele agarrou algumas das outras notas. “E você me diz que esta conta não pode pagar por cirurgias? Bem isso parece um propósito específico não relacionado a cirurgia. Agora, esta aqui com o interrogação. Para que ela serviria?”

“Ei, me de estas aí,” o gorila apanhou as notas sobre o balcão, mas seu longo polegar continuava a ficar no caminho e toda vez que ele achava que tinha pegado as notas, ele percebia que só tinha conseguido pegar seu próprio dedão.

“Ei, ei, olhem, ele está nervoso,” falou Raposão, aplaudindo com alegria. “Eu me pergunto por quê. Você percebeu quão bravo ele ficou uma vez que falamos todos estes significados interessantes? *Nós estamos espertos com você! *Nós entendemos seu jogo tão rápido!”*

“Totalmente!” disse Raposinho, um de seus braços pego pelo gorila, o outro braço agitando uma nota que exibia um travessão. “Esta aqui é para comprar suprimentos para o chão, talvez até grandes rolos de ladrilhos e tecidos impermeáveis”

“Vê,” disse Raposão, trabalhando para soltar os dedos do gorila, “nós apenas temos que descobrir o que é mais caro: cirurgia ou tecido impermeável! Isso é _tão fácil”_

“NÃO É NÃO!” berrou o gorila, chacoalhando Raposinho e o batendo com suas palmas. VOCÊ NÃO SABE NADA SOBRE DINHEIRO DE MACACO!! VOCÊ NÃO TEM MESMO SEU PRÓPRIO TIPO DE DINHEIRO!!"

Nós poderíamos facilmente ter nossos próprios tipos de dinheiro!" Disse Raposão, pegando o boné do chimpanzé e jogando-o para o fundo da sala, onde ele navegou para trás de uma parede de caixas de depósito de segurança. “E — seu chapéu está longe daqui!

“Vamos lá, devolva logo as notas dele,” disse Blix, acenando os braços sem chance de ajuda, fora do jogo. “Poderíamos realmente ter a ajuda deste cara.”

“Pare de bater em mim!” gritou Raposinho. “Estou quase entendendo esta aqui com os pontos!!”

De repente, com grande precisão e sem avisar, Raposão agarrou o nariz do macaco e bateu sua cara contra o balcão. As canetas e tintas em sua superfície agitaram-se e “Bam!” disse Raposão. Os olhos do gorila viraram-se com sonolência a medida que seus braços… então seu pescoço… e então sua cabeça escorregaram para o chão atrás do balcão.

Aqui estão mais algumas variáveis globais que talvez você possa querer usar:

 irb> $/      # O $/ é a linha separadora, ele é normalmente configurado para \n, o qual representa o _Enter_
   => "\n"    # ou "o final da linha".  A barra representa uma espada que corta e reduz linhas em um arquivo.

 # A linha separadora controla como os métodos each_line ou readlines quebram as strings.
 irb> "Jeff,Jerry,Jill\nMichael,Mary,Myrtle".each_line { |nomes| p nomes }
   => "Jeff,Jerry,Jill\n"
   => "Michael,Mary,Myrtle"

 # Se você mudar a linha separadora, você muda como os métodos trabalham, tal como o each_line.
 # Veja o que acontece quando eu mudar a linha separadora por uma vírgula.
 irb> $/ = ','
 irb> "Jeff,Jerry,Jill\nMichael,Mary,Myrtle".each_line { |nomes| p nomes }
   => "Jeff,"
   => "Jerry,"
   => "Jill\nMichael,"
   => "Mary,"
   => "Myrtle"

 irb> $,     # O $, é a variável que une o separador, usado ao unir strings com
   => nil    # Array#join or Kernel::print. A vírgula é um caractere comum de junção.

 # O separador de junção está normalmente vazio.
 irb> ['vela', 'sopa', 'mackarel'].join
   => "velasopamackarel"
 irb> $, = ' * '; ['vela', 'sopa', 'mackarel'].join
   => "vela * sopa * mackarel"

 # Mas, geralmente, você não necessitará de uma variável global.
 irb> ['vela', 'sopa', 'mackarel'].join ' # '
   => "vela # sopa # mackarel"

 irb> $;     # O $; a variável é o separador que divide, usado ao dividir strings
   => nil    # com String#split.

 # O separador split está normalmente vazio, que significa que String#split separará
 # a string onde há um espaço em branco.
 irb> "vela  sopa\nmackarel".split
   => ["vela", "sopa", "mackarel"]
 irb> $; = 'a'; "vela  sopa\nmackarel".split
   => ["vel", "sop", "\nm", "ck", "rel"]

 # Mas, geralmente, você não necessitará de uma variável global.
 irb> "vela # sopa # mackarel".split ' # '
   => ['vela', 'sopa', 'mackarel']

Fora do Casa da Moeda do Gorila, Blix repreendeu aos raposos. “Nós poderíamos ter aproveitado a ajuda desse cara! Se sabe onde está R.K., nós poderíamos usar a astúcia dele!”

Não precisamos do dinheiro do macaco!” disse o Raposinho. “Podemos criar nosso próprio dinheiro!

Nós podemos suportar pulseiras eletrônicas!” disse o Raposão.

“Seu dinheiro é sem valor,” disse Blix. “O dinheiro é do gorila. Não tem valor. Ele é pior do que os cristais azuis.”

“Mas serve para uma finalidade,” disse o Raposão.

“Não ele não serve,” disse Raposinho. “Ele apenas disse que o dinheiro não tem importância.”

“Mas sobre o tapete impermeável e as cirurgias?” disse Raposão.

“Sim,” disse o Raposinho para Blix. “O que dizer do tapete impermeável e as cirurgias?”

“Se todos os hospitais possuem uma equipe de gorila e toda as casas receberam uma rede de melhorias estritamente operadas por gorila, então — SIM — você poderia comprar o tapete impermeável e as cirurgias. Mas eu garanto que você teria um tapete impermeável desleixado e muitas cirurgias horríveis. Não acho que você conseguiria tirá-lo desta economia com vida.”

“Assim, se R.K. é tão esperto,” disse o Raposão, dando risada dissimuladamente, “por que imprime tal moeda sem valor?”

“Ele é a tampa para outras atividades,” disse Blix. “Além do que, se você é tão esperto, por que você recorreu violentamente derrotando aquele pobre gorila?”

“Eu suponho que foi um mau jogo,” afirmou Raposão, pendendo sua cabeça. “Meu amigo, direi a você que fiquei de saco cheio o dia inteiro.”

“E sua raiva finalmente levantou seu focinho fumegante!” falou Raposinho. “Você finalmente está vivendo a vida à altura do seu cavanhaque.”

Percorriam sobre as pistas, os dois raposos distraídos no seu rumo, mas divertindo-se agora que tinham Blix conduzindo-os pelo caminho com tanta urgência. Eles passaram o tempo vagando descuidados bem atrás de Blix e gastando sua tarde importunando a maioria dos pedestres.

Um dos alvos dos seus permanentes comentários eram Os Transportadores Alados de Pergaminho, pares de morcegos que carregam documentos que precisam ser imediatamente autenticados. Não pode haver nenhum atraso, eles devem ser ligeiros, não há mesmo tempo para enrolar o pergaminho, não, eles devem deixar cair seus queijos suíços e sair pela porta.

Estes correios assemelham-se a um tipo de construção do Ruby chamado tipos delimitados. Uma série longa de caracteres equivale ao pergaminho, defendido em cada lado por um morcego cercando suas asas onduladas para manter o pergaminho unido. O morcego da ponta usa um chapéu em que está escrito %w, que identifica o pergaminho como um conjunto de palavras.

 irb> bats = %w{Os Transportadores Alados de Pergaminho}
   => ['Os', 'Transportadores', 'Alados', 'de', 'Pergaminho']

Os morcegos de %w e seus pergaminhos, quando alimentados dentro do Ruby, emergem como um array de palavras. Esta sintaxe é um atalho caso você não queira atravessar o problema de decorar cada palavra com vírgulas e citações. Você está com pressa, também, não pode haver nenhum atraso. Você rabisca as palavras entre os morcegos e deixa o Ruby descobrir onde cortar.

Outros morcegos, outros chapéus. Por exemplo, o chapéu de %x funciona como um programa externo.

 irb> %w{ruby --help}
   => ["ruby", "--help"]
 irb> %x{ruby --help}
   => "Usage: ruby [switches] [--] [programfile] [arguments] ..."

Meu favorito é o chapéu Q. que pode também ser escrito apenas como %. Isto atua como uma string de aspas duplas, mas fica legal quando usado com strings que ocupam muitas linhas. Por exemplo, digamos que você quer adicionar um novo método com eval.

 m = "morcegos!"
 eval %{
   def #{ m }
     puts "{" * 100
   end
 }

Assim como se faz com uma string de aspas duplas, você pode usar interpolação de strings com vitórias-régia (#).

Clonefrutas: Quanto mais você come, Mais de *Você*.

Blixy sacudiu sua cabeça. “Oh, não.”

“Caramba! Minha mão está grávida,” disse Raposão, vendo o pequeno embrião de raposa escorregando em sua mão.
“Elas são boas frutas, apesar de tudo,” disse Blix. “O vinho que fazem destas frutinhas fará nascer alguns olhos nos seus dentes. Mas nada além disso.”

“Ah, dor!” gritou Raposinho, a medida que sua miniatura saia através dos poros de seu couro. Mas logo ele estava ninando seu pequeno eu e murmurando canções de ninar. Nunca mais, nunca mais, cantava docemente o rouxinol. Luz piscante das estrelas, dormindo tranqüilo, enquanto empoleirado num pedaço de Plátano.

Fazer duplicatas dos objetos Ruby não é nada mais do que uma fruta de código.e.

 irb> arvore = [:fruta, :fruta, :fruta]
   => [:fruta, :fruta, :fruta]
 irb> filhoarvore = arvore.clone
   => [:fruta, :fruta, :fruta]

O método clone faz uma cópia exata de um objeto Ruby. Como isso difere de uma atribuição comum?

 irb> arvore_charles_william_iii = arvore
   => [:fruta, :fruta, :fruta]

A atribuição de um objeto a variáveis apenas cria mais apelidos. O Array acima pode ser chamado arvore_charles_william_iii agora. Ou o mais curto arvore. O mesmo objeto, mas nomes diferentes.

Entretanto, um clone é uma cópia de um objeto. Você pode alterá-lo sem afetar o original.

 irb> filhoarvore << 'flor'
   => [:fruta, :fruta, :fruta, 'flor']
 irb> arvore
   => [:fruta, :fruta, :fruta]

Contudo, o método clone não faz cópias de tudo que está amarrado ao objeto. No array acima, apenas o array é copiado, não todos os símbolos e strings que estão dentro.

Você também pode ver o método dup sendo usado para copiar objetos. O método dup faz cópias que não são tão exatas. Por exemplo, existem objetos em Ruby que estão “congelados” e não podem ser alterados. Se você fizer um clone do objeto, terá uma cópia exata que também estará congelada. Se você usar dup, você terá uma cópia descongelada que você poderá alterar se quiser.

O método clone também copia a metaclasse de um objeto, enquanto o dup não.

 irb> o = Object.new
 irb> class << o
 irb>   def nuncamais; :nuncamais; end
 irb> end

 irb> o.clone.nuncamais
   => :nuncamais
 irb> o.dup.nuncamais
 # NoMethodError: undefined method `nuncamais' for #<Object:0xb7d4a484>
 #         from (irb):7
 

Nem sempre você precisa fazer cópias dos objetos, de qualquer maneira, já que muitos métodos como collect, gsub e format fazem cópias para você como parte trabalho deles.

Veado da Fumaça Rosa Bafejante.

Sobre as colinas e nos vales, eles correm pela grama onde perambula o Veado da Fumaça Rosa Bafejante. O sol estava encoberto pelas pesadas nuvens rosas, repletas de linguagem de veado, colorindo o horizonte com um gradiente de toranja e produzindo um brilho sobre a colina. As nuvens deslizavam umas sob as outras, algumas flutuando para cima, com destino a parentes canadenses. Outras aterrisando numa distância legível dos cascos de quem vê.

“Vamos parar! Por favor!” gritou Raposão. Você não espera que corremos no meio desta penugem irrespirável"!

“Por que você está gritando?” falou Blix, enquanto uma fina camada de nuvens flutuava arás de suas pernas. “Você não precisa levantar sua voz além de um sussurro. Estas longas e finas nuvens são geralmente só um murmuro ou um suspiro Elas podem conseguir nem mesmo chegar até seu destino.”

“Todos esses escritos nas nuvens são conversa de cervos?” disse Raposinho.

“Ajudem-me! Onde vocês estão, caras?” Raposão abaixou-se através de uma tempestuosa lengalenga formada por uma densa ondulada fumaça e moitas afiadas. Ele girou em todas direções, “Alguém grite se estiver aí!”

Procurou por uma fenda na densa matéria, penteando para frente com suas mãos. As eloqüentes, furiosas nuvens responderam-no espetando-o para adiante, forçando-o para cantos apertados em suas breves pausas entre as frases. Ele ficou em um sumidouro e manteve sua cabeça baixa a medida que as cascatas de fumaça agitavam-se adiante.

“Sim, os cervos podem ler estas coisas,” afirmou Blix. “Eles apenas encaram seus alvos e atiram-nas de suas narinas. Escutei uma vez sobre um cara que tinha cavalgado em um poema de amor cervídeo.”

“Sem chance,” falou Raposinho.

“Sim,” disse Blix. “E este cara era eu.” Blix alcançou seu ombro e juntou-se a uma espiral de fumaça que girava acima de sua cabeça. “Você apenas tem que saber quais nuvens são fracotes e quais são pomposas”. Blix deixou a nuvem puxá-lo e quando a nuvem voou para cima, Blix perdeu seu apoio e manteve seus pés movendo vagarosamente ao longo do chão. "Vê, está aqui é uma das boas, longa como um cabo de vassoura. Um cara descobriu uma uma vez que tinha a forma exatamente igual a de um carro: pára-brisa, airbags laterais para o motorista, direção hidráulica. " Excepcional!"

E este cara era—

“Ele era!” E Blix escalou sobre a longa nuvem gelada, com seus hieróglifos pendurados, e manteve-se em pé orgulhosamente, flutuando bem acima da pontuda sombra do raposo.

“Ah, eu poderia fazer isso” disse Raposinho. “Eu e Raposão andamos de jetski o tempo todo. Eu fico em pé no meu jetski. É igualzinho a isso.”

Raposão lançou-se sobre uma fumaça descendente, chacoalhando sua frase, cujas letras se descolaram e se espalharam pelo chão com palavras embaralhadas, mas ele tinha apenas sucedido em alcançar as partes depressivas das correspondências dos cervos, que se manifestavam como uma úmida e opaca névoa.

Enquanto isso, sua contraparte pequena agarrou um estreito trem de fumaça que passava sob seu braço. Ele foi aerotransportado e gritou, Tallyho! Mas se segurou muito firmemente e a nuvem evaporou sob seu braço e o enviou de volta ao chão com um pequeno salto.

Dado que está apenas começando seu uso de Ruby, você pode não ter entendido completamente as expressões regulares (ou regexps) de início. Você pode até mesmo se encontrar recortando as regexps da Biblioteca de Expressões Regulares e colando-as no seu código sem ter a mínima idéia de porque a expressão funciona. Ou se ela funciona!

 loop do
   print "Entre com sua senha: "
   senha = gets
   if senha.match( /^\w{8,15}$/ )
     break
   else
     puts "** Senha inadequada! Deve ter entre 8 e 15 caracteres!"
   end
 end

Você vê a ilegível linguagem de cervo no código de exemplo? O /^\w{8,15)$/ é uma expressão regular. Se posso traduzi-la, a regexp está dizendo,Por favor, permita somente letras, números ou travessões. Não menos que oito e não mais que quinze.

Expressões Regulares são uma mini-linguagem construída dentro do Ruby e muitas outras linguagens de programação. Eu, na verdade não deveria dizer mini, já que regexps podem ser complicadas e tortuosas e muito mais difíceis que qualquer programa Ruby.

Usar expressões regulares é extremamente simples. É como o Cervo: fazer fumaça é um processo árduo. Mas forçar seus ombros sobre a fumaça e direcionar-se para o Weinerschnitzel para pegar um pretzel de cachoro quente e mostarda é fácil.

 irb> "senha_adequada".match( /^\w{8,15}$/ )
   => #<MatchData:0xb7d54218>
 irb> "esta_senha_inadequada_muito_longa".match( /^\w{8,15}$/ )
   => nil

O método String#match é o uso prático mais simples das regexps. O método match checa para ver se a string se adequa as regras dentro da regexp. Uma regexp só é útil com strings, para testar strings por uma série de condições. Se as condições são atendidas, um objeto MatchData é retornado. Caso contrário, você terá nil.

As expressões regulares mais básicas são para realizar buscas dentro de strings. Digamos que você tem um grande arquivo e quer procurar nele por uma palavra ou frase. Já que um tempinho se passou, vamos procurar dentro dos registros de Achados e Perdidos dos Pré-eventualistas novamente.

 require 'preeventualist'
 PreEventualist.achadoperdido( 'caminhao' ) do |page|
   page.each_line do |linha|
     puts linha if linha.match( /caminhao/ )
   end
 end

Isto não é muito diferente do código que usamos anteriormente para linhas com a palavra “caminhão”. Anteriormente usamos puts linha if linha['caminhao'], o que é na verdade um jeito mais simples de se procurar dentro de uma string, se você está procurando apenas por uma simples palavra. A regexp /caminhao/ é idêntica. Encontre a palavra “caminhao”. Em qualquer lugar da string.

Hmn, mas e se caminhão for maiúscula. Caminhão. E então?

 puts linha if linha.match( /[Cc][Aa][Mm][Ii][Nh][Aa][Oo]/i )

As classes dos caracteres são as seções cercadas por colchetes. Cada classe de caractere dá uma lista de caracteres que são compatíveis para este lugar. (O primeiro lugar é compatível tanto um C maiúsculo quanto um c minúsculo. O segundo lugar é compatível com um A ou um a. E assim por diante.)

Mas um jeito mais simples de escrever isso é assim:

 puts line if line.match( /caminhao/i )

A letra i no final da regexp é um modificador que indica que a busca não é sensível a caixa. Ela casará com Caminhão. E CAMINHÃO. E CaMiNhÃo. E outras combinações de maiúsculas e minúsculas.

Ah, e talvez seu caminhão tenha um certo número de modelo. Um T-1000. Ou um T-2000. Você pode se lembrar. É algum T alguma coisa mil.

 puts linha if linha.match( /T-\d000/ )

Vê, linguagem de cervo. O \d representa um digito. É uma incógnita na regexp para qualquer tipo de número. A regexp irá agora casar com T-1000, T-2000, e tudo em diante até T-9000.

Classes de Caracteres
\d casa dígitos também pode ser escrita como [0-9]
\w casa caracteres de palavra (letras, números e o travessão) também pode ser escrita como [A-Za-z0-9_]
\s casa espaços em branco (espaços, tabs, retorno de carro, pula linha) a.k.a. [\t\r\n]
\D casa tudo menos dígitos um conjunto negado [^\d]
\W casa tudo menos caracteres de palavra assim como [^\w]
\S casa tudo menos espaços em branco também [^\s]
. o ponto casa tudo.

Construir uma expressão regular envolve encadear esses receptáculos para expressar sua busca. Se estiver procurando por um número seguido de espaço em branco: /\d\s/. Se estiver procurando por três números em seqüência: /\d\d\d/. As barras que abrem e fecham marcam o início e o fim da expressão regular.

Uma busca por três números em seqüência também pode ser escrita como: /\d{3}/. Imediatamente após uma classe de caracteres como \d, você pode usar um símbolo de quantidade para dizer quantas vezes quer que aquela classe de caracteres seja repetida.

Quantificadores
{n} casa exatamente n vezes Precisamente três números em seqüência é /\d{3}/
{n,} casa n vezes ou mais Três ou mais letras em seqüência é /[a-z]{3,}/i
{n,n2} casa pelo menos n vezes mas não mais que n2 vezes Então, /[\d,]{3,9}/ casa entre três e nove caracteres que são números ou vírgulas
* o asterisco * é a forma curta para {0,} Para casar dois pontos, seguidos de zero ou mais caracteres de palavra: /:\w*/
+ o sinal de mais é a forma curta para {1,} Para casar um ou mais sinais de menos ou mais, use /[-+]+/
? a interrogação é a forma curta para {0,1} Para casar três números seguidos de um ponto opcional: /\d{3}[.]?/

Uma expressão regular bem comum é uma que case números de telefone. Números de telefone norte-americanos (incluindo código de área) podem ser casados usando a classe de caractere de dígito e os quantificadores precisos.

 irb> "Ligue 909-375-4434" =~ /\d{3}-\d{3}-\d{4}/
   => 6
 irb> "O número é (909) 375-4434" =~ /[(]\d{3}[)]\s*\d{3}-\d{4}/
   => 11

Desta vez, em vez de usar match para procurar pela expressão, usou-se o operador =~. Este operador é o operador de casamento, um sinal de igual seguido de um til. O til é como uma fumacinha saindo da ponta de uma chaminé. Lembre-se dos cervos, a fumaça que eles soltam, uma linguagem críptica assim como as expressões regulares. O til fumacento aponta para a expressão regular.

O operador de casamento retorna um número. O número é a posição na string onde a expressão regular foi encontrada. Então quando o operador retorna 6, ele está dizendo, “Antes da expressão, há seis caracteres na string.”

Se você precisa casar a string inteira, você pode usar a variável global especial $& se você está usando o operador de casamento. Ou, se estiver usando o método match, você pode conseguir a string inteira convertendo o objeto MatchData em uma string.

 # Usando =~ e $& juntos.
 irb> "O número é (909) 375-4434" =~ /[(]\d{3}[)]\s*\d{3}-\d{4}/
   => 11
 irb> $&
   => "(909) 375-4434"

 # Usando o objeto MatchData.
 irb> telefone = /[(]\d{3}[)]\s*\d{3}-\d{4}/.match("O número é (909) 375-4434")     
   => #<MatchData:0xb7d51680>
 irb> telefone.to_s
   => "(909) 375-4434"

A maioria dos Rubistas prefere a segunda alternativa, uma vez que usa um objeto dentro de uma variável local em vez de uma variável global. Variáveis globais são meio questionáveis, uma vez que podem ser facilmente sobrescritas. Se você rodar duas expressões regulares na seqüência, a variável global será sobrescrita na segunda vez. Mas com variáveis locais você pode manter as duas ocorrências desde que as variáveis tenham nomes diferentes.

Além de encontrar ocorrências, outro uso comum de expressões regulares é fazer encontre-e-substitua de dentro do Ruby. Você pode buscar pela palavra “mala” e substitui-la pela palavra “banjo.” Claro, você pode fazer isso com strings ou expressões regulares.

 irb> musica = "Eu furtei sua mala / E roubei o malabarista"
 irb> musica.gsub 'mala', 'viola'
   => "Eu furtei sua viola / E roubei o violabarista"

 irb> musica.gsub /\bmala\b/, 'viola'
   => "Eu furtei sua viola / E roubei o malabarista"

O método gsub significa “substituição global.” Note como no primeiro exemplo ele substituiu a palavra “mala” e as quatro primeiras letras de “malabarista.” Strings também têm um método simples sub que vai substituir apenas uma vez.

E assim este capítulo acaba, com Blix e os Raposos voando no sólido rosa expelido por um cervo muito reservado em algum lugar naquelas pastagens.

6. Só Parando Para Lhe Assegurar Que o Porco-espinho Não Se Moveu

O porco-espinho e sua pipa de novo.

Estou Fora >

Um dia, há algum tempo atrás, quando conheci o Bigelow (o cachorro que fugiu com os balões), eu voltei para o meu apartamento levando uns jogos de tabuleiro que havia comprado em uma venda de garagem. E a Quil estava na minha varanda. O que me surpreendeu, pois ela estava em San Antonio há três meses. Ela estava dormindo num saco de dormir na minha varanda.

Não tinha grana para a escola de artes, então ficou na minha casa por uns cinco meses.

Eu achei essa bicama usada para o nosso cantinho. À noite, nós nos sentávamos em nossas camas para ler um para o outro estórias de nossas agendas. Eu estava escrevendo um livro sobre uma criança que era um detetive e tentava descobrir quem matou essa outra criança do time de tênis e todos esses animais acabavam ajudando ela a desvendar o caso. Ela escrevia um livro sobre um garoto que coloca um anúncio nos classificados para que outras crianças entrem no seu culto fictício e eles terminam por construir um foguete. Mas durante a maioria do livro dela essas crianças estão perdidas na mata, totalmente sem rumo, o que eu me enchi de escutar a cada noite.

É, toda noite era poesia ou estórias ou idéias para pregar peças nos vizinhos. Nosso vizinho Justin era um grande fã do jogo de tabuleiro Warhammer. Ele tinha todas essas espadas e túnicas de verdade. Decidimos fazer armaduras de papel alumínio e atacar o apartamento dele. Começamos a pilhar o apartamento e ele adorou. Daí ele também fez sua armadura de papel alumínio e nós fomos a um glamuroso estúdio profissional e tiramos uma foto em grupo de qualidade.

Não estou dizendo que minha vida é melhor que a sua. Eu simplesmente sinto falta da minha irmã. As coisas agora não são mais como antigamente. Estamos separados ou algo do tipo.

Não sei. Estou confuso. Isto é crescer? Assistir a todas suas penas se soltarem? E mesmo sabendo que algumas dessas penas eram as melhores coisas que você possuía?

Eu acho difícil dizer quem acabou com tudo. Quem parou de amar quem? Eu parei de me importar? Talvez eu só a visse em duas dimensões e não fazia questão de olhar os outros ângulos. Eu só via planos. Então ela deslizou no eixo z enquanto eu não olhava e não fiz o dever de casa para traçar as coordenadas. Um tronco em uma árvore geométrica e eu insistindo em círculos.

Blix estava certo. Eu estou em ótima forma para escrever este livro. Adeus até que eu possa cair fora daqui.

Virar a página.