<?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>Destaquenet blog</title>
	<atom:link href="http://weblog.destaquenet.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>O Blog da equipe Destaquenet</description>
	<lastBuildDate>Wed, 01 Jul 2009 20:33:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fabric + VirtualEnv: uma combinação explosiva (no bom sentido)</title>
		<link>http://weblog.destaquenet.com/2009/07/01/fabric-virtualenv-uma-combinacao-explosiva-no-bom-sentido/</link>
		<comments>http://weblog.destaquenet.com/2009/07/01/fabric-virtualenv-uma-combinacao-explosiva-no-bom-sentido/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 04:20:01 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[automatização]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[django-flash]]></category>
		<category><![CDATA[fabric]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[pypi]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[setuptools]]></category>
		<category><![CDATA[teste]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virtualenv]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=554</guid>
		<description><![CDATA[Escreveu uma super-hiper-biblioteca ou aplicação em Python mas quer se certificar de que ela funciona em diferentes versões do interpretador? Embora isso possa ser resolvido através da execução manual dos testes com os vários interpretadores, isso é chato e improdutivo. Além do mais, cada versão do Python pode ter diferentes bibliotecas instaladas, o que pode [...]]]></description>
			<content:encoded><![CDATA[<p>Escreveu uma super-hiper-biblioteca ou aplicação em <a href="http://python.org">Python</a> mas quer se certificar de que ela funciona em diferentes versões do interpretador? Embora isso possa ser resolvido através da execução <em>manual</em> dos testes com os vários interpretadores, isso é chato e improdutivo. Além do mais, cada versão do Python pode ter diferentes bibliotecas instaladas, o que pode acabar influenciando no resultado dos testes.</p>
<p>Temos portanto dois problemas a serem resolvidos. O primeiro problema, relacionado a automatização de tarefas repetitivas, pode ser facilmente solucionado com <a href="http://docs.fabfile.org/">Fabric</a>, uma ferramenta muito útil para criação de scripts de build e deployment de aplicações. Já escrevemos <a href="http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/">um texto introdutório</a> sobre a mesma, não deixe de conferir.</p>
<p>O segundo problema, entretanto, é um pouco mais complicado de se resolver, mas não é nenhum bicho de sete cabeças. Com <a href="http://pypi.python.org/pypi/virtualenv/">VirtualEnv</a>, é possível criar ambientes Python isolados com o objetivo de testar e executar aplicações em uma espécie de sandbox onde temos total controle sobre as bibliotecas ali instaladas.</p>
<p><span id="more-554"></span></p>
<h3>Instalando as diferentes versões do Python</h3>
<p>O primeiro passo é instalar as versões do Python a serem usadas nos testes. Rode o comando abaixo para instalar os diferentes interpretadores, supondo que você utilize <a href="http://www.debian.org/">Debian</a> e sua aplicação precise funcionar nas versões 2.4, 2.5 e 2.6 do Python:</p>
<pre>$ sudo apt-get install python2.4 python2.4-dev \
    python2.5 python2.5-dev \
    python2.6 python2.6-dev</pre>
<p>A versão atual do Ubuntu já inclui o Python 2.6 por padrão. Veja também que aproveitamos para instalar os arquivos de desenvolvimento para cada versão, pois eventualmente precisamos deles para compilar bibliotecas com extensões escritas em C.</p>
<h3>Instalando Fabric e VirtualEnv</h3>
<p>Da mesma forma:</p>
<pre>$ sudo apt-get install python-setuptools</pre>
<p>Após a instalação do <a href="http://pypi.python.org/pypi/setuptools/">SetupTools</a>, execute o seguinte comando para instalar o Fabric e o VirtualEnv:</p>
<pre>$ sudo easy_install Fabric virtualenv</pre>
<h3>Configurando ambientes isolados para sua aplicação</h3>
<p>O próximo passo é criar ambientes de execução isolados para sua aplicação, sendo que cada ambiente deve usar uma versão diferente do interpretador do Python. Para fazer isso, execute os comandos abaixo, substituindo o <code>APP</code> pelo nome da sua aplicação ou biblioteca:</p>
<pre>$ mkdir ~/.virtualenvs
$ cd ~/.virtualenvs
$ virtualenv --python=/usr/bin/python2.6 --no-site-packages APP-py2.6
$ virtualenv --python=/usr/bin/python2.5 --no-site-packages APP-py2.5
$ virtualenv --python=/usr/bin/python2.4 --no-site-packages APP-py2.4</pre>
<p>Primeiramente criamos o diretório <code>~/.virtualenvs</code>, que é por convenção o diretório padrão para armazenamento dos ambientes. Em seguida, criamos três ambientes para nossa aplicação <code>APP</code>. A flag <code>--no-site-packages</code> é <em>opcional</em> e indica que as bibliotecas instaladas no diretório <code>site-packages</code> do Python em questão não devem ser visíveis ao ambiente sendo criado.</p>
<p>Finalmente, não esqueça de instalar, em cada um dos ambientes, as dependências exigidas pela sua aplicação:</p>
<pre>$ source ~/.virtualenvs/APP-py2.6/bin/activate
(APP-py2.6) $ easy_install biblioteca1 biblioteca2 ... bibliotecaN
(APP-py2.6) $ source ~/.virtualenvs/APP-py2.5/bin/activate
(APP-py2.5) $ easy_install biblioteca1 biblioteca2 ... bibliotecaN
(APP-py2.5) $ source ~/.virtualenvs/APP-py2.4/bin/activate
(APP-py2.4) $ easy_install biblioteca1 biblioteca2 ... bibliotecaN</pre>
<p>Supondo que sua aplicação utilize o SetupTools para a configuração dos metadados do projeto (através do script <code>setup.py</code>), os comandos abaixo devem indicar se a aplicação funciona nos ambientes que criamos:</p>
<pre>$ source ~/.virtualenvs/APP-py2.6/bin/activate
(APP-py2.6) $ python setup.py test
...
(APP-py2.6) $ source ~/.virtualenvs/APP-py2.5/bin/activate
(APP-py2.5) $ python setup.py test
...
(APP-py2.5) $ source ~/.virtualenvs/APP-py2.4/bin/activate
(APP-py2.4) $ python setup.py test
...</pre>
<h3>Automatizando!</h3>
<p>Se tudo funcionou até aqui, estamos prontos para criar um script que nos permita rodar os testes de forma automática, nos diferentes ambientes.</p>
<p>Supondo que sua aplicação utilize o SetupTools para a configuração dos metadados do projeto, o exemplo abaixo resolve o problema:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Environment info</span>
config.<span style="color: black;">project</span> = <span style="color: #483d8b;">'APP'</span>
config.<span style="color: black;">virtualenv_dir</span> = <span style="color: #483d8b;">'~/.virtualenvs'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Supported Python versions</span>
config.<span style="color: black;">versions</span> = <span style="color: black;">&#40;</span><span style="color: #483d8b;">'2.4'</span>, <span style="color: #483d8b;">'2.5'</span>, <span style="color: #483d8b;">'2.6'</span>,<span style="color: black;">&#41;</span>
config.<span style="color: black;">default_version</span> = <span style="color: #483d8b;">'2.6'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> setup<span style="color: black;">&#40;</span>command, version=config.<span style="color: black;">default_version</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Executes the given setup command with a virtual Python installation.
    &quot;&quot;&quot;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s/%s-py%s/bin/python setup.py %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>config.<span style="color: black;">virtualenv_dir</span>, config.<span style="color: black;">project</span>, version, command<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">test</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Runs all tests in different Python versions.
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> version <span style="color: #ff7700;font-weight:bold;">in</span> config.<span style="color: black;">versions</span>:
        setup<span style="color: black;">&#40;</span><span style="color: #483d8b;">'test'</span>, version<span style="color: black;">&#41;</span></pre></div></div>

<p>Agora é só alegria:</p>
<pre>$ fab test
Fabric v. 0.1.1.
Running test...
[localhost] run: ~/.virtualenvs/APP-py2.4/bin/python setup.py test
...
[localhost] run: ~/.virtualenvs/APP-py2.5/bin/python setup.py test
...
[localhost] run: ~/.virtualenvs/APP-py2.6/bin/python setup.py test
...</pre>
<p>Devo lembrar que o script mostrado é só um exemplo. Você pode (e <strong>deve</strong>) modificá-lo para que este atenda às suas necessidades.</p>
<h3>(Bônus!) Distribuindo sua aplicação para diferentes versões do Python</h3>
<p>Com mais algumas linhas de código, podemos criar tasks que nos permitam gerar arquivos para distribuição da aplicação para diferentes versões do Python:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> dist_src<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Create source archive.
    &quot;&quot;&quot;</span>
    setup<span style="color: black;">&#40;</span><span style="color: #483d8b;">'sdist'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> dist_eggs<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Create binary archives, one for each Python version.
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> version <span style="color: #ff7700;font-weight:bold;">in</span> config.<span style="color: black;">versions</span>:
        setup<span style="color: black;">&#40;</span><span style="color: #483d8b;">'bdist_egg'</span>, version<span style="color: black;">&#41;</span></pre></div></div>

<h3>(Bônus!) Automatizando geração de documentação e upload para o PyPI</h3>
<p>Ainda acha pouco? <a href="http://github.com/danielfm/django-flash/blob/master/fabfile.py">Este outro exemplo</a> de script vai além e mostra, numa aplicação real, como automatizar o registro e upload dos pacotes para o <a href="http://pypi.python.org/pypi/">PyPI</a>, atualizar site de documentação, entre outras coisas.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/07/01/fabric-virtualenv-uma-combinacao-explosiva-no-bom-sentido/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FISL 10: Vídeos</title>
		<link>http://weblog.destaquenet.com/2009/06/30/fisl-10-videos/</link>
		<comments>http://weblog.destaquenet.com/2009/06/30/fisl-10-videos/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 11:25:06 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[evento]]></category>
		<category><![CDATA[fisl]]></category>
		<category><![CDATA[fisl10]]></category>
		<category><![CDATA[fórum]]></category>
		<category><![CDATA[software livre]]></category>
		<category><![CDATA[vídeo]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=560</guid>
		<description><![CDATA[Promessa é dívida!

GNU and Richard Stallman dancing at FISL 10!
GNU dancing at FISL 10
GNU dancing warm-up at FISL 10

]]></description>
			<content:encoded><![CDATA[<p><a href="http://weblog.destaquenet.com/2009/06/29/fisl-10-fotos/">Promessa</a> é dívida!</p>
<ul>
<li><a href="http://www.youtube.com/watch?v=zxhSrUuQy0o">GNU and Richard Stallman dancing at FISL 10!</a></li>
<li><a href="http://www.youtube.com/watch?v=lP36JGmEpUc">GNU dancing at FISL 10</a></li>
<li><a href="http://www.youtube.com/watch?v=gnB5s9smglA">GNU dancing warm-up at FISL 10</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/06/30/fisl-10-videos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FISL 10: Fotos</title>
		<link>http://weblog.destaquenet.com/2009/06/29/fisl-10-fotos/</link>
		<comments>http://weblog.destaquenet.com/2009/06/29/fisl-10-fotos/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 16:15:10 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[evento]]></category>
		<category><![CDATA[fisl]]></category>
		<category><![CDATA[fisl10]]></category>
		<category><![CDATA[fórum]]></category>
		<category><![CDATA[foto]]></category>
		<category><![CDATA[software livre]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=547</guid>
		<description><![CDATA[Acabei de subir as fotos no Flickr!
Assim que possível subirei também alguns vídeos, inclusive um onde Richard Stallman dança com Gnu. Imperdível!
]]></description>
			<content:encoded><![CDATA[<p>Acabei de subir as <a href="http://www.flickr.com/photos/daniel_tritone/sets/72157620720957680/">fotos no Flickr</a>!</p>
<p>Assim que possível subirei também alguns vídeos, inclusive um onde <a href="http://stallman.org/">Richard Stallman</a> dança com Gnu. Imperdível!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/06/29/fisl-10-fotos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>FISL 10: Aí vou eu!</title>
		<link>http://weblog.destaquenet.com/2009/06/22/fisl-10-ai-vou-eu/</link>
		<comments>http://weblog.destaquenet.com/2009/06/22/fisl-10-ai-vou-eu/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 12:00:44 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[evento]]></category>
		<category><![CDATA[fisl]]></category>
		<category><![CDATA[fisl10]]></category>
		<category><![CDATA[fórum]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[porto alegre]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=540</guid>
		<description><![CDATA[Nesta quarta-feira acontece, em Porto Alegre, o maior evento de software livre da América Latina e um dos maiores do mundo. O Fórum Internacional de Software Livre, ou FISL, chega este ano à sua décima edição, que promete ser ainda melhor e maior que as anteriores.
Quando voltei do meu primeiro fórum, em 2007, prometi a [...]]]></description>
			<content:encoded><![CDATA[<p>Nesta quarta-feira acontece, em Porto Alegre, o maior evento de software livre da América Latina e um dos maiores do mundo. O <a href="http://fisl.org.br/">Fórum Internacional de Software Livre</a>, ou FISL, chega este ano à sua décima edição, que promete ser ainda melhor e maior que as anteriores.</p>
<div id="attachment_542" class="wp-caption aligncenter" style="width: 445px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/06/fisl_banner.png"><img class="size-full wp-image-542" title="fisl_banner" src="http://weblog.destaquenet.com/wp-content/uploads/2009/06/fisl_banner.png" alt="Banner  do evento" width="435" height="120" /></a><p class="wp-caption-text">Banner  do evento</p></div>
<p>Quando voltei do meu primeiro fórum, em 2007, prometi a mim mesmo que faria o possível para não perder as edições seguintes. Felizmente, essa promessa vem sendo cumprida à risca, já que este será meu terceiro fórum. E a empolgação, como não podia deixar de ser, já está começando a tomar conta!</p>
<p>Nos vemos lá!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/06/22/fisl-10-ai-vou-eu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Você gostaria de ver Django-flash incluído no Django como uma Contrib app?</title>
		<link>http://weblog.destaquenet.com/2009/06/19/voce-gostaria-de-ver-django-flash-incluido-no-django-como-uma-contrib-app/</link>
		<comments>http://weblog.destaquenet.com/2009/06/19/voce-gostaria-de-ver-django-flash-incluido-no-django-como-uma-contrib-app/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 15:14:46 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[contrib]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[django-flash]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[projeto]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=535</guid>
		<description><![CDATA[Django-flash, um despretencioso projeto de software livre desenvolvido pela Destaquenet, tem recebido excelentes críticas por quem o vem utilizando regularmente. Sua adoção vem crescendo vagarosamente, mas consistentemente. Nem preciso dizer o quanto isso é gratificante para nós.
De um tempo para cá, eu fui contactado por alguns desses usuários perguntando sobre a possibilidade de ter o [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://djangoflash.destaquenet.com">Django-flash</a>, um despretencioso projeto de <em>software</em> livre desenvolvido pela <a href="http://www.destaquenet.com">Destaquenet</a>, tem recebido excelentes críticas por quem o vem utilizando regularmente. Sua adoção vem crescendo vagarosamente, mas consistentemente. Nem preciso dizer o quanto isso é gratificante para nós.</p>
<p>De um tempo para cá, eu fui contactado por alguns desses usuários perguntando sobre a possibilidade de ter o nosso projeto incluído na distribuição do <a href="http://www.djangoproject.com/">Django</a>, na forma de uma <a href="http://docs.djangoproject.com/en/dev/ref/contrib/">Contrib app</a>. Eu achei a idéia excelente, pois eu penso que um <em>framework</em> como o Django deveria se preocupar em resolver um <a href="http://weblog.destaquenet.com/2009/02/06/mensagens-flash-a-la-rails-para-django-com-django-flash/">problema tão recorrente</a> quanto este que o Django-flash se propõe a resolver.</p>
<p>Se você utiliza Django-flash em seus projetos, não deixe de acompanhar <a href="http://code.djangoproject.com/ticket/4604">essa discussão</a>. Se possível, nos dê sua opinião sobre o que poderia ser feito para melhorar ainda mais o projeto e, assim, facilitar sua inclusão no Django.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/06/19/voce-gostaria-de-ver-django-flash-incluido-no-django-como-uma-contrib-app/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Programação Funcional: vale a pena aprender?</title>
		<link>http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/</link>
		<comments>http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 19:32:54 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[programação funcional]]></category>
		<category><![CDATA[project euler]]></category>
		<category><![CDATA[projeto]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=511</guid>
		<description><![CDATA[Antes de começar com Python, eu não conhecia praticamente nada sobre Programação Funcional. Para falar a verdade, eu até achava que os paradigmas Funcional e Procedural eram a mesma coisa pelo fato do segundo se basear em funções métodos (e várias pessoas com as quais eu convivo e trabalho também têm esse equívoco). Felizmente, tudo [...]]]></description>
			<content:encoded><![CDATA[<p>Antes de começar com <a href="http://python.org">Python</a>, eu não conhecia praticamente nada sobre <a href="http://en.wikipedia.org/wiki/Functional_programming">Programação Funcional</a>. Para falar a verdade, eu até achava que os paradigmas Funcional e <a href="http://en.wikipedia.org/wiki/Procedural_programming">Procedural</a> eram a mesma coisa pelo fato do segundo se basear em <span style="text-decoration: line-through;">funções</span> métodos (e várias pessoas com as quais eu convivo e trabalho também têm esse equívoco). Felizmente, tudo começou a fazer sentido quando aprendi, graças ao Python, coisas  como <a href="http://docs.python.org/library/functions.html#map"><code>map()</code></a>, <a href="http://docs.python.org/library/functions.html#reduce"><code>reduce()</code></a>, <a href="http://docs.python.org/library/functions.html#filter"><code>filter()</code></a>, <a href="http://docs.python.org/tutorial/classes.html#generators">generators</a> e <a href="http://docs.python.org/tutorial/datastructures.html#list-comprehensions">list comprehensions</a>.</p>
<p>Como o mercado é dominado por linguagens imperativas, é bem difícil encontrar pessoas que realmente conheçam e utilizem linguagens funcionais com certa regularidade. Mas isso não significa, de forma alguma, que não há espaço para tais linguagens. Na verdade, a tendência é que elas ganhem cada vez mais espaço.</p>
<p><span id="more-511"></span></p>
<h3>Por que aprender uma linguagem funcional?</h3>
<p>Em linguagens imperativas, a programação de um <em>software</em> consiste basicamente na definição e manipulação de seu estado interno, conduzida de modo a resolver um determinado problema. Portanto, pode-se dizer que <em>softwares</em> escritos em tais linguagens são movidos a <em>efeitos colaterais</em>, pois a forma e a ordem com que seu estado interno é modificado é o que define o funcionamento do <em>software</em>.</p>
<p>Em <em>softwares</em> triviais isso não chega a ser um problema, mas quando falamos de <em>softwares</em> grandes e complexos, essa volatilidade complica, e muito, a vida de quem os desenvolve e os mantém.</p>
<p>Linguagens funcionais, por outro lado, são conhecidas por evitar efeitos colaterais ao máximo, e isso nos trás uma infinidade de vantagens. Assim como na matemática, executar uma função <em>f(x)</em> com o mesmo argumento <em>N</em> vezes produz <em>sempre</em> o mesmo resultado, e por isso:</p>
<ol>
<li>o código fica muito mais fácil de entender, debugar e testar. Tudo o que você precisa saber sobre uma função está nos seus argumentos;</li>
<li>o código, por também contar com estruturas de dados imutáveis, pode ser executado de forma concorrente, com poucas ou quaisquer modificações, e você nunca terá de se preocupar com locks, <a href="http://en.wikipedia.org/wiki/Race_condition">condições de corrida</a>, <a href="http://en.wikipedia.org/wiki/Deadlock">deadlocks</a> e coisas do tipo;</li>
<li>o compilador pode fazer otimizações impossíveis de serem feitas em linguagens imperativas, como automaticamente paralelizar ou reordenar chamadas a funções;</li>
</ol>
<p>Enfim, esse é só um resumo das vantagens que linguagens funcionais têm sobre linguagens imperativas. Confira os links no final deste post para saber mais.</p>
<h3>Escolhendo a linguagem</h3>
<p>Clojure, Erlang, Haskell, J, (Common) Lisp, Scheme. E essas são somente algumas das linguagens com forte base funcional disponíveis por aí.</p>
<p>Mas qual delas escolher? Cada pessoa segue um ritual diferente ao escolher uma nova ferramenta e por isso não sou eu quem irá te dizer qual delas escolher. O que eu posso fazer é dar algumas sugestões:</p>
<ul>
<li>Quer saber como tudo começou? Aprenda <a href="http://en.wikipedia.org/wiki/Common_Lisp">Common Lisp</a>.</li>
<li>Quer uma linguagem parecida com Lisp, mas que rode na JVM? <a href="http://clojure.org/">Clojure</a> pode ser uma boa.</li>
<li>Quer uma linguagem com uma sintaxe sucinta e poderosa? Dê uma olhada em <a href="http://www.jsoftware.com/">J</a>.</li>
<li>Quer uma linguagem que facilite a construção de <em>softwares</em> distribuídos e de alta disponibilidade? Vá de <a href="http://www.erlang.org/">Erlang</a>.</li>
<li><strong>Quer uma linguagem que mude a forma com que você pensa sobre programação? Aprenda qualquer uma delas!</strong></li>
</ul>
<p>Erlang e Haskell estão na minha mira mas, no momento, eu optei por aprender Clojure.</p>
<h3>Praticar é essencial</h3>
<p>Ok, escolhida a linguagem de programação, o próximo passo é ler muito e praticar mais ainda.</p>
<p>Para quem está interessado em aprender Clojure, material não falta. Apesar de bem nova (apenas 2 anos de existência), a linguagem vem ganhando popularidade e muito vêm sendo escrito sobre ela. Aliás, <a href="http://www.pragprog.com/titles/shcloj/programming-clojure">o primeiro livro sobre Clojure</a> foi publicado recentemente pela <a href="http://pragprog.com/">Pragmatic Bookshelf</a>. (Pode comprar sem medo, o livro é excelente)</p>
<p>Agora, independente da linguagem escolhida, uma forma interessante de aplicar os conhecimentos recém-adquiridos é tentar resolver os problemas propostos pelo <a href="http://projecteuler.net/">Project Euler</a>, um website com centenas de problemas do tipo <a href="http://projecteuler.net/index.php?section=problems&amp;id=12">&#8220;What is the value of the first triangle number to have over five hundred divisors?&#8221;</a>. No começo eu sofri um pouco para pegar as manhas da linguagem, mas depois de ter resolvido uns 10-15 problemas desse tipo, eu sinto que as coisas estão começando a fazer sentido.</p>
<p>Aos interessados, eu acabei de disponibilizar no Github <a href="http://github.com/danielfm/euler-clojure/tree/master">um projeto</a> contendo as soluções, todas em Clojure, para alguns dos problemas propostos.</p>
<h3>E vocês, o que recomendam?</h3>
<p>Depois de algumas semanas pesquisando sobre Programação Funcional, eu me sinto como se tivesse deixado de lado um vício: meio assustador no início, mas melhor a cada dia que passa!</p>
<p>Aos que já conhecem ou trabalham regularmente com linguagens funcionais, que dica vocês dão para quem acabou de tomar a <a href="http://en.wikipedia.org/wiki/Redpill">pílula vermelha</a>?</p>
<h3>Referências</h3>
<ul>
<li><a href="http://www.paulgraham.com/onlisp.html">On Lisp Book</a> (Obrigatório!);</li>
<li><a href="http://www.defmacro.org/ramblings/fp.html">Functional Programming For The Rest Of Us</a> (Obrigatório!);</li>
<li><a href="http://www2.computer.org/portal/web/computingnow/0609/whatsnew/cise">The Promises Of Functional Programming</a> (Atualização);</li>
<li><a href="http://www.pragprog.com/titles/shcloj/programming-clojure">Programming Clojure</a>;</li>
<li><a href="http://java.ociweb.com/mark/clojure/article.html">Clojure &#8211; Functional Programming for the JVM</a>;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Era uma vez um patinho feio&#8230;&#8221;</title>
		<link>http://weblog.destaquenet.com/2009/06/03/era-uma-vez-um-patinho-feio/</link>
		<comments>http://weblog.destaquenet.com/2009/06/03/era-uma-vez-um-patinho-feio/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 23:44:31 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[idéia]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[linguagem de programação]]></category>
		<category><![CDATA[opinião]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=486</guid>
		<description><![CDATA[Eu me lembro como se fosse ontem. Quando comecei a desenvolver aplicações web, o JavaScript, apesar de ter seu uso &#8212; normalmente limitado a validações de formulários e joguinhos do tipo pergunta-e-resposta &#8212; não era algo que os desenvolvedores conheciam nos mínimos detalhes. Na verdade, ninguém parecia se importar em saber mais do que fazer [...]]]></description>
			<content:encoded><![CDATA[<p>Eu me lembro como se fosse ontem. Quando comecei a desenvolver aplicações web, o <a href="http://pt.wikipedia.org/wiki/JavaScript">JavaScript</a>, apesar de ter seu uso &#8212; normalmente limitado a validações de formulários e joguinhos do tipo pergunta-e-resposta &#8212; não era algo que os desenvolvedores conheciam nos mínimos detalhes. Na verdade, ninguém parecia se importar em saber mais do que fazer uns testes <code>if</code>/<code>else</code> e mostrar um <code>alert</code> na tela. Eu inclusive.</p>
<p>Alguns anos se passaram e a coisa ficou bem diferente. Conhecer JavaScript e suas peculiaridades é requisito obrigatório. Qualquer aplicação decente utiliza a linguagem em partes importantes do seu código, bibliotecas para as mais variadas funções são criadas a cada dia, as engines estão cada vez mais velozes. Isso tem que significar alguma coisa.</p>
<p>Teria o JavaScript deixado de ser uma linguagem de script e se tornado uma&#8230; <em>plataforma</em>?</p>
<p>Claro que o JavaScript tem problemas. Nada é perfeito. Só que antes de dizer que a linguagem é ruim, ou que não é tão &#8220;sexy&#8221; como <a href="http://www.ruby-lang.org/">Ruby</a> (ui!), muitos esquecem que JavaScript é a linguagem (plataforma?) que dispõe da <em>maior</em> base de potenciais usuários. Maior até que <a href="http://en.wikipedia.org/wiki/ActionScript">ActionScript</a>/Flash.</p>
<p>Se formos parar para pensar, isso nem é assim tão surpreendente: a única coisa que, por enquanto, impede que um usuário rode uma aplicação escrita em JavaScript é a ausência de um browser. Tirando os servidores, quais as chances de um computador não possuir um browser instalado? Praticamente zero, eu diria. E o mesmo vale para os smartphones, netbooks e outros dispositivos.</p>
<p>Por isso, aos que gostam de profetizar sobre qual será a próxima grande linguagem, fica a lição de que não existe uma bola de cristal que funcione. Afinal, ninguém imaginava que JavaScript, o então ex-patinho feio nascido em 1995, viria a chegar onde chegou.</p>
<p>E o melhor ainda está por vir.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/06/03/era-uma-vez-um-patinho-feio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Livro grátis: &#8220;Python para Desenvolvedores&#8221;!</title>
		<link>http://weblog.destaquenet.com/2009/06/01/livro-gratis-python-para-desenvolvedores/</link>
		<comments>http://weblog.destaquenet.com/2009/06/01/livro-gratis-python-para-desenvolvedores/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 22:24:46 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[errata]]></category>
		<category><![CDATA[livro]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=471</guid>
		<description><![CDATA[Há alguns dias atrás fui informado do lançamento (sob licença CC) de um livro sobre Python chamado Python para Desenvolvedores. Para quem não conhece Python, ou ainda está iniciando nessa excepcional linguagem, trata-se de um excelente recurso de aprendizado, apresentando uma infinidade de exemplos e mostrando, na prática, um pouco do que pode ser feito [...]]]></description>
			<content:encoded><![CDATA[<p>Há alguns dias atrás fui informado do lançamento (sob licença <a href="http://creativecommons.org/licenses/by-nc-sa/2.5/br/">CC</a>) de um livro sobre <a href="http://www.python.org/">Python</a> chamado <a href="http://ark4n.wordpress.com/python/">Python para Desenvolvedores</a>. Para quem não conhece Python, ou ainda está iniciando nessa excepcional linguagem, trata-se de um excelente recurso de aprendizado, apresentando uma infinidade de exemplos e mostrando, na prática, um pouco do que pode ser feito com ela. Congratulações ao autor, Luiz Eduardo Borges!</p>
<p>Não deixe de <a href="http://ark4n.wordpress.com/python/">baixar o livro</a> e, claro, aprender Python. O único problema é que você provavelmente <a href="http://www.ubermonkey.net/blog/2008/02/25">não irá querer olhar para trás</a>&#8230;</p>
<p><span id="more-471"></span></p>
<h3>Errata</h3>
<p>O livro ainda é bem novo, por isso é meio óbvio que existem ajustes a serem feitos. Por isso, para ajudar a tornar o livro ainda melhor, eu resolvi dar a minha humilde contribuição.</p>
<p>Como infelizmente eu não consegui contato com o autor do livro, resolvi publicar aqui os erros que eu encontrei no mesmo.</p>
<h4>Página 21</h4>
<p>Creio que a explicação dos operadores lógicos <code>and</code> e <code>or</code> está simples demais, considerando que o público-alvo do livro é de desenvolvedores, ou seja, pessoas com um pouco mais de experiência na área. Trecho:</p>
<blockquote><p>and: retorna verdadeiro se e somente se receber duas expressões que forem verdadeiras.</p></blockquote>
<p>Na verdade, o operador <code>and</code> não retorna <em>verdadeiro</em> ou <em>falso</em>. Se ambos os operandos são valores considerados verdadeiros, ele retorna o último operando avaliado. Do contrário, ele retorna o primeiro operando considerado falso:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">''</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">True</span> <span style="color: #808080; font-style: italic;"># Retorna: ''</span>
<span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #483d8b;">''</span>    <span style="color: #808080; font-style: italic;"># Retorna: 0</span>
<span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">True</span>  <span style="color: #808080; font-style: italic;"># Retorna: True</span>
<span style="color: #008000;">True</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #ff4500;">1</span>  <span style="color: #808080; font-style: italic;"># Retorna: 1</span></pre></div></div>

<p>A mesma idéia vale para o operador <code>or</code>. Trecho:</p>
<blockquote><p>or: retorna falso se e somente se receber duas expressões que forem falsas.</p></blockquote>
<p>Este operador também não retorna valores literais de <em>verdadeiro</em> ou <em>falso</em>, e sim o primeiro operando considerado verdadeiro ou o último considerado falso se não existirem operandos verdadeiros:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">False</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #483d8b;">&quot;&quot;</span> <span style="color: #808080; font-style: italic;"># Retorna: ''</span>
<span style="color: #008000;">True</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #ff4500;">1</span>   <span style="color: #808080; font-style: italic;"># Retorna: True</span>
<span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #ff4500;">1</span>      <span style="color: #808080; font-style: italic;"># Retorna: 1</span>
<span style="color: #008000;">False</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># Retorna: []</span></pre></div></div>

<p>Na minha opinião, desenvolvedores Python <strong>devem</strong> saber que os operadores <code>and</code> e <code>or</code> têm essas propriedades. Isso até ajuda a deixar os códigos mais &#8220;pythonicos&#8221;. Um exemplo (idiota, mas enfim) seria:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># Versão não muito pythonica</span>
<span style="color: #ff7700;font-weight:bold;">def</span> not_so_good<span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
    params = kwargs
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> kwargs:
        params = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'default'</span>: <span style="color: #ff4500;">1234</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> params
&nbsp;
not_so_good<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>         <span style="color: #808080; font-style: italic;"># Imprime: {'default': 1234}</span>
not_so_good<span style="color: black;">&#40;</span>a=<span style="color: #ff4500;">1</span>, b=<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Imprime: {'a': 1, 'b': 2}</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Versão um pouco melhor</span>
<span style="color: #ff7700;font-weight:bold;">def</span> good<span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
    params = kwargs <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'default'</span>: <span style="color: #ff4500;">1234</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> params
&nbsp;
good<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>         <span style="color: #808080; font-style: italic;"># Imprime: {'default': 1234}</span>
good<span style="color: black;">&#40;</span>a=<span style="color: #ff4500;">1</span>, b=<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Imprime: {'a': 1, 'b': 2}</span></pre></div></div>

<h4>Páginas 27, 30, 75, 131, 140</h4>
<p>Em vários lugares o autor diz que X é mais eficiente que Y, mas não especifica em que especificamente essa eficiência se traduz: menor consumo de memória, processamento mais rápido, coisas do tipo. Seria legal saber em que exatamente X é mais eficiente que Y.</p>
<h4>Página 39</h4>
<p>No 7o item da lista, faltou um espaço após a vírgula.</p>
<h4>Página 92</h4>
<p>Trecho:</p>
<blockquote><p>Na herança múltipla, a nova classe deriva de várias classes já existentes. A diferença mais significativa em relação à herança simples é a ordem de resolução de métodos (em inglês, Method Resolution Order- MRO), que segue o chamado algoritmo diamante. No algoritmo diamante, a resolução será feita a partir da esquerda, descendo até encontrar a classe em comum entre os caminhos dentro hierarquia. Quando encontra a classe em comum, passa para o caminho à direita. Ao esgotar os caminhos, o algoritmo prossegue para a classe em comum e repete o processo.</p></blockquote>
<p>A herança múltipla funciona de forma diferente em <em>classes clássicas</em> e <em>classes de estilo novo</em>. A &#8220;resolução diamante&#8221;, onde a pesquisa de herança é estritamente profunda primeiro, depois da esquerda para direita, é usada somente em <em>classes clássicas</em>. Nas <em>classes de estilo novo</em>, a pesquisa de herança é feita da esquerda para direita primeiro, depois em profundidade:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># Hierarquia de &quot;classes clássicas&quot;</span>
<span style="color: #ff7700;font-weight:bold;">class</span> A: attr = <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">class</span> B<span style="color: black;">&#40;</span>A<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">pass</span>
<span style="color: #ff7700;font-weight:bold;">class</span> C<span style="color: black;">&#40;</span>A<span style="color: black;">&#41;</span>: attr = <span style="color: #ff4500;">2</span>
<span style="color: #ff7700;font-weight:bold;">class</span> D<span style="color: black;">&#40;</span>B, C<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
d = D<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
d.<span style="color: black;">attr</span> <span style="color: #808080; font-style: italic;"># Retorna: 1</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Hierarquia de &quot;classes de estilo novo&quot;</span>
<span style="color: #ff7700;font-weight:bold;">class</span> A<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>: attr = <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">class</span> B<span style="color: black;">&#40;</span>A<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">pass</span>
<span style="color: #ff7700;font-weight:bold;">class</span> C<span style="color: black;">&#40;</span>A<span style="color: black;">&#41;</span>: attr = <span style="color: #ff4500;">2</span>
<span style="color: #ff7700;font-weight:bold;">class</span> D<span style="color: black;">&#40;</span>B, C<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
d = D<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
d.<span style="color: black;">attr</span> <span style="color: #808080; font-style: italic;"># Retorna: 2</span></pre></div></div>

<p>O código mostra claramente que, dependendo do tipo de classe (<em>clássica</em> ou <em>de estilo novo</em>), a resolução do atributo <code>attr</code> é feita de forma diferenciada.</p>
<p>Bom, por enquanto é isso! Espero que o autor leve esses pontos em consideração para fazer do livro <a href="http://ark4n.wordpress.com/python/">Python para Desenvolvedores</a> um livro ainda melhor!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/06/01/livro-gratis-python-para-desenvolvedores/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django e settings.py: dicas e boas práticas</title>
		<link>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/</link>
		<comments>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 02:32:06 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[configuração]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=415</guid>
		<description><![CDATA[Em vez de ficar rasgando elogios ao Django, como de costume, eu tentarei aproveitar o melhor o meu (e o seu) tempo e mostrar algo que é de fato útil. O assunto em questão envolve o módulo settings.py, cuja função é fornecer as configurações necessárias para que o projeto funcione. Apesar deste módulo ser uma [...]]]></description>
			<content:encoded><![CDATA[<p>Em vez de ficar rasgando elogios ao <a href="http://djangoproject.com">Django</a>, como de costume, eu tentarei aproveitar o melhor o meu (e o seu) tempo e mostrar algo que é de fato útil. O assunto em questão envolve o módulo <code>settings.py</code>, cuja função é fornecer as configurações necessárias para que o projeto funcione. Apesar deste módulo ser uma peça importante em qualquer projeto Django, pouco se fala sobre ele, ou sobre boas práticas associadas a ele. Por isso, achei que seria interessante mostrar a minha visão pessoal sobre o assunto.</p>
<h3>O poder do Python</h3>
<p>Quem não está acostumado a trabalhar com Django pode estranhar o fato deste utilizar um script <a href="http://python.org">Python</a> para fazer a configuração do projeto: o famoso <code>settings.py</code>. E essa estranheza é justificada, afinal muitos desenvolvedores &#8212; principalmente os que vêm de outras linguagens &#8212; estão acostumados a trabalhar com ferramentas onde tal tarefa é feita com arquivos XML ou coisa assim.</p>
<p>O fato é que utilizar um script Python para tal é uma excelente idéia, pois você deixa de depender de algum tipo de estrutura estática (e muitas vezes inconveniente) para algo mais flexível e poderoso, que, no caso, é a própria linguagem de programação. Isso faz uma grande diferença em situações onde tal flexibilidade é necessária.</p>
<p>Quer exemplos?<span id="more-415"></span></p>
<h3>Ambientes de desenvolvimento/produção</h3>
<p>Eis como fizemos aqui. Primeiramente, defina a variável de ambiente <code>WORKSPACE</code>. No Linux, isso pode ser feito através do arquivo <code>~/.bashrc</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">WORKSPACE</span>=<span style="color: #000000;">1</span></pre></div></div>

<p>A idéia é possibilitar a criação de perfis de configuração, cada qual correspondente a um ambiente de execução. A existência ou não da variável de ambiente é o que define o ambiente no qual a aplicação roda.</p>
<p>Continuando com o exemplo, no diretório raíz do seu projeto Django, crie o módulo <code>environment.py</code>, com o seguinte conteúdo:</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;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff7700;font-weight:bold;">not</span> development_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> development_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'WORKSPACE'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span></pre></div></div>

<p>Finalmente, modifique o módulo <code>settings.py</code> para que este utilize tais métodos onde for necessário definir configurações diferentes para ambientes de execução diferentes:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> environment <span style="color: #ff7700;font-weight:bold;">import</span> production_mode
&nbsp;
<span style="color: #808080; font-style: italic;"># Configurações padrão</span>
PREPEND_WWW = <span style="color: #008000;">False</span>
DEBUG = <span style="color: #008000;">True</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Configurações para ambiente de produção</span>
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    PREPEND_WWW = <span style="color: #008000;">True</span>
    DEBUG = <span style="color: #008000;">False</span>
&nbsp;
MIDDLEWARE_CLASSES = <span style="color: black;">&#40;</span>
    <span style="color: #483d8b;">'django.middleware.common.CommonMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.sessions.middleware.SessionMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.auth.middleware.AuthenticationMiddleware'</span>,
    <span style="color: #483d8b;">'django.middleware.doc.XViewMiddleware'</span>,
    <span style="color: #483d8b;">'pages.middleware.PageFallbackMiddleware'</span>,
    <span style="color: #483d8b;">'django.contrib.redirects.middleware.RedirectFallbackMiddleware'</span>,
<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Habilitando caching em modo de produção</span>
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    MIDDLEWARE_CLASSES += <span style="color: black;">&#40;</span>
        <span style="color: #483d8b;">'django.middleware.cache.UpdateCacheMiddleware'</span>,
        <span style="color: #483d8b;">'django.middleware.cache.FetchFromCacheMiddleware'</span>,
    <span style="color: black;">&#41;</span></pre></div></div>

<p>Não tenha medo de utilizar os recursos do Python onde eles se fizerem necessários, apenas tomando cuidado para não exagerar e acabar criando acidentalmente um <a href="http://en.wikipedia.org/wiki/Genetic_algorithm">Algoritmo Genético</a> para configurar seu projeto!</p>
<h3>Informações secretas (IPs, usernames, passwords, etc)</h3>
<p>Praticamente não há quem ignore a importância de um bom sistema de controle de revisões (<a href="http://subversion.tigris.org">Subversion</a>, <a href="http://git-scm.org">Git</a>, etc). O problema é que, muitas vezes, não tomamos o devido cuidado com o que colocamos dentro dos nossos repositórios. Sempre que possível, informações secretas &#8212; como endereços de IP, usernames e passwords &#8212; devem ser mantidas fora dos repositórios.</p>
<p>Em um projeto Django, as informações de acesso a servidores de e-mail e bancos de dados devem estar disponíveis através do módulo  <code>settings.py</code>. Felizmente, existe um jeito simples de manter essas informações separadas das outras configurações.</p>
<p>Primeiramente, abra o arquivo <code>settings.py</code> do seu projeto e remova todas as senhas e outras informações que você considere secretas. Em seguida, cole o seguinte trecho de código no final do arquivo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> private <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

<p>Feito isso, crie o módulo <code>private.py</code> no diretório raíz do seu projeto Django. Coloque nele as configurações que você removeu do <code>settings.py</code> no passo anterior. Exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> environment <span style="color: #ff7700;font-weight:bold;">import</span> production_mode
&nbsp;
SECRET_KEY = <span style="color: #483d8b;">'secret_key_do_seu_projeto'</span>
&nbsp;
EMAIL_HOST = <span style="color: #483d8b;">'localhost'</span>
EMAIL_HOST_PASSWORD = <span style="color: #483d8b;">'senha_email_local'</span>
&nbsp;
DATABASE_HOST = <span style="color: #483d8b;">'localhost'</span>
DATABASE_USER = <span style="color: #483d8b;">'username_db_local'</span>
DATABASE_PASSWORD = <span style="color: #483d8b;">'senha_db_local'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> production_mode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    EMAIL_HOST = <span style="color: #483d8b;">'ip_email_producao'</span>
    EMAIL_HOST_PASSWORD = <span style="color: #483d8b;">'senha_email_producao'</span>
&nbsp;
    DATABASE_HOST = <span style="color: #483d8b;">'ip_db_producao'</span>
    DATABSE_USER = <span style="color: #483d8b;">'username_db_producao'</span>
    DATABASE_PASSWORD = <span style="color: #483d8b;">'senha_db_producao'</span></pre></div></div>

<p>Certifique-se de adicionar o arquivo <code>private.py</code> no <em>ignore</em> (<code>.cvsignore</code> para <a href="http://www.nongnu.org/cvs/">CVS</a>, <code>.gitignore</code> para Git, etc) correspondente ao sistema de controle de revisões sendo utilizado. Faça o commit e pronto.</p>
<p>Para finalizar, se o seu repositório já contém uma versão &#8220;insegura&#8221; do módulo <code>settings.py</code>, mude as senhas dos seus servidores.</p>
<h3>E você, o que recomenda?</h3>
<p>Tem alguma dica útil para compartilhar conosco? Nós adoraríamos ouvir o que você tem a dizer!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/04/13/django-e-settingspy-dicas-e-boas-praticas/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Firefox: &#8220;A memória é minha e ninguém tasca!&#8221;</title>
		<link>http://weblog.destaquenet.com/2009/03/25/firefox-a-memoria-e-minha-e-ninguem-tasca/</link>
		<comments>http://weblog.destaquenet.com/2009/03/25/firefox-a-memoria-e-minha-e-ninguem-tasca/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 14:09:16 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[memória]]></category>
		<category><![CDATA[navegador]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=409</guid>
		<description><![CDATA[O Firefox gosta tanto da memória RAM que tenta pegar tudo para si! Exagero? Bem, eu sempre soube que o Firefox é um guloso consumidor de memória, mas hoje eu fiquei espantado em constatar que a situação é ainda pior do que eu pensava. Veja por si só:
Medo.
]]></description>
			<content:encoded><![CDATA[<p>O <a href="www.mozilla.com/firefox/">Firefox</a> gosta tanto da memória RAM que tenta pegar tudo para si! Exagero? Bem, eu sempre soube que o Firefox é um guloso consumidor de memória, mas hoje eu fiquei espantado em constatar que a situação é ainda pior do que eu pensava. Veja por si só:</p>
<div id="attachment_410" class="wp-caption aligncenter" style="width: 267px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/03/sysmonitor.png"><img class="size-medium wp-image-410" title="System monitor - Firefox" src="http://weblog.destaquenet.com/wp-content/uploads/2009/03/sysmonitor-257x300.png" alt="Consumo de memória do Firefox 3.0.7" width="257" height="300" /></a><p class="wp-caption-text">Consumo de memória do Firefox 3.0.7</p></div>
<p>Medo.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/03/25/firefox-a-memoria-e-minha-e-ninguem-tasca/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.680 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2009-07-02 23:31:16 -->
<!-- Compression = gzip -->