<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gustavo Dutra &#187; how-to</title>
	<atom:link href="http://gustavodutra.com/tag/how-to/feed/" rel="self" type="application/rss+xml" />
	<link>http://gustavodutra.com</link>
	<description>Um pouco de tudo, nada de pouco</description>
	<lastBuildDate>Thu, 29 Jul 2010 22:57:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Como fazer testes unitários em Models no CakePHP</title>
		<link>http://gustavodutra.com/post/412/como-fazer-testes-unitarios-em-models-no-cakephp/</link>
		<comments>http://gustavodutra.com/post/412/como-fazer-testes-unitarios-em-models-no-cakephp/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 22:51:54 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Unit Test]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[simpletest]]></category>
		<category><![CDATA[testes unitários]]></category>

		<guid isPermaLink="false">http://gustavodutra.com/?p=412</guid>
		<description><![CDATA[Olá! Dando continuidade ao post anterior Introdução a testes unitários no CakePHP e SimpleTest, este post tenta explicar como testar models.
A camada de modelo (model) geralmente é conhecida pela sua capacidade de abstrair as fontes dos dados, tornando o sistema independente de banco de dados, isto é, independente se é utilizado MySQL, Postgres ou até [...]]]></description>
			<content:encoded><![CDATA[<p>Olá! Dando continuidade ao post anterior <a href="http://gustavodutra.com/post/377/introducao-a-testes-unitarios-com-cakephp-e-simpletest/">Introdução a testes unitários no <em>CakePHP</em> e SimpleTest</a>, este post tenta explicar como testar models.</p>
<p>A camada de modelo (<em>model</em>) geralmente é conhecida pela sua capacidade de abstrair as fontes dos dados, tornando o sistema independente de banco de dados, isto é, independente se é utilizado MySQL, Postgres ou até mesmo arquivos CSV ou XML.</p>
<p>Pelo fato desta camada ser responsável pela manutenção dos dados do sistema, é de extrema importância testá-la. Os testes unitários devem garantir que esta esteja funcionando de acordo, para evitar incosistências.</p>
<p>Vamos criar os testes unitários desde o início, desde a criação das tabelas do banco de dados, passando pelos testes e a criação do model em si.</p>
<p><span id="more-412"></span></p>
<p>Vamos criar no banco de dados, que já suponho estar configurado no <em>CakePHP</em>, a tabela com a qual vamos trabalhar. Vamos criar um Model simples para produtos.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`products`</span> <span style="color: #66cc66;">&#40;</span>
   <span style="color: #ff0000;">`id`</span> INT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
   <span style="color: #ff0000;">`name`</span> VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
   <span style="color: #ff0000;">`description`</span> TEXT<span style="color: #66cc66;">,</span>
   <span style="color: #ff0000;">`price`</span> DOUBLE<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
   <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
comment <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Produtos'</span>
engine <span style="color: #66cc66;">=</span> InnoDB</pre></div></div>

<p>Tendo esta tabela no banco, podemos utilizar o próprio <em>CakePHP</em> para gerar automaticamente o fixture e o model. Para isto vamos executar o seguinte:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> meu_projeto<span style="color: #000000; font-weight: bold;">/</span>app
..<span style="color: #000000; font-weight: bold;">/</span>cake<span style="color: #000000; font-weight: bold;">/</span>console<span style="color: #000000; font-weight: bold;">/</span>cake bake model Product</pre></div></div>

<p>Interagindo com o <em>Shell</em> do cake, você pode criar seu model de forma simples e prática. Observe que ele criou 2 arquivos:</p>
<p><strong>app/tests/fixtures/product_fixture.php<br />
app/tests/cases/models/product.test.php</strong></p>
<p>Em app/tests/fixtures/product_fixture.php vamos definir nossos dados de teste, os dados que utilizaremos nos testes. Para isto, basta ajustar a propriedade $records:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$fields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'type'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'integer'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'null'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'length'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">15</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'key'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'primary'</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'type'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'string'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'null'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'length'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">200</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'type'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'text'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'null'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">NULL</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'price'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'type'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'float'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'null'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'length'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'10,2'</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'indexes'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	     <span style="color: #0000ff;">'PRIMARY'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'column'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'unique'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'tableParameters'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'charset'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'utf8'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'collate'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'utf8_general_ci'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'engine'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'InnoDB'</span>
      <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$records</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Nome do Produto'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Descrição longa'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'price'</span> <span style="color: #339933;">=&gt;</span> <span style="color:#800080;">15.23</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Nome do Segundo Produto'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Descrição super longa'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'price'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">12</span>
      <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Pronto, nosso fixture se encontra com a estrutura da tabela na propriedade $fields e os dados na propriedade $records.</p>
<p>Em <strong>app/tests/cases/models/product.test.php</strong> ficarão nossos testes. O <em>CakePHP</em> já escreve algumas coisas no arquivo:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$fixtures</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app.product'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>É essencial que todos os models relacionados devam ter seus fixtures adicionados a esta propriedade, pois senão ele não é capaz de criar as tabelas com os dados de teste.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> startTest<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span> <span style="color: #339933;">=</span> ClassRegistry<span style="color: #339933;">::</span><span style="color: #004000;">init</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Product'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Este método é executado sempre antes de cada teste (de ser executado o método que inicia com test). É interessante ter o objeto sempre &#8220;reiniciado&#8221; ao se fazer cada teste, pois senão um teste pode influenciar no valor do outro. Por exemplo, se o campo name tivesse um índice unique, poderia ter erro caso dois métodos de teste tivessem o mesmo valor sendo inserido, sendo que não era isto que estava sendo testado.</p>
<p>Para ter certeza que o objeto está sendo reinicializado, eu sugiro adicionar (somente necessário nos testes de 1.2.X):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> endTest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   ClassRegistry<span style="color: #339933;">::</span><span style="color: #990000;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Assim temos mais garantia de que tudo vai funcionar como o esperado.</p>
<p>O teste que o <em>CakePHP</em> 1.2.X insere automaticamente não deixa de ser importante, porém, na versão 1.3.X do <em>CakePHP</em> este teste não é mais inserido automaticamente.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testIsA<span style="color: #339933;">...</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">asssertIsA</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Product'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Quando o <em>ClassRegistry::init()</em> não acha o arquivo com o model sendo inicializado, porém consegue encontrar uma tabela que satisfaça o nome deste model, o <em>CakePHP</em> cria automaticamente um model com a classe <strong>GenericModel</strong>. Assim, será possível saber se o <em>CakePHP</em> está encontrando o model na estrutura de diretórios.</p>
<p>Bom, a primeira coisa que quero testar neste model, é garantir que não será possível a inserção de dados vazios. Os campos são obrigatórios e devem ser preenchidos com valores não vazios.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testNoPassedData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertFalse</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$error_fields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validationErrors</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #666666; font-style: italic;">// Verifica se o campo deu erro na validação</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$error_fields</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'description'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$error_fields</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'price'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$error_fields</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testEmptyData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'price'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span>
   <span style="color: #009900;">&#41;</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertFalse</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$error_fields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validationErrors</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #666666; font-style: italic;">// Verifica se o campo deu erro na validação</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$error_fields</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'description'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$error_fields</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'price'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$error_fields</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Bom, o nome e a descrição podem conter o que quiser, desde que contenham alguma coisa. Então, a princípio não há necessidade de mais testes. Mas e o preço do produto?</p>
<p>Bom, vamos pensar no preço: um preço é um valor numérico acima de 0. Então podemos por os seguintes testes:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testValidPriceFormat<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$valid_prices</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> <span style="color:#800080;">5.04</span><span style="color: #339933;">,</span> <span style="color:#800080;">124.3</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">12000</span><span style="color: #339933;">,</span> <span style="color:#800080;">0.01</span><span style="color: #339933;">,</span> <span style="color:#800080;">1.0000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'nome válido'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'descrição válida'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'price'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span> <span style="color: #666666; font-style: italic;">// será substituido</span>
   <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$valid_prices</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$counter</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$price</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'price'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$price</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testInvalidPriceFormat<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$invalid_prices</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">14</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'zero'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'1,00'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'nome válido'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'descrição válida'</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'price'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">null</span> <span style="color: #666666; font-style: italic;">// será substituido</span>
   <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$invalid_prices</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$price</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'price'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$price</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertFalse</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$error_fields</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Product</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validationErrors</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// verifica se está no array de erros</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertTrue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'price'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$error_fields</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Vejam que não vale a pena misturar as coisas: quando eu testo valores válidos ou inválidos de preço, somente o preço eu modifico. O restante das informações permancem imutáveis e devem ser válidas. O que queremos testar agora é a validação do preço e não de outras partes.</p>
<p>Uma outra coisa importante é considerar strings e valores com vírgulas para estes casos, são potenciais problemas! Aqui vai uma dica: sempre que trabalhar com campos inteiros, verifique o comportamento do sistema com valores 0 e negativos também!</p>
<p>Bom, temos nossos testes. Precisamos fazer eles passarem. Para isto, vamos adicionar o array de validação ao model.</p>
<p>No arquivo <strong>app/tests/cases/model/product.test.php</strong> vamos por o seguinte:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$validate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
   <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'rule'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'/\S/'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'message'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Deve ser especificado um nome para o produto'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span>
      <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #0000ff;">'description'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'rule'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'/\S/'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'message'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Deve ser especificado uma descrição para o produto'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span>
      <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
   <span style="color: #0000ff;">'price'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'valid'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'rule'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comparison'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&gt;'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'message'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'O preço deve ser maior que zero'</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'format'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'rule'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'numeric'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'message'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'O preço deve ser um valor numérico válido'</span>
      <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
         <span style="color: #0000ff;">'rule'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'/\S/'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'message'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Deve ser especificado um preço para o produto'</span><span style="color: #339933;">,</span>
         <span style="color: #0000ff;">'required'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span>
      <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Bom, agora é só rodar os testes e ver a barra verde. Simples, huh?</p>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/412/como-fazer-testes-unitarios-em-models-no-cakephp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lookahead, Lookbehind e Condicionais em Expressões Regulares</title>
		<link>http://gustavodutra.com/post/348/lookahead-lookbehind-e-condicionais-em-expressoes-regulares/</link>
		<comments>http://gustavodutra.com/post/348/lookahead-lookbehind-e-condicionais-em-expressoes-regulares/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 22:28:29 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Nerd]]></category>
		<category><![CDATA[Regex]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[lookahead]]></category>
		<category><![CDATA[lookbehind]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[re]]></category>
		<category><![CDATA[regular expression]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://gustavodutra.com/?p=348</guid>
		<description><![CDATA[Depois de muito tempo sem postar, me lembrei de algo bem interessante! Vocês podem mandar mensagens na página de contato dando sugestões de temas sobre Vim, Expressões regulares ou outra coisa que vocês gostariam de ver no blog ;p.
Expressões Regulares
Expressão regular é uma ferramenta muito forte para o tratamento de texto. É muito utilizado para [...]]]></description>
			<content:encoded><![CDATA[<p>Depois de muito tempo sem postar, me lembrei de algo bem interessante! Vocês podem mandar mensagens na página de contato dando sugestões de temas sobre <strong>Vim</strong>, <strong>Expressões regulares</strong> ou outra coisa que vocês gostariam de ver no blog ;p.</p>
<h2>Expressões Regulares</h2>
<p><strong>Expressão regular</strong> é uma ferramenta muito forte para o tratamento de texto. É muito utilizado para substituições ou para verificar integridade dos dados, pois, através da <strong>expressão regular</strong>, vulga <strong>regex</strong> ou <strong>re</strong>, pode-se casar padrões de texto. Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">/^[a-zA-Z0-9]+$/
Para somente caracteres alfanuméricos.
&nbsp;
/^(\d{3}\.){2}\d{3}-\d{2}$/
Validando formato de CPF.</pre></div></div>

<p>Esse tipo de regex é simples, valida praticamente só os caracteres que compõe uma dada string. Porém, as <em>Perl Compatible Regular Expressions</em> (Expressões Regulares Compatíveis com Perl), também conhecidas como <em>pcre</em>, permitem muito mais, inclusive utilizar condicionados (if&#8217;s), porém isso é para outro post! O que vamos falar agora é de <strong>Lookahead</strong> e <strong>Lookbehind</strong>.</p>
<p><span id="more-348"></span></p>
<h2>Lookahead</h2>
<p><strong>Lookahead</strong> é uma forma de casar strings que tenham ou não um determinado final. É utilizado (?⁼&#8230;) para o positivo, ou seja, que terminem com; e (?!&#8230;) para o negativo, ou seja, que não termina com.</p>
<p>Um exemplo simples, seria a busca, primeiramente, de Gustavo seguido por Dutra. Se existisse Gustavo ou Gustavo Outracoisa, ele não casaria. Ao contrário, o segundo exemplo somente casaria o Gustavo ou o Gustavo Outracoisa, porém não casaria o Gustavo Dutra:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">/Gustavo(?= Dutra)/
/Gustavo(?! Dutra)</pre></div></div>

<p>Vamos ver um exemplo mais funcional e complexo em <em>python</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\s</span>?([^;]+);'</span>, <span style="color: #483d8b;">'Vim Editor; GVim Editor; Firefox Browser; Emacs Editor; Thunderbird Email;'</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># output seria:</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Vim Editor'</span>, <span style="color: #483d8b;">'GVim Editor'</span>, <span style="color: #483d8b;">'Firefox Browser'</span>, <span style="color: #483d8b;">'Emacs Editor'</span>, <span style="color: #483d8b;">'Thunderbird Email'</span><span style="color: black;">&#93;</span></pre></div></div>

<p>Mas e se quisesse somente os editores da lista?</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\s</span>?([^;]+ Editor);'</span>, <span style="color: #483d8b;">'Vim Editor; GVim Editor; Firefox Browser; Emacs Editor; Thunderbird Email;'</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># output seria:</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Vim Editor'</span>, <span style="color: #483d8b;">'GVim Editor'</span>, <span style="color: #483d8b;">'Emacs Editor'</span><span style="color: black;">&#93;</span></pre></div></div>

<p>Mas e se eu quisesse todos MENOS os editores? É ai que entra o <strong>Lookahead</strong>, vamos pegar todos que não terminam com Editor.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\s</span>?([^;]+ (?!Editor))'</span>, <span style="color: #483d8b;">'Vim Editor; GVim Editor; Firefox Browser; Emacs Editor; Thunderbird Email;'</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># output seria:</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Firefox '</span>, <span style="color: #483d8b;">'Thunderbird '</span><span style="color: black;">&#93;</span></pre></div></div>

<p>Observem que o que casar com (?!Editor) não entra no resultado, para incluí-lo, seria necessário uma expressão regular um pouco mais complexa utilizando condicionais. Veremos isso depois!</p>
<h2>Lookbehind</h2>
<p><strong>Lookbehind</strong> faz o mesmo que o <strong>lookahead</strong>, porém, como o próprio nome diz, não procura depois, mas sim antes, da string dita. (?&lt;=&#8230;) para o positivo e (?&lt;!&#8230;) para o negativo.</p>
<p>Vamos pegar um RT de um tweet do <a rel="nofollow" href="http://twitter.com">twitter.com</a>. Como gosto de ser eclético, vou usar <em>perl</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;RT <span style="color: #000099; font-weight: bold;">\@</span>gustavotkg Testando ERs.&quot;</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">/(?&lt; =@)gustavotkg/</span>
<span style="color: #666666; font-style: italic;"># Output seria:</span>
<span style="color: #cc66cc;">1</span></pre></div></div>

<p>Essa expressão retorna 1 (ou seja, TRUE), caso exista algum gustavotkg precedido por uma @.</p>
<p>OBS: @ são escapadas porque representam variáveis do tipo array em perl.</p>
</pre>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Este é um RT <span style="color: #000099; font-weight: bold;">\@</span>gustavotkg Testando ERs.&quot;</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">/(?&lt; !RT )\@gustavotkg/</span>
<span style="color: #666666; font-style: italic;"># Output seria, vazio, pois o @gustavotkg é precedido por um RT</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;RT <span style="color: #000099; font-weight: bold;">\@</span>gustavotkg2 também estou testando ERs.&quot;</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">/(?&lt;!^RT \@gustavotkg\b)(.+)$/</span>
<span style="color: #666666; font-style: italic;"># Output seria:</span>
RT <span style="color: #0000ff;">@gustavotkg2</span> també<span style="color: #000066;">m</span> estou testando ERs<span style="color: #339933;">.</span></pre></div></div>

<p>O <em>\b</em> significa borda de palavra (espaço, ponto final, exclamação, final de linha, etc). Como 2 não é uma borda de palavra, pois a expressão regular diz o seguinte: <em>"Case com tudo que não começar com RT @gustavotkg seguido de uma borda de palavra"</em>.</p>
<h2>Condicionais</h2>
<p>Como se pode notar nos casos acima, os operadores de lookahead e lookbehind não colocam o valor casado junto ao resultado final. Para isso temos que verificar condicionalmente e adicionar manualmente o valor. A sintaxe é esta: <strong>(?(condicao)(caso verdadeiro)|(caso falso)).</strong></p>
<p>Parece complicado, mas é bem simples, vamos começar com algo fácil utilizando php:</p>
</pre>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/(?(?&lt; =@)\w+|\w{2})/&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;@testando&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$r</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$r</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;"># Output seria:
</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;testando&quot;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/(?(?&lt; =@)\w+|\w{2})/&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;testando&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$r</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$r</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;"># Output seria:
</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;te&quot;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Notem o condicional: Se começar (<strong>lookbehind</strong>) com @, então quero que case toda a palavra que segue o @, caso contrário, quero apenas os dois primeiros caracteres. Fácil? Vamos complicar!</p>
<p>Lembra do exemplo mais acima do <strong>lookahead</strong>? Vou refrescar a memória:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #dc143c;">re</span>.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\s</span>?([^;]+ (?!Editor))'</span>, <span style="color: #483d8b;">'Vim Editor; GVim Editor; Firefox Browser; Emacs Editor; Thunderbird Email;'</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># output seria:</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'Firefox '</span>, <span style="color: #483d8b;">'Thunderbird '</span><span style="color: black;">&#93;</span></pre></div></div>

<p>Notem que ela não adicionar a categoria do Firefox nem do Thunderbird, pois o (?!) como supracitado, não é colocado junto no resultado final. Para adicioná-los, podemos usar o condicional.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/(\w+ (?(?!Editor)\w+));/&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;Vim Editor; GVim Editor; Firefox Browser; Emacs Editor; Thunderbird Email;&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Output seria:</span>
<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span>
  <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span>
    string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">16</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;Firefox Browser;&quot;</span>
    <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span>
    string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">18</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;Thunderbird Email;&quot;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span>
  <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span>
    string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;Firefox Browser&quot;</span>
    <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span>
    string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">17</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;Thunderbird Email&quot;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Ou seja, no segundo índice do array, que na verdade é o indice 1, consta o resultado pego. Veja que utilizamos o seguinte método: Se \w+ não for seguido de 'Editor' então pega o \w+, senão ignora pois não é para casar. Assim, se for Editor, ele nunca irá casar.</p>
<p><strong>Dúvidas? Sugestões? Deixe um comentário!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/348/lookahead-lookbehind-e-condicionais-em-expressoes-regulares/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Usando Screen e Vim para Pair Programming remoto</title>
		<link>http://gustavodutra.com/post/276/usando-screen-e-vim-para-pair-programming-remoto/</link>
		<comments>http://gustavodutra.com/post/276/usando-screen-e-vim-para-pair-programming-remoto/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 22:09:59 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Engenharia de Software]]></category>
		<category><![CDATA[Nerd]]></category>
		<category><![CDATA[Software Livre]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[engenharia de software]]></category>
		<category><![CDATA[extreme programming]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[pair programming]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[skype]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://gustavodutra.com/?p=276</guid>
		<description><![CDATA[Bem, é notável o crescimento das metodologias ágeis de desenvolvimento de software. Uma das práticas que me agrada muito, é a programação em pares (pair programming). É bem perceptível, a um longo prazo, a diferença que faz essa prática. Navegando pela internet, como um marujo sem rumo, encontrei um post falando sobre Remote Pair Programming. [...]]]></description>
			<content:encoded><![CDATA[<p>Bem, é notável o crescimento das <strong>metodologias ágeis de desenvolvimento de software</strong>. Uma das práticas que me agrada muito, é a programação em pares (<em>pair programming</em>). É bem perceptível, a um longo prazo, a diferença que faz essa prática. Navegando pela internet, como um marujo sem rumo, encontrei um post falando sobre <em>Remote Pair Programming</em>. Parece meio estranho, porque o XP (<a rel="nofollow" href="http://www.extremeprogramming.org/">eXtreme Programming</a>) faz alusão a uma dupla programar em um único computador, com um único teclado e um único mouse.<br />
<span id="more-276"></span><br />
Então, vamos tentar simular este ambiente utilizando 4 ferramentas simples:</p>
<ul>
<li>screen</li>
<li>ssh</li>
<li>vim</li>
<li>skype</li>
</ul>
<p>Destas, só o <em>skype</em> não é <em>open-source</em>. Mas é interessante manter uma conversa verbal, pois conversas escritas podem desviar o foco da programação, que é bem mais rápida e precisa do que a escrita, que pode deixar brechas para má interpretações. A conversa verbal consegue interromper o programador ao mesmo tempo em que escreve, corrigindo-o ou questionando-o.</p>
<p>Conectados no skype, basta decidir em qual máquina será o desenvolvimento. Esta, por sua vez, terá que ter um servidor <strong>ssh</strong>. Ela será o <em>host</em> da programação. Será necessário, também, nesta máquina, ter instalado o <em>screen</em>, que é um programa que possibilita criar &#8217;sessões&#8217; no terminal.</p>
<h2>Host</h2>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #660033;">-S</span> PairProgramming</pre></div></div>

<p>Parece que nada mudou, mas você está numa sessão do <strong>screen</strong> chamada <em>PairProgramming</em>.</p>
<p>Precione CTRL+a e digite:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">:multiuser on</pre></div></div>

<p>Pressione CTRL+a novamente e digite:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">:acladd usuarioclient</pre></div></div>

<p>Tudo que você ver nesta sessão, será visto pelo outro usuário (<em>usuarioclient</em>) que se conectará nela.</p>
<p>Então, abra o <strong>vim</strong>, pois será necessário um edito de textos de verdade <img src='http://gustavodutra.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> , e se divirta:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">vim</span> <span style="color: #000000; font-weight: bold;">/</span>caminho<span style="color: #000000; font-weight: bold;">/</span>arquivo</pre></div></div>

<h2>Client</h2>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ssh</span> usuarioclient<span style="color: #000000; font-weight: bold;">@</span>host
<span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #660033;">-x</span> usuariohost<span style="color: #000000; font-weight: bold;">/</span>PairProgramming</pre></div></div>

<p>Pronto! Agora você está acessando a mesma seção! Tudo que o <em>usuáriohost</em> fizer, o <em>usuárioclient</em> enxergará e <strong>vice-versa</strong>.</p>
<p>Agora, basta descutir a tarefa via Skype e programar. As atualizações são em tempo real, ou seja, aparecem ao mesmo tempo que são escritos, digo&#8230; depende da conexão, mas não é um grande problema.</p>
<p>Caso seja necessário que o usuarioclient não possa modificar o código, apenas assitir e dar pitacos, o usuáriohost deve pressionar CTRL+A e digitar:</p>
<pre>:aclchg usuarioclient -w #</pre>
<p>Eu ainda vou programar assim, depois digo a experiência.</p>
<h2>Referências</h2>
<ul>
<li><a rel="nofollow" href="http://www.linux.com/archive/feature/56443">Linux.com</a></li>
<li><a rel="nofollow" href="http://haruska.com/2009/09/29/remote-pair-programming/">Jason Haruska</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/276/usando-screen-e-vim-para-pair-programming-remoto/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Criando apresentações Power Point pelo Vim</title>
		<link>http://gustavodutra.com/post/229/criando-apresentacoes-power-point-pelo-vim/</link>
		<comments>http://gustavodutra.com/post/229/criando-apresentacoes-power-point-pelo-vim/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 21:56:13 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Nerd]]></category>
		<category><![CDATA[Software Livre]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[aumentar produtivade]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[gvim]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[openoffice]]></category>
		<category><![CDATA[power point]]></category>
		<category><![CDATA[produtividade]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimrc]]></category>

		<guid isPermaLink="false">http://gustavodutra.com/?p=229</guid>
		<description><![CDATA[Essa semana eu precisei de uma apresentação Power Point. Abri o Impress, o editor de apresentações do OpenOffice. Comecei meu raciocínio sobre a apresentação. Quando me dei conta, estava colocando negrito e identando um parágrafo. Ao reler o parágrafo, havia 3 erros de gramática. Foi a gota d&#8217;água: Não consigo criar apresentações, pensei.
Quando eu vou [...]]]></description>
			<content:encoded><![CDATA[<p>Essa semana eu precisei de uma apresentação Power Point. Abri o Impress, o editor de apresentações do OpenOffice. Comecei meu raciocínio sobre a apresentação. Quando me dei conta, estava colocando negrito e identando um parágrafo. Ao reler o parágrafo, havia 3 erros de gramática. Foi a gota d&#8217;água: Não consigo criar apresentações, pensei.</p>
<p>Quando eu vou escrever em algum programa de qualquer suíte de escritório &#8211; openoffice, koffice, etc -, eu geralmente me preocupo mais com o negrito da palavra, com identação do parágrafo do que com o conteúdo em si. Isso é um pecado.</p>
<p>Meu primeiro instinto foi: vou escrever tudo no Vim, depois colo no Impress. Boa! Ok, mas e quanto às páginas?<br />
Vou ter que por página por página? Ainda sim eu teria mais trabalho. Eu teria que refazer as listas para que ficassem com as &#8220;bolinhas&#8221; à esquerda. E teria que modificar todos os títulos para negrito?</p>
<p><span id="more-229"></span></p>
<p>Fui pro google e achei um plugin que já conhecia no resultado: <a rel="nofollow" href="http://www.vimoutliner.org/">VimOutliner</a>. Ele dita uma sintaxe muito intuitiva para hierarquisar (existe esse verbo?) o conteúdo. Algo assim:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Título do documento
&nbsp;
Tópico Nível 1
	Tópico Nível 2
	: Parágrafo com alinhamento justify
	; Parágrafo fica do jeito que foi escrito
	- Item de lista
	+ Item de lista numérica</pre></div></div>

<p>O plugin vem com documentação e um shell script que instala automaticamente o plugin. O site tem toda documentação, é bem simples.</p>
<p>Em <a rel="nofollow" href="http://perens.com/FreeSoftware/Outline/">http://perens.com/FreeSoftware/Outline/</a> é possível encontrar vários scripts que convertem o documento para outros formatos. Um deles é o vo2odp.rb, um script em ruby para converter arquivos para o OpenOffice Presentation.</p>
<p>Pra fazê-lo rodar, eu sofri um pouquinho. Tive que instalar o ruby (obviamente) e o rubygems. Depois de instalado:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ gem install builder
$ gem install rubyzip</pre></div></div>

<p>Também alterei o script, segue o patch das modificações:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">29,30c29,30
&lt; require_gem 'builder'
&lt; require_gem 'rubyzip'
---
&gt; require 'builder'
&gt; require 'zip/zip'</pre></div></div>

<p>Copie o trecho acima em um arquivo, por exemplo: /tmp/patch_vo2odp, depois execute</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ patch /caminho/para/vo2odp.rb &lt; /tmp/patch_vo2odp</pre></div></div>

<p>Pronto, agora só escrever sua apresentação. Lembre-se que o plugin tem uma extenção própria, a .otl. Sempre que um arquivo for aberto com esta extenção, o Vim irá carregar o syntax highlight apropriado e algumas outras opções para melhor escrever sua apresentação.</p>
<p>Concluída a apresentação, você pode usar</p>
</pre>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ ruby /caminho/para/vo2odp.rb apresentacao.otl apresentacao.odp</pre></div></div>

<p>Abra com o OpenOffice e salve como .ppt. Pronto! Você acabou de fazer sua apresentação no PowerPoint pelo Vim.</p>
<h3>Observações importantes</h3>
<ul>
<li>O script não quebra as páginas dos slides automaticamente. É separado por capítulos de nível 1. Então, não escreva coisas muito longas dentro de um nível. Lembre-se que é uma apresentação e não um documento de texto.</li>
<li>Quando aberto no OpenOffice, use o negrito, sublinhado, coloque imagens, etc. Crie seu layout e não pense nisso durante a criação do conteúdo. Escreva antes e formate depois</li>
</ul>
<p>E isso ai! Gostou? Não? Comente! Dê dicas e sugestões!</p>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/229/criando-apresentacoes-power-point-pelo-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dicas de como aumentar a produtividade usando autocmd no vim</title>
		<link>http://gustavodutra.com/post/153/dicas-de-como-aumentar-a-produtividade-usando-autocmd-no-vim/</link>
		<comments>http://gustavodutra.com/post/153/dicas-de-como-aumentar-a-produtividade-usando-autocmd-no-vim/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 02:06:11 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Nerd]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[abreviaturas]]></category>
		<category><![CDATA[aumentar produtivade]]></category>
		<category><![CDATA[autocmd]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[gvimrc]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[poo]]></category>
		<category><![CDATA[porque]]></category>
		<category><![CDATA[produtividade]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[reuso]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimrc]]></category>

		<guid isPermaLink="false">http://gustavodutra.com/?p=153</guid>
		<description><![CDATA[Quantas vezes você faz um arquivo que é exatamente igual à um outro arquivo por dia? Quantas vezes você abre um arquivo só para copiar um trecho de código que é utilizado em vários arquivos? Quantas vezes você se vê fazendo a mesma coisa que fez em outro lugar?
E aquela palavra que você sempre escreve [...]]]></description>
			<content:encoded><![CDATA[<p>Quantas vezes você faz um arquivo que é exatamente igual à um outro arquivo por dia? Quantas vezes você abre um arquivo só para copiar um trecho de código que é utilizado em vários arquivos? Quantas vezes você se vê fazendo a mesma coisa que fez em outro lugar?</p>
<p>E aquela palavra que você sempre escreve errada? Aquela função que você sempre esquece o nome?</p>
<p>Conheça algumas dicas para aumentar a produtividade e diminuir o trabalho dessas coisas rotineiras.</p>
<p><span id="more-153"></span></p>
<h2>Lista de Abreviaturas</h2>
<p>Sabe aquelas palavras que a gente insiste em escrever errado? Principalmente quem trabalha com e-mails, códigos e comentários em outras línguas tem dificuldades com certas palavras. Por exemplo,</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">vc -&gt; você
q -&gt; que
pq -&gt; porque
nao -&gt; não</pre></div></div>

<p>Agora a pergunta que não quer calar: Porque não usarmos algo para evitar esse tipo de coisa? Às vezes nem notamos os erros, mas eles estão lá. Mantenha uma lista de abreviaturas no Vim. Cuide dela, adicione novas abreviaturas assim que vierem à sua cabeça. A sintaxe é simples, basta adicionar no seu .vimrc:</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">&quot;&quot; abbr ERRADO CORRETO, por exemplo:
abbr pq porque
abbr vc você</pre></div></div>

<p>O Vim ainda possibilita que você crie sintaxes diferentes para arquivos diferentes. Então, seus arquivos <strong>.txt</strong> podem ter abreviaturas diferentes das de <strong>.py</strong>. Ou seja, se o nome daquela função python é muito <strong>longa</strong> ou você insiste em escrevê-la errada, ela merece uma abreviatura, no formato descrito acima (abbr ERRADO CORRETO).</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">$ mkdir -p ~/.vim/abreviaturas/
$ vim ~/.vim/abreviaturas/txt.vim</pre></div></div>

<p>Adicione ao txt.vim as abreviaturas utilizadas para arquivos texto. Mesmo que poucas, coloque algumas. Um pouco de disciplina fará com que sua produtividade aumente. Tenha certeza.</p>
<p>Ao seu .vimrc, basta acrescentar:</p>

<div class="wp_syntax"><div class="code"><pre class="vim" style="font-family:monospace;"><span style="color: #668080;">autocmd</span> BufNewFile,BufRead <span style="color: #000000;">*</span> source <span style="color: #000000;">$</span>HOME<span style="color: #000000;">/.</span>vim<span style="color: #000000;">/</span>abreviaturas<span style="color: #000000;">/</span>para_qualquer_linguagem<span style="color: #000000;">.</span>vim
<span style="color: #668080;">autocmd</span> BufNewFile,BufRead <span style="color: #000000;">*.</span>txt source <span style="color: #000000;">$</span>HOME<span style="color: #000000;">/.</span>vim<span style="color: #000000;">/</span>abreviaturas<span style="color: #000000;">/</span>txt<span style="color: #000000;">.</span>vim
<span style="color: #668080;">autocmd</span> BufNewFile,BufRead <span style="color: #000000;">*.</span>py source <span style="color: #000000;">$</span>HOME<span style="color: #000000;">/.</span>vim<span style="color: #000000;">/</span>abreviaturas<span style="color: #000000;">/</span>python<span style="color: #000000;">.</span>vim</pre></div></div>

<p>O <em>autocmd</em> funciona mais ou menos igual a uma <em>trigger</em>. É um sistema de eventos, basicamente. Ou seja, ao abrir um arquivo novo (BufNewFile) ou um arquivo já existente (BufRead), se o nome do arquivo casar com a expressão (no caso, *, *.txt ou *.py) irá executar o código a seguir.</p>
<p>Vou falar mais sobre o autocmd em outro post, tem muitoooo pano pra manga, hehehe.</p>
<h2>Templates de Arquivos</h2>
<p>Quando se fala em programação é meio que como na arte. Não só porque programar é uma arte, mas porque nada se cria, tudo se copia. Tudo bem que, hoje em dia, com técnicas de encapsulamento, oop, etc, fica mais difícil. Mas sempre há coisas em comum entre os arquivos. Vamos começar com algo simples.</p>
<p>Template básico para javascript, onde será utilizado jquery.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">onready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">// code here</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Simples, mas não é um saco ter que escrever isso sempre que abre um arquivo novo? Tome isso como regra: Faça uma, porém apenas uma vez. Não seria mais fácil abrir o arquivo e tcha-ram! Lá está o código que, em 90% dos casos, você irá utilizar?</p>
<p>Esse foi pequeninho, mas imagine um arquivo html. A trabalheira que é copiar todo o caçalho. E se você segue um padrão, pode usar inclusive o css junto. Observe:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt; !DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;pt&quot; lang=&quot;pt-br&quot; dir=&quot;ltr&quot;&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
		&lt;meta http-equiv=&quot;Content-Style-Type&quot; content=&quot;text/css&quot; /&gt;
		&lt;meta name=&quot;keywords&quot; content=&quot;aqui,vai,as,keywords&quot; /&gt;
		&lt;link rel=&quot;stylesheet&quot; href=&quot;/style.css&quot; /&gt;
		&lt;link rel=&quot;shortcut icon&quot; href=&quot;/favicon.ico&quot; /&gt;
        &lt;/head&gt;
        &lt;body&gt;
        &lt;div id=&quot;wrapper&quot;&gt;
                &lt;div id=&quot;head&quot;&gt;&lt;/div&gt;
                &lt;div id=&quot;content&quot;&gt;&lt;/div&gt;
                &lt;div id=&quot;footer&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
&lt;/body&gt;&lt;/html&gt;</pre></td></tr></table></div>

<p>E o css:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="css" style="font-family:monospace;">html <span style="color: #00AA00;">*</span> <span style="color: #00AA00;">&#123;</span>
<span style="color: #00AA00;">&#125;</span>
body <span style="color: #00AA00;">&#123;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#wrapper</span> <span style="color: #00AA00;">&#123;</span>
<span style="color: #00AA00;">&#125;</span>
        <span style="color: #cc00cc;">#wrapper</span> <span style="color: #cc00cc;">#head</span> <span style="color: #00AA00;">&#123;</span>
        <span style="color: #00AA00;">&#125;</span>
        <span style="color: #cc00cc;">#wrapper</span> <span style="color: #cc00cc;">#content</span> <span style="color: #00AA00;">&#123;</span>
        <span style="color: #00AA00;">&#125;</span>
        <span style="color: #cc00cc;">#wrapper</span> <span style="color: #cc00cc;">#footer</span> <span style="color: #00AA00;">&#123;</span>
        <span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>Imagine um designers, aqueles que fazem o psd e depois passam pra xhtml, tendo que copiar isso vezes e vezes para todos os arquivos que ele faz. Faça apenas uma vez e siga o padrão!</p>
<p>Usuários de django, ao criar um model, precisam escrever sempre os imports ? Se são utilizados sempre, porque não criar um template?</p>
<p>Agora você me pergunta, como carregar o template automagicamente no Vim ? Fácil! Utilizando nosso autocmd =). Do mesmo modo que fizemos com as abreviaturas, vamos criar os diretórios:</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">$ mkdir -p ~/.vim/templates/</pre></div></div>

<p>Criei lá os arquivos com os templates que você acha útil.</p>

<div class="wp_syntax"><div class="code"><pre class="vim" style="font-family:monospace;"><span style="color: #668080;">autocmd</span> BufNewFile <span style="color: #000000;">*.</span>html 0r <span style="color: #000000;">~/.</span>vim<span style="color: #000000;">/</span>templates<span style="color: #000000;">/</span>html<span style="color: #000000;">.</span>tpl
<span style="color: #668080;">autocmd</span> BufNewFile style<span style="color: #000000;">.</span>css 0r <span style="color: #000000;">~/.</span>vim<span style="color: #000000;">/</span>templates<span style="color: #000000;">/</span>cssstyle<span style="color: #000000;">.</span>tpl
<span style="color: #668080;">autocmd</span> BufNewFile jquery<span style="color: #000000;">.*.</span>js 0r <span style="color: #000000;">~/.</span>vim<span style="color: #000000;">/</span>templates<span style="color: #000000;">/</span>jqueryjs<span style="color: #000000;">.</span>tpl</pre></div></div>

<p>Agora, abra seu Vim e sinta a magia:</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">vim index.html style.css jquery.initscript.js</pre></div></div>

<h2>Executando comandos externos</h2>
<h3>g(un)zip</h3>
<p>O manual do Vim tem um exemplo bem interessante, para abrir arquivos <strong>gzipados</strong>, editá-los, como se nada tivesse acontecido e salvá-lo no formato <strong>gzip</strong> de novo. Apesar de que aqui, não precisou acrescentar os códigos abaixo, ele já fez automático. Basta adicionar o .vimrc</p>

<div class="wp_syntax"><div class="code"><pre class="vim" style="font-family:monospace;">augroup gzip
  <span style="color: #668080;">autocmd</span><span style="color: #000000;">!</span>
  <span style="color: #668080;">autocmd</span> BufReadPre,FileReadPre	<span style="color: #000000;">*.</span>gz set bin
  <span style="color: #668080;">autocmd</span> BufReadPost,FileReadPost	<span style="color: #000000;">*.</span>gz <span style="color: #C5A22D;">'[,'</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">!</span>gunzip
  <span style="color: #668080;">autocmd</span> BufReadPost,FileReadPost	<span style="color: #000000;">*.</span>gz set nobin
  <span style="color: #668080;">autocmd</span> BufReadPost,FileReadPost	<span style="color: #000000;">*.</span>gz <span style="color: #804040;">execute</span> <span style="color: #C5A22D;">&quot;:doautocmd BufReadPost &quot;</span> <span style="color: #000000;">.</span> <span style="color: #25BB4D;">expand</span><span style="color: #000000;">&#40;</span><span style="color: #C5A22D;">&quot;%:r&quot;</span><span style="color: #000000;">&#41;</span>
  <span style="color: #668080;">autocmd</span> BufWritePost,FileWritePost	<span style="color: #000000;">*.</span>gz <span style="color: #000000;">!</span>mv <span style="color: #000000;">&lt;</span>afile<span style="color: #000000;">&gt;</span> <span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;&lt;</span>afile<span style="color: #000000;">&gt;:</span>r
  <span style="color: #668080;">autocmd</span> BufWritePost,FileWritePost	<span style="color: #000000;">*.</span>gz <span style="color: #000000;">!</span>gzip <span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;&lt;</span>afile<span style="color: #000000;">&gt;:</span>r
&nbsp;
  <span style="color: #668080;">autocmd</span> FileAppendPre		<span style="color: #000000;">*.</span>gz <span style="color: #000000;">!</span>gunzip <span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;&lt;</span>afile<span style="color: #000000;">&gt;</span>
  <span style="color: #668080;">autocmd</span> FileAppendPre		<span style="color: #000000;">*.</span>gz <span style="color: #000000;">!</span>mv <span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;&lt;</span>afile<span style="color: #000000;">&gt;:</span>r <span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;&lt;</span>afile<span style="color: #000000;">&gt;</span>
  <span style="color: #668080;">autocmd</span> FileAppendPost		<span style="color: #000000;">*.</span>gz <span style="color: #000000;">!</span>mv <span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;&lt;</span>afile<span style="color: #000000;">&gt;</span> <span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;&lt;</span>afile<span style="color: #000000;">&gt;:</span>r
  <span style="color: #668080;">autocmd</span> FileAppendPost		<span style="color: #000000;">*.</span>gz <span style="color: #000000;">!</span>gzip <span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;&lt;</span>afile<span style="color: #000000;">&gt;:</span>r
augroup END
<span style="color: #000000;">&lt;/</span>afile<span style="color: #000000;">&gt;</span></pre></div></div>

<h3>Verificação por erro</h3>
<p>Já deve ter acontecido com você: você salva o arquivo e quando vai testar, faltou um ponto e vírgula, ou escrever o nome de uma função errada, ou algo similar&#8230; um erro bobo, mas que não deixou seu código ser executado e exige reparo.</p>
<p>Para ajudar contra esse trabalho desnecessário (teste + correção + teste), que pode se repetir inúmeras vezes, você pode usar o autocmd para alertá-lo, utilizando ferramentas externas. Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="vim" style="font-family:monospace;"><span style="color: #668080;">autocmd</span> BufWritePost <span style="color: #000000;">*.</span>pl <span style="color: #000000;">!</span>perl <span style="color: #000000;">-</span>c <span style="color: #000000;">%</span>
<span style="color: #668080;">autocmd</span> BufWritePost <span style="color: #000000;">*.</span>php <span style="color: #000000;">!</span>php <span style="color: #000000;">-</span>l <span style="color: #000000;">%</span>
<span style="color: #668080;">autocmd</span> BufWritePost <span style="color: #000000;">*.</span>java <span style="color: #000000;">!</span>javac <span style="color: #000000;">-</span>Xlint <span style="color: #000000;">%</span></pre></div></div>

<h2>Use a criativdade</h2>
<p>Utilize sua criatividade e seja mais produtivo na SUA rotina. Deixe as coisas serem automatizadas. Para mais eventos do autocmd, :help autocmd. Tem uma lista bem extensa. Leia a documentação e seja feliz =). Crítias, sugestões e CASES são bem vindos nos comentários =)</p>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/153/dicas-de-como-aumentar-a-produtividade-usando-autocmd-no-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como fazer um mini servidor HTTP em Python</title>
		<link>http://gustavodutra.com/post/141/como-fazer-um-mini-servidor-http-em-python/</link>
		<comments>http://gustavodutra.com/post/141/como-fazer-um-mini-servidor-http-em-python/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 00:06:58 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Nerd]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tchelinux]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://gustavodutra.com/?p=141</guid>
		<description><![CDATA[Olá! Estava lendo minhas mail lists matinais, mais especificadamente a mail list do TcheLinux (evento que, aliás, irá ocorrer em Gravataí sábado que vem, dia 28/03), quando me deparo com um post de Leonardo Menezes Vaz falando de um mini servidor http em python. Achei muito interessante e resolvi postar aqui.

Ingredientes

Lazanha
Python instalado
3 minutos de lazer


Modo [...]]]></description>
			<content:encoded><![CDATA[<p>Olá! Estava lendo minhas mail lists matinais, mais especificadamente a mail list do TcheLinux (evento que, aliás, irá ocorrer em Gravataí sábado que vem, dia 28/03), quando me deparo com um post de Leonardo Menezes Vaz falando de um mini servidor http em python. Achei muito interessante e resolvi postar aqui.</p>
<p><span id="more-141"></span></p>
<h2>Ingredientes</h2>
<ul>
<li>Lazanha</li>
<li>Python instalado</li>
<li>3 minutos de lazer</li>
</ul>
<ul>
<h2>Modo de preparo</h2>
<p>Pegue os 3 minutos de lazer e utlize para criar um diretório:</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">$ mkdir ~/htmldocs
$ cd ~/htmldocs
$ echo &quot;&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;Meus posts no blog&lt;/body&gt;&lt;/html&gt;&quot; &gt; index.html
$ python -m SimpleHTTPServer
$ firefox http://localhost:8000</pre></div></div>

<p>Pronto! Agora você pode gerenciar documentações, fazer preview de posts no seu blog, fazer testes de javascript/css sem precisar instalar o apache ou criar um VirtualHost!</p>
<p>Eu achei útil! E você?</ul>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/141/como-fazer-um-mini-servidor-http-em-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Como usar mod_rewrite de verdade</title>
		<link>http://gustavodutra.com/post/120/como-usar-mod_rewrite-de-verdade/</link>
		<comments>http://gustavodutra.com/post/120/como-usar-mod_rewrite-de-verdade/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 13:38:31 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Nerd]]></category>
		<category><![CDATA[Software Livre]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[clean url]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[exemplo]]></category>
		<category><![CDATA[flexibilidade]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://gustavodutra.com/?p=120</guid>
		<description><![CDATA[Rá! Hoje quero falar sobre mod_rewrite. Um módulo para o apache que permite reescrever URL&#8217;s. Ele é muito útil em vários sentidos: aumenta a o page rank em buscadores, torna URL&#8217;s limpas e inteligíveis, fazendo com que o usuário consiga lembrá-las muito mais rápida e facilmente.
Porém, como todos os outros artefatos que estão por aí, [...]]]></description>
			<content:encoded><![CDATA[<p>Rá! Hoje quero falar sobre mod_rewrite. Um módulo para o apache que permite reescrever URL&#8217;s. Ele é muito útil em vários sentidos: aumenta a o page rank em buscadores, torna URL&#8217;s limpas e inteligíveis, fazendo com que o usuário consiga lembrá-las muito mais rápida e facilmente.</p>
<p>Porém, como todos os outros artefatos que estão por aí, pode complicar ainda mais a vida de um programador, caso não seja usado adequadamente.</p>
<p><span id="more-120"></span></p>
<h2>Introdução</h2>
<p>Como visto no post anterior, onde está descrito algumas vantagens e desvantages de se usar o mod_rewrite, neste post vamos concluir o assunto. Assumindo que você esteja usando Apache com o mod_rewrite habilitado. Também é necessário o uso de arquivos .htaccess: Arquivos ocultos que contém diretivas interpretadas pelo Apache. Para que seu .htaccess funcione, deve se certificar de que a diretiva <em>AllowOverride All</em> esteja nos arquivos de configuração do apache. Ela deve ficar dentro de &lt;Directory /&gt;, mais ou menos assim:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">	AllowOverride All</pre></div></div>

<p>Basta adicionar ao seus arquivos de configuração do apache ou requisitar seu servidor que o faça.</p>
<h2>Conhecendo as diretivas</h2>
<p>Antes de mais nada, vamos entender o que o mod_rewrite faz e é capaz de fazer, conhecendo seus parâmetros de configurações.</p>
<h4>RewriteEngine on|off</h4>
<p>Habilita(on) ou desabilita(off) o uso do módulo mod_rewrite.</p>
<h4>RewriteOptions [inherit] [MaxRedirects=X]</h4>
<p>   Adiciona uma ou as duas opções.</p>
<h5>inherit</h5>
<p>            Herda os parâmetros dos diretórios pai.</p>
<h5>MaxRedirects=X</h5>
<p>            Ao invés de permitir o &#8216;loop infinito&#8217; de redirecionamento, limita para X vezes. Caso, X seja alcançado, é disparado erro 500 (Internal Error).</p>
<h4>RewriteLog /caminho/para/arquivo.log</h4>
<p>Escreve o log dos eventos ocorridos no arquivo especificado.</p>
<h4>RewriteLogLevel Level</h4>
<p>Level inicia em 0 (desabilitado) e vai até 9 (números superiores podem ser utilizados, mas terão o mesmo efeito: irão logar quase tudo! Use somente para debug, pois vai diminuir a performance do apache. Bom para testes/debug, não para produção.)</p>
<h4>RewriteBase /dir</h4>
<p>Especifica /dir como a base para a procura do arquivo pelo Apache. (Mais explicações adiante)</p>
<h4>RewriteCond </h4>
<p>Responsável pela condições (a.k.a. IF&#8217;s). Pode-se utilizar inúmeros testes antes de especificar uma regra, sendo que a mesma só será executada ao passar por todos os testes com sucesso. Exemplos:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;"># Se o host for 123.45.67.89
RewriteCond %{REMOTE_ADDR} ^123.45.67.89$ [OR]
# ou for 98.76.54.32
RewriteCond %{REMOTE_ADDR} ^98.76.54.32
# A regra será a seguinte...</pre></div></div>

<p>Podem ser usadas uma série de variáveis, entre elas:</p>
<ul>
<li>%{HTTP_USER_AGENT}</li>
<li>%{HTTP_REFERER}</li>
<li>%{REMOTE_ADDR}</li>
<li>%{SCRIPT_FILENAME}</li>
<li>%{QUERY_STRING}</li>
<li>%{HTTP_HOST}</li>
<li>mais informações <a rel="nofollow" href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewritecond">aqui</a></li>
</ul>
<h4>RewriteRule </h4>
<p>É aqui que realmente acontece a reestruturação da URL. Aqui é onde é dito o que deve ser entrepretado como o quê. Se o Padrão casar, o apache interpreta como se fosse o Caminho.</p>
<p>Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">RewriteRule ^/(about|aboutme|sobre|sobremim|eu|minhavida)$ eu.html [L,NC]</pre></div></div>

<h3>Referências interessantes:</h3>
<ul>
<li><a rel="nofollow" href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html" alt="Documentação do Apache">Documentação do Apache</a></li>
<li><a rel="nofollow" href="http://www.addedbytes.com/cheat-sheets/download/mod_rewrite-cheat-sheet-v2.png" alt="ModRewrite CheatSheet">ModRewrite CheatSheet</a></li>
</ul>
<h2>Exemplos de uso</h2>
<p>Agora, com alguma noção sobre o mod_rewrite, vamos utilizá-los. Com alguns exemplos do que é possível. A idéia é que você descubra um jeito próprio e que funcione PARA VOCÊ. Esta é o tipo da coisa que não adianta fazer porque alguém disse que funciona, deve seguir os seus padrões e cobrir suas necessidades.</p>
<h3>Exemplo 1: Organizando seu site no .htaccess</h3>
<p>Convenhamos: uma notícia sobre um acidente não irá mudar. Depois de submetida para um site de notícias, dificilmente ela irá ser modificada. Ao menos que tenha passado desapercebido um erro de português ou uma estatística imprecisa, uma notícia não será modificada. Portando, é possível manter um cache da notícia em um arquivo .html, evitando consultas desnecessárias a bancos de dados ou outras fontes. Mas só porque ela está em cache, não significa que ela deva aparecer com o .html no fim ou .htm ou seja lá o que for.</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">RewriteEngine On
RewriteBase /
# Se não foi requerido um arquivo vazio (-s)
RewriteCond %{REQUEST_FILENAME} !-s [OR]
# Se não foi requerido um link simbólico (-l)
RewriteCond %{REQUEST_FILENAME} !-l [OR]
# ou um arquivo (-f)
RewriteCond %{REQUEST_FILENAME} !-f [OR]
# ou um diretório (-d)
RewriteCond %{REQUEST_FILENAME} !-d
# Aplique a seguinte regra:
# Se for notícia cacheada, chama o cache
RewriteRule ^ler/([A-Za-z0-9_-]+)$ /noticias/cache/$1.html [L]
# Se for para buscar por noticias
RewriteRule ^buscar/([A-Za-z0-9_-]+) /noticias/busca.php?termo=$1&amp;area=noticias [L]
# Feeds
RewriteRule ^feeds$ feeds.php?area=noticias
# Feeds para a categoria X
RewriteRule ^feeds/(.*)$ feeds.php?area=noticias&amp;categoria=$1</pre></div></div>

<p>e assim por diante. Podemos estabelecer regras, inclusive, para subdomínios.</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">RewriteCond %{HTTP_HOST} ^en\.example\.com$
RewriteRule ^(.*)$ /news/english/index.php?q=$1 [L]
&nbsp;
RewriteCond %{HTTP_HOST} ^br\.example\.com$
RewriteRule ^(.*)$ /news/brazilian/index.php?q=$1 [L]</pre></div></div>

<p>uma outra sugestão:</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">RewriteCond %{HTTP_HOST} ^en\.example\.com$
RewriteRule ^(.*)$ /news/index.php?lang=en&amp;q=$1 [L]
&nbsp;
RewriteCond %{HTTP_HOST} ^br\.example\.com$
RewriteRule ^(.*)$ /news/index.php?lang=pt-br&amp;q=$1 [L]</pre></div></div>

<h3>Exemplo 2: Listas de traduções</h3>
<p>A questão de usar uma única variável que receberá o valor da url, funciona melhor para este segundo caso:</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-s [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,NC]</pre></div></div>

<p>Imagine que seu cliente queira criar páginas novas, de &#8216;política de privacidade&#8217;, &#8217;sobre a empresa&#8217;, seja lá qual for o assunto da página. Ele vai querer acessá-la de forma rápida e acessível. Para tanto, <em>index.php?area=view_page&#038;page=4354</em> não parece agradar muita gente. Não seria interessante deixar que o próprio cliente crie seu padrão de URL? Talvez /politicas ou /empresa.</p>
<p>Existe uma forma interessante de se fazer isso: usando uma lista de expressões regulares e seus arquivos originais, os quais serão usados caso as expressões regulares casarem. Por exemplo, nos casos acima, apenas com o código abaixo no .htaccess, já poderíamos fazer algo:</p>
<p>A idéia é usar a <strong>REQUEST_URI</strong> (no php <strong>$_SERVER['REQUEST_URI']</strong>). Ela retornará, por exemplo, <em>/ler/minha_noticia_bombastica</em> que casará com <em>^/ler/([a-z0-9_-])$</em> e por consequência, irá chamar a <em>noticias.php</em>. Agora, como pegar o &#8216;minha_noticia_bombastica&#8217; ? Fácil! Basta apenas utilizarmos os grupos das expressões regulares de forma apropriada. Usando o exemplo do php, com <em>preg_match</em> podemos resolver isso!</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$urlPatterns</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'/^ler\/([a-z0-9_-]+)$/i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'noticias.php'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$urlPatterns</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$pattern</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$fileName</span><span style="color: #009900;">&#41;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$vars</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$_GET</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$vars</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">include</span> <span style="color: #000088;">$fileName</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Pronto! Alguns usuários podem ter notado, mas <em>$vars</em> irá ser uma sequência numérica dos grupos casados:</p>
<p>   <strong>0 => /ler/minha_noticia_bombastica, 1 => &#8216;minha_noticia_bombastica&#8217;</strong></p>
<p> Para resolver isso, podemos dar nomes aos grupos, o que seria extremamente normal para o programador (que utilizaria a variável $_GET normalmente) e bonito aos olhos do cliente. Para tanto, modificamos a nossa $urlPatterns:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #000088;">$urlPatterns</span> <span style="color: #339933;">=</span> <span style="color: #990000;">Array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'/ler\/(?&lt;news -slug&gt;[a-z0-9_-]+)$/i'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'noticias.php'</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;&lt;/</span>news<span style="color: #339933;">&gt;</span></pre></div></div>

<p>Assim, poderemos acessar <em>$_GET['news-slug']</em>. Como fica mais difícil do usuário modificar nomes de variáveis vindos da URL, se torna uma solução segura. Podemos ter certeza de que <em>$_GET['news-slug']</em> <strong>não conterá aspas, caracateres hexadecimais ou qualquer outro tipo de código malicioso</strong>. Pois se tivesse, não passaria no teste da expressão regular. E também nos certificamos de que aquele arquivo (noticias.php) só esteja sendo acessado, caso nossa index.php o esteja incluindo. Porque o usuário não conseguirá acessar de fora.</p>
<p>Neste caso, nós estipulamos os valores na <em>$urlPatterns</em>, mas ainda se pode pegar esses <strong>valores do banco de dados</strong>, por exemplo. Uma lista de &#8216;tradução&#8217; para a url. Funciona muito bem, principalmente com páginas estáticas ou fixas. Ao invés do cidadão digitar <em>index.php?area=pages&#038;page_id=4232</em>, ele estará acessando <em>/sobre-a-empresa</em>. Para usuários provenientes de sites de busca, isto é muito importante. Lhe dá muito mais <strong>segurança</strong> e você garante o seu clique. Ele vai direto ao ponto.</p>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/120/como-usar-mod_rewrite-de-verdade/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Gravando Sessões no Vim</title>
		<link>http://gustavodutra.com/post/108/gravando-sessoes-no-vim/</link>
		<comments>http://gustavodutra.com/post/108/gravando-sessoes-no-vim/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 16:39:38 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Nerd]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[produtividade]]></category>
		<category><![CDATA[sessao]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://gustavodutra.com/?p=108</guid>
		<description><![CDATA[Pense na cena: você está programando uma certa funcionalidade de um determinado projeto, vamos chamá-lo de A. Então, você tem 4 arquivos abertos em buffers dentro do Vim. Criou uns mapeamentos do teclado extra, só para o momento. Também tem marcadores que pulam de um trecho do código para outro. Está tudo do jeito que [...]]]></description>
			<content:encoded><![CDATA[<p>Pense na cena: você está programando uma certa funcionalidade de um determinado projeto, vamos chamá-lo de A. Então, você tem 4 arquivos abertos em buffers dentro do Vim. Criou uns mapeamentos do teclado extra, só para o momento. Também tem marcadores que pulam de um trecho do código para outro. Está tudo do jeito que você adora.</p>
<p>Chega, então, o seu chefe e diz: &#8220;Cara, preciso que tu veja algo em outro projeto.&#8221; ou até mesmo atualiza seu kernel e precisa rebootar o sistema. Chega sua namorada e pede pra ver o orkut. Seja qual seja o motivo, você precisa fechar o Vim. Mas, mais tarde, vai voltar a mexer, nestes 4 mesmos arquivos. Vai refazer todos os mapeamentos, refazer as marcações, etc.</p>
<p>Pois, se já aconteceu isso com você &#8211; comigo acontece muito frequênte -, você pode usar o <em>:mksession</em>.<br />
<span id="more-108"></span><br />
A sintaxe é a seguinte:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">:mksession ~/.vim-sessions/projeto-A.vim</pre></div></div>

<p>Você escolhe o nome do arquivo e o diretório e o vim grava no arquivo as informações exatas do editor no momento em que foi executado o comando. Dentre as coisas das quais ele grava estão:</p>
<ol>
<li><strong>Mapeamentos de teclas</strong></li>
<li><strong>Variáveis globais (iniciadas com maiúsculas e que tenham pelo menos 1 caracter minúsculo)</strong></li>
<li><strong>Caso use o GVim, grava o posicionamento e o tamanho dele na tela</strong></li>
<li><strong>Todos os arquivos abertos em buffers e o ponteiro do mouse</strong></li>
<li><strong>O estado visual do Gvim (folds, marks, incserch)</strong></li>
</ol>
<p>Depois de gravada, para recarregar a session, basta abrir o arquivo.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">gvim -S ~/.vim-sessions/projeto-A.vim
ou
vim -S ~/.vim-sessions/projeto-A.vim</pre></div></div>

<p>Eu tenho usado bastante para funcionalidades que requerem muita manutenção. Por exemplo, no desenvolvimento web.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">vim -S ~/.vim-sessions/projetoA-javascripts.vim
vim -S ~/.vim-sessions/projetoA-accounts.vim</pre></div></div>

<p>Assim, até o módulo de accounts ficar pronto, testado e aprovado pelo inmetro, todos os arquivos relacionados estão ali. E quando acaba o expediente, sobreescrevo a session, para que no próximo dia eu possa dar continuidade.</p>
<p>E você? Tem alguma idéia melhor? Comente!</p>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/108/gravando-sessoes-no-vim/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Como baixar e converter vídeos do youtube no linux</title>
		<link>http://gustavodutra.com/post/58/como-baixar-e-converter-videos-do-youtube-no-linux/</link>
		<comments>http://gustavodutra.com/post/58/como-baixar-e-converter-videos-do-youtube-no-linux/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 18:17:15 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Nerd]]></category>
		<category><![CDATA[Software Livre]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[slackware]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://blog.gustavodutra.com/?p=58</guid>
		<description><![CDATA[Aloha! Neste pequeno e simples tutorial (afinal de contas baixar e converter vídeos do youtube é bem mais simples do que você imagina!) vou mostrar a forma mais roots de como baixar vídeos do youtube e converter ela para o formato que quiser. Para isso, vou usar o Slackware 12.2 (testei também no ubuntu 8.04 [...]]]></description>
			<content:encoded><![CDATA[<p>Aloha! Neste pequeno e simples tutorial (afinal de contas baixar e converter vídeos do youtube é bem mais simples do que você imagina!) vou mostrar a forma mais <em>roots</em> de como baixar vídeos do youtube e converter ela para o formato que quiser. Para isso, vou usar o Slackware 12.2 (testei também no ubuntu 8.04 e funcionou legal).</p>
<p>Bom, vamos aos requisitos dos quais vamos precisar:</p>
<ul>
<li>Pacote ffmpeg instalado (geralmente vem com o mplayer, pode ser instalado por apt-get. Também há uma build no linuxpackages)</li>
<li>1 Browser de sua preferência.</li>
<li>1 xícara de café puro sem açúcar</li>
<li>Uma tesoura sem ponta</li>
<li>Cola em bastão</li>
<li>1 url de algum vídeo do youtube</li>
</ul>
<p><span id="more-58"></span></p>
<h2>Baixando o vídeo do youtube</h2>
<p>Modo de preparo:</p>
<ol>
<li>Abra o browser de sua preferência e acesse a url do vídeo do youtube. Eu vou utilizar: http://www.youtube.com/watch?v=dMR0VRb7g60 uma música dos &#8216;Os Nerds&#8217; que fala de um cara que pede &#8220;me dê op no #seu_coração&#8221;, uma paródia com &#8220;here comes you&#8217;re man&#8221;.</li>
<li>Após ter carregada a página, abra o código-fonte do mesmo. (Firefox: CTRL+U).</li>
<li>Localize no meio de tudo aquilo a string &#8220;t&#8221;, sim com aspas e tudo &#8220;t&#8221;. No meu caso ele está nessa linha:

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">var swfArgs = {&quot;q&quot;: &quot;os%20nerds%20kick%20de%20amor&quot;, &quot;vq&quot;: null, &quot;sourceid&quot;: &quot;ys&quot;, &quot;video_id&quot;: &quot;dMR0VRb7g60&quot;, &quot;l&quot;: 164, &quot;sk&quot;: &quot;C4c1AWqTMKCqlc-ps6iNq8hHDwAaAkYAU&quot;, &quot;fmt_map&quot;: &quot;&quot;, &quot;usef&quot;: 0, &quot;t&quot;: &quot;OEgsToPDskJ9NevmQow7fOToemrym1db&quot;, &quot;hl&quot;: &quot;en&quot;, &quot;plid&quot;: &quot;AARgxT891VByDIGsAAAAoAAAAAA&quot;};</pre></div></div>

<p>Viu ele? &#8220;t&#8221;: &#8220;OEgsToPDskJ9NevmQow7fOToemrym1db&#8221;</li>
<li>Copie(com a tesoura sem ponta) aquele token (OEgsToPDskJ9NevmQow7fOToemrym1db) da página do seu vídeo</li>
<li>Agora, na barra de endereços do browser, vamos trocar um pouco as coisas. o que era:<br />
http://www.youtube.com/watch?v=dMR0VRb7g60 vai se tornar: http://www.youtube.com/get_video?video_id=dMR0VRb7g60&#038;t=OEgsToPDskJ9NevmQow7fOToemrym1db (Observerem que trocamos: watch por get_video, v por video_id e adicionamos &#038;t=TOKEN), onde depois de &#038;t= colamos com cola bastão o aquele token que retiramos do código-fonte.</li>
<li>Dando um enter, ele vai pedir pra fazer o download. Esse download é justamente o flv.</li>
<li>Enquanto baixa o vídeo, você toma a 1 xícara de café puro sem açucar.</li>
</ol>
<h2>Convertendo o Vídeo</h2>
<p>Bom, nem todo player toca .flv, então talvez alguns queiram convertê-lo pra .mp3 ou pra .avi, .ogg ou .mpeg. Para isso, vamos utilizar o ffmpeg.</p>
<h3>Convertendo para mp3</h3>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">ffmpeg -author &quot;Os nerds&quot; -title &quot;Me dê op&quot; -i download/get_video.flv -ab 128 -ac 2 -acodec mp3 -vn -y ~/&quot;Musicas/Os nerds - Me dê op.mp3&quot;</pre></div></div>

<p>Voalá! os comandos -author e -title vão mexer na IDv3 da mp3. Assim, quando executar num player, vai aparecer bonitinho o autor e a música. -ab para especificar o bitrate, -i = arquivo de entrada, e -vn = desabilita a gravação de vídeo. -y = é para sobreescrever o arquivo de destino. Ah! e o -acodec para selecionar o codec do audio e -ac o número de canais.</p>
<p>UPDATE<br />
Usando o Arch Linux eu notei que o <strong>-acodec mp3</strong> não funcionava. Portanto, caso vocês não conseguirem com -acodec mp3, tentem: <strong>-acodec libmp3lame</strong></p>
<h3>Convertendo para avi</h3>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">ffmpeg -i download/get_video.flv -ab 56 -y ~/&quot;Clipes/Os nerds - Me dê op.avi&quot;</pre></div></div>

<p>Mais parâmetros, ajuda e outras coisas: http://swoolley.org/man.cgi/1/ffmpeg<br />
Agora você não precisa mais aqueles programinhas cheio de spyware ou ver 300 erros antes de conseguir baixar o vídeo pelo vixy.net!</p>
<p>Qualquer dúvida comente!</p>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/58/como-baixar-e-converter-videos-do-youtube-no-linux/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>15 dicas para maior produtividade usando o GVim</title>
		<link>http://gustavodutra.com/post/48/15-dicas-para-maior-produtividade-usando-o-gvim/</link>
		<comments>http://gustavodutra.com/post/48/15-dicas-para-maior-produtividade-usando-o-gvim/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 21:33:14 +0000</pubDate>
		<dc:creator>Gustavo Dutra</dc:creator>
				<category><![CDATA[Nerd]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[exemplo]]></category>
		<category><![CDATA[gvimrc]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[produtividade]]></category>
		<category><![CDATA[vimrc]]></category>

		<guid isPermaLink="false">http://blog.gustavodutra.com/?p=48</guid>
		<description><![CDATA[Olá! \o/
Hoje vou falar sobre dicas (algumas bem simples, mas que fazem diferença) para aumentar a produtividade no GVim/Vim. Algumas delas são plugins, outras vão direto para o ~/.gvimrc!

Color Picker
Saindo sem estresse
Colocando Headers nos arquivos
Abrindo arquivos escritos no arquivo
Trabalhando com buffers
Aprimorando a busca
Mudando a fonte
Documentando o código
Autocomplete de código
Rodando comandos do Shell
Solução para arquivos chatos [...]]]></description>
			<content:encoded><![CDATA[<h2>Olá! \o/</h2>
<p>Hoje vou falar sobre dicas (algumas bem simples, mas que fazem diferença) para aumentar a produtividade no GVim/Vim. Algumas delas são plugins, outras vão direto para o ~/.gvimrc!</p>
<ol>
<li>Color Picker</li>
<li>Saindo sem estresse</li>
<li>Colocando Headers nos arquivos</li>
<li>Abrindo arquivos escritos no arquivo</li>
<li>Trabalhando com buffers</li>
<li>Aprimorando a busca</li>
<li>Mudando a fonte</li>
<li>Documentando o código</li>
<li>Autocomplete de código</li>
<li>Rodando comandos do Shell</li>
<li>Solução para arquivos chatos de backup</li>
<li>Removendo Linhas em Branco</li>
<li>Compilando arquivos e analizando erros</li>
<li>Mostrando a identação</li>
<li>Autorrecarregando nosso .gvimrc</li>
</ol>
<ol>
<span id="more-48"></span></p>
<h2>1. Color Picker</h2>
<p>Quem trabalha com web, geralmente precisa rapidamente selecionar uma cor em hexadecimal. Geralmente recorremos à sites para isso. Existe um plugin que resolve nossos problemas, você pode baixar ele aqui: http://www.vim.org/scripts/script.php?script_id=927</p>
<p>Para instalar é muito fácil. Baixe o arquivo colorsel.vim do site mencionado acima, jogue para dentro do diretórios de plugins, no meu caso /usr/share/vim/vim71/plugins. Ao reiniciar o gvim, basta digitar</p>
<pre>:colorSel</pre>
<p>Ele deve aparecer algo como:</p>
<p><img class="aligncenter size-full wp-image-50" title="colorsel" src="http://blog.gustavodutra.com/wp-content/uploads/2009/01/colorsel.png" alt="colorsel" width="364" height="260" /></p>
<p>Notem, que caso o vim seja aberto pelo terminar, ele dispara um erro, dizendo que o plugin instalado é para uso com interface gráfica. Para resolver isso, na linha 24 do colorsel.vim, que começa com &#8217;stderr&#8217;&#8230;</p>
<p>Apenas apague esta linha e o erro não é mais mostrado para você!</p>
<h2>2. Saindo sem estresse</h2>
<p>Muitos devem ficar brabos ao tentar sair do vim e digitar o Q maiúsculo</p>
<pre>:Q</pre>
<p>Para isso, vamos por no nosso ~/.gvimrc</p>
<pre>cab W w
cab Q q
cab Wq wq
cab wQ wq
cab WQ wq</pre>
<p>Isso vai fazer com que ao digitar algum comando da segunda coluna, ele deve interpretar como o da terceira, logo se for digitado :Q, ele vai entender :q. Isso nos livras de muitas dores de cabeça!</p>
<h2>3. Colocando Headers nos arquivos</h2>
<p>Muita gente gosta de identificar o arquivo que está escrevendo ou até mesmo ao documentar arquivos. Às vezes precisa por uma licensa, o autor do arquivo, a hora em que foi escrito. Algumas IDE&#8217;s oferecem isso normalmente, o GVim, apesar de não ser uma IDE, também oferece algo parecido. Basta acrescentar estas linhas no .gvimrc, mapeando a tecla F8 (você pode modificar à sua preferência).</p>
<pre>map &lt;F8&gt; O/**&lt;CR&gt;
\* Descrição do arquivo&lt;CR&gt;
\* @author Gustavo Dutra &lt;mechamo@gustavodutra.com&gt;&lt;cr&gt;
\* @created &lt;esc&gt;:r!date '+\%d/\%m/\%y'&lt;cr&gt;kJA&lt;cr&gt;
\*/</pre>
<p>Ao abrir um novo arquivo, basta pressionar F8, ele acrescentará nosso header (que você pode modificar para o que você desejar!).</p>
<h2>4. Abrindo arquivos escritos no arquivo</h2>
<p>Algumas linguagens não usam &#8216;import&#8217;, porém incluem arquivos dentro de arquivos, o que salva muito a vida do programador. Mas supondo que estamos editando o arquivo X, que inclui o arquivo Y, e precisamos, por alguma eventualidade, editar algo no arquivo Y. Precisamos abrir o arquivo passando todo o caminho até ele. Para isso, facilitar isso, façamos um atalho:</p>
<pre>nmap gf :new %:p:h/&lt;cfile&gt;&lt;CR&gt;</pre>
<p>Basta posicionar o cursor sobre o nome do arquivo, e digitar &#8216;gf&#8217;. Nomeei gf para significar Go to File. Você pode colocar o atalho que desejar! Basta mudar o gf para o que quiseres.</p>
<h2>5. Trabalhando com buffers</h2>
<p>Eu particularmente não gosto de um monte de instâncias do GVim aberta ao mesmo tempo, muito menos gosto de tabs. Eu gosto mesmo é de buffers. Para isso criei alguns atalhos para navegar entre eles</p>
<pre>map &lt;A-1&gt; :b1&lt;cr&gt;
map &lt;A-2&gt; :b2&lt;cr&gt;
map &lt;A-3&gt; :b3&lt;cr&gt;
map &lt;A-4&gt; :b4&lt;cr&gt;
map &lt;A-5&gt; :b5&lt;cr&gt;
map &lt;A-6&gt; :b6&lt;cr&gt;
map &lt;A-7&gt; :b7&lt;cr&gt;
map &lt;A-8&gt; :b8&lt;cr&gt;
map &lt;A-9&gt; :b9&lt;cr&gt;
map &lt;A-0&gt; :b10&lt;cr&gt;
map &lt;S-F1&gt; :b11&lt;cr&gt;
map &lt;S-F2&gt; :b12&lt;cr&gt;
map &lt;S-F3&gt; :b13&lt;cr&gt;
map &lt;S-F4&gt; :b14&lt;cr&gt;
map &lt;S-F5&gt; :b15&lt;cr&gt;
map &lt;S-F6&gt; :b16&lt;cr&gt;
map &lt;S-F7&gt; :b17&lt;cr&gt;
map &lt;S-F8&gt; :b18&lt;cr&gt;
map &lt;S-F9&gt; :b19&lt;cr&gt;
map &lt;S-F10&gt; :b20&lt;cr&gt;
map &lt;S-F11&gt; :b21&lt;cr&gt;
map &lt;S-F12&gt; :b22&lt;cr&gt;
map &lt;C-Q&gt; :bwipeout&lt;cr&gt;
map &lt;F6&gt; :buffers&lt;cr&gt;</pre>
<p>Para quem não sabe, para iniciar um buffer, utilizamos :e. Logo, para abrir nosso .gvimrc num buffer diferente, digitamos</p>
<pre>:e ~/.gvimrc</pre>
<p>À cada buffer aberto, o GVim da um número sequencial começando em 1. Nos mapa descrito ali em cima, ALT+1 até ALT+0 navegam nos 10 primeiros buffers. SHIFT+F1 até SHIFT+F12, navegam do buffer 11 até o 22. CTRL+Q, fecha o buffer (remove da lista) e F6 lista todos os buffers disponíveis com os nomes dos arquivos e seus respectivos números.</p>
<h2>6. Aprimorando a busca</h2>
<p>Para buscar por algum trecho de texto no gvim, é utilizado a barra (/).</p>
<pre>/texto da busca</pre>
<p>Adicionando no nosso .gvimrc o seguinte:</p>
<pre>set incsearch
set hlsearch</pre>
<p>É possível fazer com que à medida em que é digitado, o GVim saliente o texto (highlight), caso encontrado. Para navegar entre os resultados, utilizamos n (próxima ocorrência) ou N (ocorrência anterior). Mas, uma das coisas interessantes é sobreescrever estes comandos desta forma:</p>
<pre>nmap n nzz
nmap N Nzz</pre>
<p>zz é responsável por por a linha atual no centro da tela. Logo, isto permite que ao encontrar uma próxima ocorrência do texto, o texto ficará no meio da tela.</p>
<h2>7. Mudando a fonte</h2>
<p>No Vim a fonte utilizada é a do Terminal no qual ele foi executado. No GVim, por ser gráfico, possibilita com que seja modificada a fonte atual.</p>
<pre>set guifont=Fonte\ Desejada\ 8</pre>
<p>Lembre-se de escapar os espaços. Logo depois do nome da fonte, é colocado o tamanho dela. Se por alguma acaso você ficar em dúvida em qual fonte utilizar, você pode digitar o seguinte no GVim</p>
<pre>:set guifont=*</pre>
<p>Com isso, ele abrirá o seletor de fontes do seu OS. Basta selecionar o dar OK. Quando feito e fonte for modificada, você pode digitar somente</p>
<pre>:set guifont</pre>
<p>Ele retornará a sintaxe correta de como usar a fonte e o tamnho da mesma. Então, basta copiar e colar no .gvimrc!</p>
<h2>8. Documentando o código</h2>
<p>Todos sabem da importância que é documentar os códigos, assim como sabem a chatisse que é! Para nos ajudar com isso, seguem alguns plugins:</p>
<ul>
<li><a rel="nofollow" href="http://www.vim.org/scripts/script.php?script_id=1355" target="_blank">PHPdoc</a></li>
<li><a rel="nofollow" href="http://github.com/hotchpotch/perldoc-vim/tree/master" target="_blank">Perl<br />
</a></li>
<li><a rel="nofollow" href="http://www.vim.org/scripts/script.php?script_id=20" target="_blank">Javadoc</a></li>
</ul>
<h2>9. Autocomplete de código</h2>
<p>Maneira simples de autocompletar o código é usando CTRL+X + CTRL+O, mas isso é difícil de assimilar, logo podemos criar uma funçãozinha para ajudar:</p>
<pre>function! CleverTab()
if strpart( getline('.'), 0, col('.')-1 ) =~ '^\s*$'
return "\&lt;Tab&gt;"
else
return "\&lt;C-X&gt;\&lt;C-O&gt;"
endfunction
inoremap &lt;Tab&gt; &lt;C-R&gt;=CleverTab()&lt;CR&gt;
set completeopt=menu,preview
</pre>
<p>Ao digitar &#8216;tex&lt;TAB&gt;&#8217; ele vai tentar utilizar o omnicompletition para completar a palavra, que pode ser uma função/variável criada dentro do arquivo ou nativa da linguagem.</p>
<h2>10. Rodando comandos do Shell</h2>
<p>Quantas vezes você já precisou ordenar algo em ordem alfabética? copiar um arquivo inteiro para o arquivo que está digitando? Para quem domina o shell, isso vai ser muito útil. No nosso .gvimrc vamos por o seguinte:</p>
<pre>set shell=/bin/bash</pre>
<p>Feito isso, vamos fazer alguns testes. Abra algum no gvim e cole o seguinte:</p>
<pre>Banana
Maçã
Amora
Pêra
Batata
Melancia</pre>
<p>Agora, vamos à mágica:</p>
<p>Digite o seguinte:</p>
<pre>:%!sort</pre>
<p>Tcharam! O % diz que é o arquivo inteiro; o ! exige que seja executado no shell. sort é comando do shell. O GVim automaticamente pega o conteúdo do arquivo, executa o comando no shell e substitui pelo resultado! Então, para copiar um arquivo no fim do nosso aberto, podemos utilizar o &#8216;cat&#8217;</p>
<pre>:$!cat /meu/arquivo</pre>
<p>Observem que eu utilizei $, ele vai começar a colar na última linha do arquivo. É legal, então, sempre ter certeza que esta linha está em branco, para que não haja perda de dados. Você também pode por numa linha específica.</p>
<pre>:6!cat /meu/arquivo</pre>
<p>Ele vai substituir o texto da linha 6 com o que contiver no arquivo, conservando da linha 1 até a linha 5, e da linha 7 até o fim do arquivo.</p>
<h2>11. Solução para arquivos chatos de backup</h2>
<p>Sabe aqueles arquivos de backup do vim? Que ficam .ext~ ? Você edita algo no projeto e o vim polui o projeto inteiro, quando você vê, já perdeu as contas de quantos arquivos novos foram criados. Ou até mesmo já commitou aqueles arquivos de swap (.swp) do vim sem querer.</p>
<p>Para resolver isso, podemos mudar o diretório onde eles são criados ou até mesmo desabilitá-los, basta acrescentar no .gvimrc:</p>
<pre>set backup
set backupdir=/tmp
set dir=/tmp</pre>
<p>Se você deseja desabilitar, utilize &#8217;set nobackup&#8217;, caso contrário os arquivos de backup irão para o /tmp, e não mais para o diretório do seu projeto! O mesmo acontece com os .swp, especificado pelo &#8217;set dir&#8217;.</p>
<h2>12. Removendo Linhas em Branco</h2>
<p>Para remover todas as linhas em branco do arquivo (vazias ou que contenham somente espaços) podemos utilizar:</p>
<pre>:g/^\s*$/d</pre>
<h2>13. Compilando arquivos e analizando erros</h2>
<p>Para compilar um arquivo, basta especificarmos o compilador. Vamos usar o exemplo do javac.</p>
<pre>:compiler javac</pre>
<p>Para compilar arquivos em java, abra ele no gvim, execute o comando acima e digite:</p>
<pre>:make %</pre>
<p>Ele irá compilar com o javac o arquivo atual e mostrar os erros em tempo de compilação. Por mais louco que pareça, há também como fazer isso com o php, por exemplo. Mas ao invés de compilar o código, ele checa a sintaxe.</p>
<pre>:compiler php
:make %</pre>
<p>Ele irá executar `php -l arquivo.php`, retornando os erros de sintaxes! É bom para testes antes de rodá-lo, evitando erros bobos como o esquecimento de 1 ponto e vírgula, um ponto ao concatenar, etc.</p>
<p>Ah! Caso você desejar, pode modificar o comando do make! Se quiser adicionar mais parâmetros, por exemplo, jogar todos os erros que já teve para um determinado lugar (é legal saber o quanto de erro produzimos, para que, ao programar, tentamos cometer cada vez menos e nunca os mesmos (né? ^__^)):</p>
<pre>au FileType php set makeprg=php\ -l\ %\ &gt;&gt;\ /tmp/errors.log</pre>
<p>assim, ele modificará somente se o arquivo for interpretado como php. Basta dar um :make que ele joga para o arquivo. No final do dia podemos avaliar nossos erros e ver (olha, preciso melhor em tal aspecto).</p>
<h2>14. Mostrando a identação</h2>
<p>Quem nunca se perguntou (o que este } está fechando? é este ou aquele if?). Pois é, bater o olho e de cara descobrir é complicado, ainda mais quando o início (if () {) não está na mesma página, digo, não é visível, é preciso rolar pra vê-lo.</p>
<pre>set list listchars=tab:»·,trail:·,eol:$</pre>
<p>Assim, primeiro habilitamos a exibição deles. Depois substituimos com os valores. Isso fará com que o nossa identação fique visível, e possamos ver (hmm&#8230; esse if tem 3 tabs antes, então vai fechar na } que tiver 3 tabs antes também!). O arquivo ficará mais ou menos assim:</p>
<pre>»····»····»····if (condicao) {$
»····»····»····»····//codigo$
»····»····»····}$</pre>
<p>Assim, o código fica claro. Você se acha no tab e consegue enxergar se há espaços desnecessários no final da linha, pois $ representa o nosso amigo \n.</p>
<h2>15. Autorrecarregando nosso .gvimrc</h2>
<p>Bom, apresento para vocês o autocmd bufwritepost. Ele é executado depois do arquivo ser salvo. Então ao salvar o arquivo ele executa o(s) comando(s) que seguem ali. Acrescentamos, então, ao nosso gvimrc os seguintes comandos:</p>
<pre>autocmd! bufwritepost .gvimrc source %
autocmd! bufwritepost .vimrc source %</pre>
<p>Assim, ao salvar .gvimrc ou .vimrc, ele recarregará as configurações automaticamente! Voltando ali na dica 13, podemos fazer isso:</p>
<pre>autocmd! bufwritepost *.php make %</pre>
<p>Rá! Agora, ao salvar um arquivo .php, ele executa no :make % que manda para /tmp/errors.log! Não é feitiçaria, é tecnologia.</p>
<p>Espero que alguma coisa seja útil para vocês! Fui!</ol>
]]></content:encoded>
			<wfw:commentRss>http://gustavodutra.com/post/48/15-dicas-para-maior-produtividade-usando-o-gvim/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
