<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Simples Ideias. Por Nando Vieira.</title>
	
	<link>http://simplesideias.com.br</link>
	<description />
	<lastBuildDate>Tue, 07 Feb 2012 18:54:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/simplesideias" /><feedburner:info uri="simplesideias" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>simplesideias</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Configurando Ruby, Rails, MySQL e Git no Windows</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/P6an7p_--l4/</link>
		<comments>http://simplesideias.com.br/configurando-ruby-rails-mysql-e-git-no-windows/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 18:54:42 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=743</guid>
		<description><![CDATA[Configurar o ambiente de desenvolvimento no Windows não é tarefa das mais fáceis. Embora exista o RubyInstaller e o RailsInstaller, existem muitos detalhes que não são tão simples para quem está começando. Um outro problema é que o RailsInstaller não vem com o MySQL instalado, o que não adianta muito e, por isso, vamos configurar [...]]]></description>
			<content:encoded><![CDATA[<p>Configurar o ambiente de desenvolvimento no Windows não é tarefa das mais fáceis.
Embora exista o <a rel="external" href="http://rubyinstaller.org">RubyInstaller</a> e o <a rel="external"  href="http://railsinstaller.org">RailsInstaller</a>,
existem muitos detalhes que não são tão simples para quem está começando. Um outro problema é que o RailsInstaller não vem com o MySQL instalado, o que não adianta muito e, por isso, vamos configurar manualmente.</p>

<p>Neste artigo, você verá um passo-a-passo de como instalar e configurar o ambiente de desenvolvimento no Windows com Ruby 1.9.3-p0 e Rails 3.2.1, MySQL e Git.</p>

<h3>Instalando o Ruby</h3>

<p>O primeiro passo é instalar o Ruby. Isso pode ser feito com o <a rel="external"  href="http://rubyinstaller.org">RubyInstaller</a>, mantido pelo <a rel="external" href="http://blog.mmediasys.com/">Luis Lavena</a>. Faça o download do instalador Ruby 1.9.3-p0.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/ruby-installer-site.png" alt="Página de download do RubyInstaller"></p>

<p>Assim que o download for concluído, execute-o para iniciar a instalação. Siga os passos apresentados pelo instalador e não deixe de marcar a opção &#034;Add Ruby executables to your PATH&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/ruby-installer-configuration.png" alt="Configuração do RubyInstaller"></p>

<p>O Ruby já está instalado. Para se certificar de que ele está funcionando, abra o seu terminal. Para isso, digite &#034;powershell&#034; no menu Windows e execute o programa &#034;Windows PowerShell&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/windows-7-menu.png" alt="Executando o PowerShell"></p>

<p>No terminal, digite o comando <code>ruby -v</code>. Isso deverá exibir a versão instalada do Ruby.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/ruby-version.png" alt="Versão do Ruby"></p>

<p>Nós também iremos precisar do Ruby DevKit, um instalador disponibilizado no próprio site do RubyInstaller e que permitirá instalar extensões nativas como <a rel="external" href="http://rubygems.org/gems/json">json</a> e <a href="http://rubygems.org/gems/mysql2">mysql2</a>. Na <a rel="external" href="http://rubyinstaller.org/downloads">página de downloads</a> do Ruby Installer, faça o download do arquivo <code>DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe</code>.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/ruby-devkit.png" alt="Download do Ruby DevKit"></p>

<p>Assim que o download for concluído, você precisará extrair os arquivos para o diretório <code>C:\Ruby193\devkit</code>. Esse diretório não existe, então você precisará criá-lo.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/ruby-devkit-extract.png" alt="Extraindo os arquivos do Ruby DevKit"></p>

<p>Agora, volte ao terminal. Você precisará instalar o DevKit na instalação atual do Ruby. Para isso, digite o comando <code>cd C:\Ruby193\devkit</code> para ir ao diretório que você acabou de extrair. Execute o comando <code>ruby dk.rb init</code> e depois <code>ruby dk.rb install</code>.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/ruby-devkit-install.png" alt="Instalando o Ruby DevKit"></p>

<p>Pronto! Agora o seu Ruby já está instalado!</p>

<h3>Instalando o MySQL</h3>

<p>Antes de instalar o Rails, você precisará instalar e configurar o MySQL. Para fazer isso, acesse a <a rel="external" href="http://mysql.com/downloads/mysql/">página de downloads</a> e baixe o instalador. Assim que o download for concluído, inicie a instalação.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-installer.png" alt="Instalador do MySQL"></p>

<p>Quando for perguntado sobre o tipo de instalação, escolha &#034;Complete&#034;. Clique em &#034;Install&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-setup-type.png" alt="Definindo o tipo de instalação"></p>

<p>Assim que a instalação finalizar, marque a opção &#034;Launch the MySQL Instance Configuration Wizard&#034; para iniciar o assistente de configuração. Clique em &#034;Finish&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-finish-installation.png" alt="Tela final do instalador do MySQL"></p>

<p>No assistente de configuração, selecione a opção &#034;Detailed Configuration&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-configuration-type.png" alt="Definindo o tipo de configuração do MySQL"></p>

<p>Defina o tipo de servidor como &#034;Developer Machine&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-server-type.png" alt="Definindo o tipo de servidor"></p>

<p>Selecione a opção &#034;Multifunctional Database&#034;, que permite criar bancos de dados do tipo InnoDB e MyISAM.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-engine.png" alt="Definindo o tipo de engine"></p>

<p>O próximo passo permite definir onde os bancos de dados serão criados. Nós iremos definir um diretório diferente do padrão. Assim, quando uma nova atualização do MySQL for lançada, não perderemos os dados armazenados até então. No dropdown onde está escrito &#034;Instalation Path&#034;, escolha o diretório &#034;\Data&#34;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-data-directory.png" alt="Definindo o diretório onde os bancos de dados serão criados"></p>

<p>Agora você precisa escolher quantas conexões concorrentes você espera. Escolha a opção &#034;Decision Support (DSS)/OLAP&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-connections.png" alt="Definindo a quantidade de conexões simultâneas"></p>

<p>Marque as opções &#034;Enable TCP/IP Networking&#034; e &#034;Enable Strict Mode&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-network.png" alt="Configurações de rede"></p>

<p>Você também pode definir qual o tipo de codificação de caracteres padrão. Escolha a opção &#034;Best Support For Multilingualism&#034;, que irá definir o UTF-8 como o tipo padrão.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-encoding.png" alt="Codificação padrão dos bancos de dados"></p>

<p>Para iniciar o MySQL automaticamente quando o Windows é iniciado, marque a opção &#034;Install As A Windows Service&#034;. Não deixe de marcar a opção &#034;Include Bin Directory in Windows PATH&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-windows-options.png" alt="Configurações de serviço do Windows"></p>

<p>Como estamos executando o MySQL em modo de desenvolvimento, você pode desmarcar a opção &#034;Modify Security Settings&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-security.png" alt="Desabilitando as configurações de segurança"></p>

<p>Agora, clique em &#034;Next&#034; e depois &#034;Execute&#034; para aplicar as configurações que acabamos de definir.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-finish.png" alt="Finalizando a instalação"></p>

<p>Pronto! Para saber se o MySQL foi corretamente instalado, abra uma nova janela do terminal e execute o comando <code>mysql --version</code>. Você deverá ver a versão do MySQL instalado.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/mysql-version.png" alt="Versão instalada do MySQL"></p>

<p>Nós ainda precisaremos configurar o Ruby com suporte ao MySQL. Para fazer isso, acesse a página de downloads do MySQL e clique no link <a rel="external" href="http://mysql.com/downloads/connector/">MySQL Connectors</a>. Você precisará da versão &#034;Connector/C (libmysql)&#034;. Na página de download, escolha a opção sem o instalador. Escolha a versão de 32-bits. Isso é necessário porque o Ruby é 32-bits e, mesmo que a instalação do MySQL tenha sido feita em 64-bits, o conector que será usado por ele deve ter a mesma arquitetura.</p>

<p>Extraia os arquivos e copie o arquivo <code>mysql-connector-c-noinstall-6.0.2-win32/lib/libmysql.dll</code> para o diretório <code>C:\Ruby193\bin</code>. Isso é necessário pois DLLs precisam estar no PATH do Windows e, o diretório <code>bin</code> do Ruby no Windows adiciona todas as dependências lá.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/libmysql.png" alt="Movendo o conector C para o diretório do Ruby"></p>

<p>Se tudo deu certo, você conseguirá usar a gem <a href="http://rubygems.org/gems/mysql2">mysql2</a> no Windows.</p>

<h3>Instalando o Ruby on Rails</h3>

<p>Agora que já temos o Ruby e o MySQL devidamente configurados, podemos instalar o <a rel="external" href="http://rubyonrails.com">Ruby on Rails</a>. Antes, vamos fazer uma pequena configuração para desabilitar a geração de documentação toda vez que uma gem for instalada. Isso não é obrigatório, mas você verá que o tempo usado para gerar a documentação é um tanto quanto longo.</p>

<p>No Windows, o arquivo de configuração do RubyGems deve ser criado em <code>C:\ProgramData\gemrc</code>. O diretório <code>C:\ProgramData</code> não é exibido por padrão, então você precisará modificar suas configurações do Windows para exibir os arquivos e diretórios ocultos.</p>

<p>Com o seu editor de textos preferido, crie o arquivo <code>C:\ProgramData\gemrc</code> com o conteúdo à seguir.</p>

<pre><code>gem: "--no-rdoc --no-ri"</code></pre>

<p>Agora volte ao seu terminal e digite o comando <code>gem install rails</code>. Isso demorar um pouco pois o Rails irá instalar todas as suas dependências.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/rails-install.png" alt="Instalando o Ruby on Rails"></p>

<p>O próximo passo é criar um novo app do Rails. Para isso, execute o comando <code>rails new hello -d mysql</code>. Por padrão, o Rails irá usar o SQLite; por isso passamos o argumento <code>-d mysql</code>.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/rails-app.png" alt="Gerando um novo app com o Ruby on Rails"></p>

<p>Se tudo der certo, seu app foi gerado e as dependências instaladas.</p>

<h3>Instalando o Git</h3>

<p>Já estamos quase no fim! Agora, vamos instalar o Git. O Git é um sistema de versionamento de arquivos que vem sendo cada vez mais utilizado. Se você ainda não conhece sobre Git, fique ligado no workshop <a rel="external" href="http://howtocode.com.br/workshops/git">Git no dia-a-dia</a>, que eu dou no <a href="http://howtocode.com.br/?simplesideias">HOWTO</a>. Veja também o screencast <a rel="external" href="http://akitaonrails.com/2010/08/17/screencast-comecando-com-git">Começando com Git</a>, publicado pelo Fabio Akita.</p>

<p>Uma das alternativas para se usar Git no Windows é usar o <a rel="external" href="http://code.google.com/p/msysgit/">msysGit</a>. Faça o download do instalador. Neste exemplo, irei utilizar a versão <code>Git-1.7.9-preview20120201.exe</code>.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/git-installer.png" alt="Instalador do Git"></p>

<p>Você terá três opções de instalação. Selecione &#034;Run Git from the Windows Command Prompt&#034;.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/git-windows-options.png" alt="Configurações do Git"></p>

<p>A próxima opção do instalador é o tipo de conversão de quebras de linha que deve ser utilizado. A menos que você saiba o que está fazendo, selecione a opção &#034;Checkout as-is, commit as-is&#034; para manter o tipo de quebra de linha presente no arquivo, sem fazer nenhuma conversão automática.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/git-line-ending.png" alt="Definindo o comportamento do Git"></p>

<p>Depois que a instalação for finalizada, inicie uma nova janela do terminal. Execute o comando <code>git --version</code> para saber qual a versão instalada.</p>

<p><img src="http://m.simplesideias.com.br/ruby-win/git-version.png" alt="Versão instalada do Git"></p>
<img src="http://feeds.feedburner.com/~r/simplesideias/~4/P6an7p_--l4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/configurando-ruby-rails-mysql-e-git-no-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/configurando-ruby-rails-mysql-e-git-no-windows/</feedburner:origLink></item>
		<item>
		<title>Programando em ActionScript sem o Flash</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/DhVBfc1gIxk/</link>
		<comments>http://simplesideias.com.br/programando-em-actionscript-sem-o-flash/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 12:50:17 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[ActionScript]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=732</guid>
		<description><![CDATA[Estou refazendo a parte que faz o broadcasting de áudio e vídeo do Presentta, mas abrir o Flash e re-exportar o código-fonte para compilar o SWF estava se tornando um processo extremamente chato e demorado. Eu já tinha usado o SDK do Flex para compilar ActionScript em SWF antes. A grande vantagem é que eu [...]]]></description>
			<content:encoded><![CDATA[<p>Estou refazendo a parte que faz o broadcasting de
áudio e vídeo do Presentta, mas abrir
o Flash e re-exportar o código-fonte para compilar o SWF
estava se tornando um processo extremamente chato e demorado.</p>

<p>Eu já tinha usado o SDK do Flex para compilar ActionScript em SWF
antes. A grande vantagem é que eu posso usar apenas a linha de comando
para gerar os arquivos. Nada de uma IDE extramente lenta, como
a do Flash. Além disso, ainda posso usar o <a rel="external" href="http://rubygems.org/gems/guard">Guard</a> para compilar
automaticamente sempre que um arquivo for modificado.</p>

<h3>Instalando o Flex SDK no Mac OS X</h3>

<p>A instalação do SDK é bastante simples. Após fazer o
<a rel="external" href="http://fpdownload.adobe.com/pub/flex/sdk/builds/flex4.6/flex_sdk_4.6.0.23201_mpl.zip">download do SDK</a>,
que tem por volta de 164MB, você precisa extrair os arquivos.</p>

<pre><code>$ mkdir -p ~/local/flex
$ cd ~/local/flex
$ curl -O http://fpdownload.adobe.com/pub/flex/sdk/builds/flex4.6/flex_sdk_4.6.0.23201_mpl.zip
$ unzip flex_sdk_4.6.0.23201_mpl.zip
</code></pre>

<p>Agora, você precisa adicionar o diretório <code>~/local/flex/bin</code> ao
seu <code>$PATH</code>. Para isso, basta adicionar a linha abaixo ao arquivo
<code>~/.bash_profile</code> ou equivalente.</p>

<pre><code>$ echo 'export PATH="$HOME/local/flex/bin:$PATH"' &gt;&gt; ~/.bash_profile
</code></pre>

<p>Recarregue suas configurações com o comando <code>source ~/.bash_profile</code>. Se
tudo der certo, o comando <code>which mxmlc</code> está disponível.</p>

<pre><code>$ which mxmlc
/Users/fnando/local/flex/bin/mxmlc
</code></pre>

<h3>Compilando seu primeiro SWF</h3>

<p>Diferente do que você está acostumado, para criar SWFs você usará apenas
código ActionScript. Nada de IDE. E isso é uma coisa boa! Crie um arquivo
chamado <code>Main.as</code>. Esse arquivo será o arquivo principal, que será
equivalente ao stage principal do Flash.</p>

<pre class="actionscript"><code>package <span class="br0">&#123;</span>
  <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">Sprite</span>;
&nbsp;
  <span class="kw3">public</span> <span class="kw2">class</span> Main <span class="kw3">extends</span> Sprite <span class="br0">&#123;</span>
    <span class="kw3">public</span> <span class="kw2">function</span> Main<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="kw3">trace</span><span class="br0">&#40;</span><span class="st0">&quot;It works!&quot;</span><span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></code></pre>

<p>Note que o nome do arquivo deve ser igual ao nome da classe, nesse caso, <code>Main</code>.
Para compilar o arquivo <code>Main.as</code> você terá que executar o comando <code>mxmlc</code>.</p>

<pre><code>$ mxmlc -output main.swf \
      -as3 \
      -static-link-runtime-shared-libraries \
      -default-size 130 50 \
      -optimize \
      -verbose-stacktraces \
      Main.as
Loading configuration file /Users/fnando/local/flex/frameworks/flex-config.xml
/private/tmp/main.swf (592 bytes)
</code></pre>

<p>Nada muito complicado. Estamos gerando o arquivo <code>main.swf</code> à partir do
arquivo <code>Main.as</code>. O tamanho do stage será de <code>130x50</code>. É óbvio que esse exemplo,
não faz muita coisa. Se você abrir este arquivo no navegador será presenteado com
uma bela tela branca que não faz nada!</p>

<p>Para visualizar uma descrição dos parâmetros aceitos pelo comando <code>mxmlc</code>, execute
o comando abaixo.</p>

<pre><code>$ mxmlc -help details list
</code></pre>

<h3>Usando componentes</h3>

<p>Um dos problemas que tive com a compilação foi que componentes não estavam sendo renderizados.
O único modo que funcionou para mim foi exportar todos os componentes como uma biblioteca
compartilhada. Como você precisa do Flash para fazer isso, resolvi disponibilizar este arquivo em <a rel="external" href="http://f.simplesideias.com.br/components.swc">http://f.simplesideias.com.br/components.swc</a>.</p>

<p>Vamos atualizar nossa classe <code>Main</code> para adicionar um botão. Ao clicá-lo, iremos alterar seu label para &#034;Clicked&#034;.</p>

<pre class="actionscript"><code>package <span class="br0">&#123;</span>
  <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">Sprite</span>;
  <span class="kw3">import</span> fl.<span class="me1">controls</span>.<span class="kw3">Button</span>;
  <span class="kw3">import</span> flash.<span class="me1">events</span>.<span class="me1">MouseEvent</span>;
&nbsp;
  <span class="kw3">public</span> <span class="kw2">class</span> Main <span class="kw3">extends</span> Sprite <span class="br0">&#123;</span>
    <span class="kw3">public</span> <span class="kw2">function</span> Main<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="kw2">var</span> <span class="kw3">button</span>:<span class="kw3">Button</span> = <span class="kw2">new</span> <span class="kw3">Button</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp;
      <span class="kw3">button</span>.<span class="me1">label</span> = <span class="st0">&quot;Click me!&quot;</span>;
      <span class="kw3">button</span>.<span class="me1">move</span><span class="br0">&#40;</span><span class="nu0">15</span>, <span class="nu0">15</span><span class="br0">&#41;</span>;
&nbsp;
      <span class="kw3">button</span>.<span class="me1">addEventListener</span><span class="br0">&#40;</span>MouseEvent.<span class="me1">MOUSE_DOWN</span>, <span class="kw2">function</span><span class="br0">&#40;</span>event:MouseEvent<span class="br0">&#41;</span>:<span class="kw3">void</span> <span class="br0">&#123;</span>
        event.<span class="kw3">target</span>.<span class="me1">label</span> = <span class="st0">&quot;Clicked!&quot;</span>;
      <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp;
      addChild<span class="br0">&#40;</span><span class="kw3">button</span><span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></code></pre>

<p>Para criar novos botões, você precisa carregar a classe <code>flash.controls.Button</code>,
disponibilizada pelo arquivo <code>components.swc</code>. Esse arquivo deve ser carregado
pela linha de comando.</p>

<pre><code>$ mxmlc -output main.swf \
      -as3 \
      -static-link-runtime-shared-libraries \
      -default-size 130 50 \
      -optimize \
      -verbose-stacktraces \
      -include-libraries=`pwd`/components.swc \
      Main.as
</code></pre>

<p>O resultado final será algo como a imagem abaixo.</p>

<p><img src="http://m.simplesideias.com.br/as3-button.png" alt="ActionScript 3 gerando botão"></p>

<h3>Compilando os arquivos automaticamente</h3>

<p>Uma das melhores mudanças nesse processo é que agora posso executar tudo pela linha de comando. E posso, inclusive, cmpilar os arquivos automaticamente usando bibliotecas como o <a rel="external"  href="http://rubygems.org/gems/guard">Guard</a>. Primeiro, vamos instalar as gems necessárias.</p>

<pre><code>$ gem install guard guard-shell
</code></pre>

<p>Na raíz de seu projeto, crie o arquivo <code>Guardfile</code> com o conteúdo à seguir.</p>

<pre class="rails"><code>guard <span class="re3">:shell</span> <span class="kw1">do</span>
  watch<span class="br0">&#40;</span>/\.<span class="me1">as</span>$/<span class="br0">&#41;</span> <span class="kw1">do</span>
    <span class="kw3">system</span> &lt;&lt;-SHELL
      mxmlc -output main.<span class="me1">swf</span> \
            -as3 \
            -static-link-runtime-shared-libraries \
            -default-<span class="kw5">size</span> <span class="nu0">130</span> <span class="nu0">50</span> \
            -optimize \
            -verbose-stacktraces \
            -include-libraries <span class="st0">`pwd`</span>/components.<span class="me1">swc</span> \
            Main.<span class="me1">as</span>
    SHELL
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>O código acima irá compilar o SWF toda vez que uma alteração for detectada
em arquivos com a extensão <code>.as</code>. Para iniciar o monitor, basta executar o comando
<code>guard</code>.</p>

<h3>Finalizando</h3>

<p>Por pior que o Flash seja, ele ainda é imbatível em uma coisa: broadcast de áudio e vídeo.
É muito fácil publicar sua webcam e seu microfone. Já que não existe nenhuma outra
alternativa viável, evitar o uso da IDE já ajuda bastante no dia-a-dia.</p>

<p>Para você ter uma ideia de como o Flex é (sic) flexível, veja o que fiz para o Presentta até agora:</p>

<p><img src="http://m.simplesideias.com.br/as3-presentta.png" alt="Componente gerado com Flex"></p>

O componente acima conecta no media server, faz o broadcast, verifica as conexões e, em caso de queda, reconecta automaticamente. Muito bom para algumas horas de hacking. :)<img src="http://feeds.feedburner.com/~r/simplesideias/~4/DhVBfc1gIxk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/programando-em-actionscript-sem-o-flash/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/programando-em-actionscript-sem-o-flash/</feedburner:origLink></item>
		<item>
		<title>Ruby e o duck typing</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/rq46B1XhtJw/</link>
		<comments>http://simplesideias.com.br/ruby-e-o-duck-typing/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 21:15:03 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=726</guid>
		<description><![CDATA[No Ruby, nós não declaramos o tipo de objetos, nem o tipo do retorno de métodos. Embora isso possa parecer algo muito ruim para quem está acostumado com linguagens como Java, linguagens dinamicamente tipadas como o Ruby são muito flexíveis, produtivas e, acredite, seguras. Na maioria das vezes, o medo de não poder contar com [...]]]></description>
			<content:encoded><![CDATA[<p>No Ruby, nós não declaramos o tipo de objetos, nem o tipo do retorno de métodos. Embora isso possa parecer algo muito ruim para quem está acostumado com linguagens como Java, linguagens dinamicamente tipadas como o Ruby são muito flexíveis, produtivas e, acredite, seguras. Na maioria das vezes, o medo de não poder contar com o compilador para fazer verificações de tipos não tem fundamento.</p>

<p>Desenvolvedores Ruby estão mais acostumados em definir objetos pelo que eles podem fazer, do que por seu tipo. Esta técnica é chamada de <em>duck typing</em>.</p>

<p><strong>Se anda como um pato e faz barulho como um pato, então deve ser um pato.</strong> E o interpretador ficará feliz em fazer com que o objeto seja tratado como um pato. Na prática, isso significa que em vez de fazer verificações de tipo de um objeto, você deve se preocupar se este objeto é capaz de executar o método que você precisa.</p>

<p>Pegue como exemplo strings, arquivos e arrays. As classes <code>Array</code>, <code>File</code> e <code>String</code> implementam o método de instância <code>&lt;&lt;</code>, que quase sempre significa <em>append</em>. Você pode se aproveitar desta <em>interface</em> para criar, por exemplo, uma classe de log que não se importa com o tipo de objeto que irá armazenar esses logs.</p>

<pre class="rails"><code><span class="kw1">class</span> SimpleLogger
  <span class="kw1">def</span> initialize<span class="br0">&#40;</span>io<span class="br0">&#41;</span>
    <span class="re1">@io</span> = io
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">def</span> log<span class="br0">&#40;</span>message<span class="br0">&#41;</span>
    <span class="re1">@io</span> &lt;&lt; <span class="st0">&quot;#{Time.now} - #{message}<span class="es0">\n</span>&quot;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>A classe <code>SimpleLogger</code> consegue enviar os logs para arrays, strings, arquivos e, se quiser, para qualquer outro objeto que implemente o método <code>&lt;&lt;</code>.</p>

<p>O Ruby realmente abraça o <em>duck typing</em> por toda a linguagem. Diversos <em>protocolos</em> exigem que o objeto apenas implemente um método <code>to_&lt;protocol&gt;</code>. Muitas operações que envolvem arrays, por exemplo, exigem que o objeto do lado direito da expressão apenas implemente o método <code>to_ary</code>.</p>

<pre class="rails"><code><span class="kw1">class</span> Numbers
  <span class="kw1">def</span> to_ary
    <span class="br0">&#91;</span><span class="nu0">4</span>, <span class="nu0">5</span>, <span class="nu0">6</span><span class="br0">&#93;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span>
&nbsp;
<span class="br0">&#91;</span><span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span><span class="br0">&#93;</span> + Numbers.<span class="kw5">new</span>
<span class="co1">#=&gt; [1, 2, 3, 4, 5, 6]</span></code></pre>

<p>A classe <code>Hash</code>, por exemplo, permite que você una dois objetos, desde que o método <code>to_hash</code> seja implementado.</p>

<pre class="rails"><code><span class="kw1">class</span> Configuration
  <span class="kw1">def</span> to_hash
    <span class="br0">&#123;</span>root: <span class="st0">&quot;/etc&quot;</span><span class="br0">&#125;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span>
&nbsp;
config = Configuration.<span class="kw5">new</span>
&nbsp;
<span class="br0">&#123;</span>name: <span class="st0">&quot;Custom config&quot;</span><span class="br0">&#125;</span>.<span class="me1">merge</span><span class="br0">&#40;</span>config<span class="br0">&#41;</span>
<span class="co1">#=&gt; {:name=&gt;&quot;Custom config&quot;, :root=&gt;&quot;/etc&quot;}</span></code></pre>

<p>Não é preciso dizer que este tipo de <em>protocolo por convenção</em> permite criar códigos muito mais flexíveis, com extrema facilidade.</p>

<p>Isso não significa que saber o tipo de objetos não seja útil. Veja, por exemplo, as operações matemáticas. Qualquer objeto pode ser convertido em números. Para isso, basta implementar o método <code>coerce</code>, que recebe o objeto que está solicitando a coerção. O exemplo abaixo mostra como criar uma classe cuja instância pode ser convertida em números inteiros e flutuantes, mas não em instâncias da classe <code>BigDecimal</code>.</p>

<pre class="rails"><code><span class="kw1">class</span> NumberOne
  <span class="kw1">def</span> coerce<span class="br0">&#40;</span>object<span class="br0">&#41;</span>
    <span class="kw1">case</span> object
    <span class="kw1">when</span> <span class="kw3">Integer</span>
      <span class="br0">&#91;</span>object, <span class="nu0">1</span><span class="br0">&#93;</span>
    <span class="kw1">when</span> <span class="kw3">Float</span>
      <span class="br0">&#91;</span>object, <span class="nu0">1.0</span><span class="br0">&#93;</span>
    <span class="kw1">else</span>
      <span class="kw3">raise</span> <span class="kw4">TypeError</span>, <span class="st0">&quot;#{self.inspect} can't be coerced into #{object.class}&quot;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span>
&nbsp;
<span class="kw3">puts</span> <span class="nu0">1</span> + NumberOne.<span class="kw5">new</span>
<span class="co1">#=&gt; 2</span>
&nbsp;
<span class="kw3">puts</span> <span class="nu0">1.0</span> + NumberOne.<span class="kw5">new</span>
<span class="co1">#=&gt; 2.0</span>
&nbsp;
<span class="kw3">require</span> <span class="st0">&quot;bigdecimal&quot;</span>
<span class="kw3">puts</span> BigDecimal.<span class="kw5">new</span><span class="br0">&#40;</span><span class="st0">&quot;1.0&quot;</span><span class="br0">&#41;</span> + NumberOne.<span class="kw5">new</span>
<span class="co1">#=&gt; TypeError: FakeNumber can't be coerced into BigDecimal</span></code></pre>

<p>O <em>duck typing</em> vai além de simples regras; é um <em>estilo</em> de programação. Antes de exigir tipos de objetos, pergunte-se se isso é realmente necessário. Às vezes, o tipo do objeto é muito importante, mas muitas vezes isso simplesmente não importa.</p>

<p><strong>NOTA:</strong> Este artigo foi tirado do e-book "Conhecendo o Ruby" que estou escrevendo. Se inscreva na <a href="http://howtocode.com.br/?simplesideias">newsletter do HOWTO</a> e saiba quando ele for lançado.</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/rq46B1XhtJw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/ruby-e-o-duck-typing/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/ruby-e-o-duck-typing/</feedburner:origLink></item>
		<item>
		<title>Hospendando sites estáticos no Heroku</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/nyEt5yNLepI/</link>
		<comments>http://simplesideias.com.br/hospendando-sites-estaticos-no-heroku/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 03:04:50 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=719</guid>
		<description><![CDATA[Faz algum tempo que venho usando o plano gratuito do Heroku para hospedar páginas estáticas, embora você consiga ir muito além disso. De qualquer modo, é uma maneira muito prática de ter sites estáticos com o poder do deploy de aplicações através de um simples push do Git. O processo em si é bastante simples. [...]]]></description>
			<content:encoded><![CDATA[<p>Faz algum tempo que venho usando o plano gratuito do <a rel="external" href="http://heroku.com">Heroku</a> para hospedar páginas estáticas, embora você consiga ir muito além disso. De qualquer modo, é uma maneira muito prática de ter sites estáticos com o poder do deploy de aplicações através de um simples <em>push</em> do Git.</p>

<p>O processo em si é bastante simples. Primeiro, você deve organizar todos os seus arquivos em algum diretório, por exemplo, <code>some_site/public</code>. Este diretório pode conter arquivos HTML, JavaScript e CSS. Na prática, você pode servir qualquer tipo de arquivo.</p>

<p>Crie o arquivo <code>some_site/config.ru</code>. Nós iremos servir os arquivos estáticos com <a rel="external" href="http://rack.rubyforge.org">Rack</a>. Primeiro, nós vamos criar um aplicativo usando o <code>Rack::Builder</code>. Este aplicativo usará um middleware que redirecionará a requisição na raíz do site para o arquivo <code>some_site/public/index.html</code>.</p>

<p>Todos os outros arquivos do diretório <code>some_site/public</code> serão servidos com o <code>Rack::Directory</code>.</p>

<pre class="rails"><code>app = <span class="re2">Rack::Builder</span>.<span class="kw5">new</span> <span class="kw1">do</span>
  use <span class="re2">Rack::Static</span>, urls: <span class="br0">&#123;</span><span class="st0">&quot;/&quot;</span> =&gt; <span class="st0">&quot;index.html&quot;</span><span class="br0">&#125;</span>, root: <span class="st0">&quot;public&quot;</span>
  run <span class="re2">Rack::URLMap</span>.<span class="kw5">new</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
    <span class="st0">&quot;/&quot;</span> =&gt; <span class="re2">Rack::Directory</span>.<span class="kw5">new</span><span class="br0">&#40;</span><span class="st0">&quot;public&quot;</span><span class="br0">&#41;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span>
<span class="kw1">end</span>
&nbsp;
run app</code></pre>

<p>Crie também um arquivo <code>Gemfile</code>, que terá como única dependência o próprio Rack. Este arquivo <code>Gemfile</code> deve estar na raíz do seu projeto e será algo como isto.</p>

<pre class="rails"><code>source <span class="re3">:rubygems</span>
gem <span class="st0">&quot;rack&quot;</span>, <span class="st0">&quot;~&gt; 1.3&quot;</span></code></pre>

<p>Execute o comando <code>bundle install</code> para instalar a dependência e gerar o arquivo <code>Gemfile.lock</code>.</p>

<p>Na raíz do projeto, inicie um novo repositório Git e faça o commit inicial.</p>

<pre class="text"><code>$ cd some_site
$ git init
Initialized empty Git repository in /Users/fnando/Sites/some_site/.git/
$ git add .
$ git ci -am &quot;Initial commit&quot;
[master (root-commit) 54e37c9] Initial commit
 4 files changed, 31 insertions(+), 0 deletions(-)
 create mode 100644 Gemfile
 create mode 100644 Gemfile.lock
 create mode 100644 config.ru
 create mode 100644 public/index.html</code></pre>

<p>Agora, basta criar seu aplicativo no Heroku. Se você ainda não possui uma conta configurada, <a rel="external" href="http://devcenter.heroku.com/articles/quickstart">veja o que é preciso fazer</a>. Se tudo estiver certo, você pode criar um novo aplicativo com o comando <code>heroku apps:create &lt;seu-app&gt;</code>. O stack padrão é baseado no Ruby 1.9, então estamos muito bem acompanhados.</p>

<pre class="text"><code>$ heroku apps:create some-site
Creating some-site... done, stack is bamboo-mri-1.9.2
http://some-site.heroku.com/ | git@heroku.com:some-site.git
Git remote heroku added</code></pre>

<p>Para fazer o deploy, execute o comando <code>git push heroku</code>.</p>

<pre class="text"><code>$ git push heroku 
Counting objects: 7, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 768 bytes, done.
Total 7 (delta 0), reused 0 (delta 0)
&nbsp;
-----&gt; Heroku receiving push
-----&gt; Ruby/Rack app detected
-----&gt; Gemfile detected, running Bundler version 1.0.7
       Unresolved dependencies detected; Installing...
       Using --without development:test
       Fetching source index for http://rubygems.org/
       Installing rack (1.3.5) 
       Using bundler (1.0.7) 
       Your bundle is complete! It was installed into ./.bundle/gems/
-----&gt; Compiled slug size is 152K
-----&gt; Launching... done, v3
       http://some-site.heroku.com deployed to Heroku
&nbsp;
To git@heroku.com:some-site.git
 * [new branch]      HEAD -&gt; master</code></pre>

<p>Certifique-se que está tudo funcionando. Basta acessar a URL exibida após o deploy que, neste caso, é <code>http://some-site.heroku.com</code>.</p>

<p>Obviamente, usar esta URL não é nada profissional. Você pode configurar seu próprio domínio, sem gastar nada (se não me engano, você precisa adicionar o seu cartão de crédito, mesmo sendo funcionalidades gratuitas). Adicione a extensão &#034;Custom Domains&#034;.</p>

<pre class="text"><code>$ heroku addons:add custom_domains:basic
-----&gt; Adding custom_domains:basic to some-site... done, (free)</code></pre>

<p>Adicione também a extensão &#034;Zerigo DNS&#034;.</p>

<pre class="text"><code>$ heroku addons:add zerigo_dns:basic
-----&gt; Adding zerigo_dns:basic to some-site... done, (free)</code></pre>

<p>Finalmente, você pode adicionar seu domínio com o comando <code>heroku domains:add &lt;seu domínio&gt;</code>.</p>

<pre class="text"><code>$ heroku domains:add somesite.com
Added somesite.com as a custom domain name for some-site</code></pre>

<p>Você precisará adicionar o registro de DNS que irá redirecionar <code>www.somesite.com</code> para <code>somesite.com</code> no site da Zerigo. Para acessar este painel de controle, execute o comando <code>heroku addons:open zerigo_dns:basic</code>.</p>

<pre class="text"><code>$ heroku addons:open zerigo_dns:basic
Opening zerigo_dns:basic for some-site...</code></pre>

<p>Clique no botão &#034;Configure&#034;.</p>

<p><img src="http://m.simplesideias.com.br/heroku-zerigo.png" alt="Painel do Zerigo DNS no Heroku"/></p>

<p>Você será redirecionado para uma tela como esta:</p>

<p><img src="http://m.simplesideias.com.br/zerigo-dns.jpg" alt="Zerigo DNS" /></p>

<p>Clique no link &#034;Host > Add&#034; para adicionar um novo registro. No campo &#034;Host&#034;, digite &#034;www&#034;, defina o tipo do registro como sendo &#034;Redirect&#034; e, por último, digite a URL de destino no campo &#034;Data&#034;.</p>

<p><img src="http://m.simplesideias.com.br/zerigo-dns-redirect.png" alt="Zerigo DNS - Adicionando redirecionamento" /></p>

<p>O Zerigo DNS funciona bem para poucos acessos, mas você pode rapidamente ultrapassar o limite do plano básico. Neste caso, sugiro que dê uma olhada no serviço oferecido pela <a href="http://dnsimple.com">DNSimple</a>, que custa apenas US$3 para 10 domínios e é extremamente simples de configurar; existe até uma opção de configuração com apenas um clique para aplicativos hospedados no Heroku.</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/nyEt5yNLepI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/hospendando-sites-estaticos-no-heroku/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/hospendando-sites-estaticos-no-heroku/</feedburner:origLink></item>
		<item>
		<title>Usando presenters no Rails</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/YfZMHoHchUc/</link>
		<comments>http://simplesideias.com.br/usando-presenters-no-rails/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 19:49:09 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=706</guid>
		<description><![CDATA[Um problema muito recorrente de aplicativos de médio-grande porte é que as views são uma bagunça. É muito comum termos condições em nossas views. Objetos possuem diferentes estados e muitas vezes precisamos mostrar esses estados visualmente. E normalmente começamos pelo caminho mais fácil, que é adicionar ifs na view. Acontece que isso não precisa ser [...]]]></description>
			<content:encoded><![CDATA[<p>Um problema muito recorrente de aplicativos de médio-grande
porte é que as views são uma bagunça.</p>

<p>É muito comum termos condições em nossas views. Objetos possuem
diferentes estados e muitas vezes precisamos mostrar esses estados
visualmente. E normalmente começamos pelo caminho mais fácil, que é 
adicionar <code>ifs</code> na view.</p>

<p>Acontece que isso não precisa ser sempre assim. Neste artigo vou
mostrar como funciona um pattern chamado Presenter, que permite
diminuir/remover a complexidade de views e controllers.</p>

<h3>Começando com o seu próprio presenter</h3>

<p>A primeira coisa que você precisa detectar é que tipo de lógica
é possível extrair de sua view. Algumas coisas mais genéricas
fazem mais sentido serem extraídas como helpers. Outras, como <code>ifs</code>
para determinar qual partial deve ser renderizada provavelmente
devem ser movidas para seu presenter.</p>

<p>Imagine que você tenha uma view como esta:</p>

<pre class="text"><code>&lt;h1&gt;&lt;%= @product.name %&gt;&lt;/h1&gt;
&nbsp;
&lt;% if @product.description %&gt;
  &lt;p class=&quot;description&quot;&gt;&lt;%= @product.more %&gt;&lt;/p&gt;
&lt;% end %&gt;</code></pre>

<p>Não se deixe enganar por esse tipo de lógica. Embora pareça inofensiva, 
coisas como esta podem sair do controle rapidamente.</p>

<p>Esta view precisa de uma variável <code>@product</code> que deve ser definida em nosso controller:</p>

<pre class="rails"><code><span class="kw1">class</span> ProductsController &lt; ApplicationController
  <span class="kw1">def</span> <span class="kw5">show</span>
    <span class="re1">@product</span> = Product.<span class="me1">find</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:id</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Agora, precisamos de uma classe que irá &#034;envelopar&#034; nossa instância da classe <code>Product</code>. Crie o arquivo <code>app/presenters/product_presenter.rb</code>. Como este 
diretório não está no load path do Rails, vamos ter que fazer uma configuração no arquivo <code>config/application.rb</code>.</p>

<pre class="rails"><code><span class="kw1">module</span> HOWTO
  <span class="kw1">class</span> Application &lt; <span class="re2">Rails::Application</span>
    <span class="co1"># ... </span>
    config.<span class="me1">autoload_paths</span> &lt;&lt; config.<span class="me1">root</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">&quot;app/presenters&quot;</span><span class="br0">&#41;</span>.<span class="kw5">to_s</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Volte ao arquivo <code>product_presenter.rb</code> e crie a classe <code>ProductPresenter</code>. </p>

<pre class="rails"><code><span class="kw1">class</span> ProductPresenter
  <span class="kw1">def</span> initialize<span class="br0">&#40;</span>product<span class="br0">&#41;</span>
    <span class="re1">@product</span> = product
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Esta classe será responsável por <strong>expor</strong> todos os atributos que nossa view irá acessar. Em vez de definir cada um dos métodos manualmente, podemos apenas <em>delegar</em> as chamadas para o objeto. Para fazer isso, vamos usar o método <a rel="external" href="http://rubydoc.info/docs/rails/3.1.1/Module:delegate">Module#delegate</a>, adicionado pelo ActiveSupport. </p>

<pre class="rails"><code><span class="kw1">class</span> ProductPresenter
  delegate <span class="re3">:name</span>, <span class="re3">:description</span>, to: :<span class="st0">&quot;@product&quot;</span>
&nbsp;
  <span class="kw1">def</span> initialize<span class="br0">&#40;</span>product<span class="br0">&#41;</span>
    <span class="re1">@product</span> = product
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Qualquer chamada aos métodos <code>ProductPresenter#name</code> e <code>ProductPresenter#description</code> serão delegadas para o objeto que foi armazenado em <code>@product</code>. Você também poderia utilizar o módulo <a rel="external" href="http://www.ruby-doc.org/stdlib-1.9.3/libdoc/forwardable/rdoc/index.html">Forwardable</a>, mas a versão adicionada pelo ActiveSupport é mais elegante.</p>

<p>Agora, podemos remover aquele <code>if</code>. Se você não se lembra mais dele, dê uma última olhadela, pois logo ele não mais existirá! Adicione o método <code>description</code>. Faça com que este método retorne o parágrafo com a descrição, caso ela tenha sido definida. 
Como é necessário retornar uma tag HTML, vamos usar o helper <code>content_tag</code>.</p>

<pre class="rails"><code><span class="kw1">class</span> ProductPresenter
  delegate <span class="re3">:name</span>, to: :<span class="st0">&quot;@product&quot;</span>
&nbsp;
  <span class="kw1">def</span> initialize<span class="br0">&#40;</span>product<span class="br0">&#41;</span>
    <span class="re1">@product</span> = product
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">def</span> description
    <span class="kw1">if</span> <span class="re1">@product</span>.<span class="me1">description</span>.<span class="me1">present</span>?
      helpers.<span class="kw5">content_tag</span><span class="br0">&#40;</span><span class="re3">:p</span>, <span class="re1">@product</span>.<span class="me1">description</span>, <span class="kw1">class</span>: <span class="st0">&quot;description&quot;</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
&nbsp;
  private
  <span class="kw1">def</span> helpers
    ApplicationController.<span class="me1">helpers</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Altere o controller para que ele passe a instância da classe <code>Product</code> para o presenter.</p>

<pre class="rails"><code><span class="kw1">class</span> ProductsController &lt; ApplicationController
  <span class="kw1">def</span> <span class="kw5">show</span>
    <span class="re1">@product</span> = ProductPresenter.<span class="kw5">new</span><span class="br0">&#40;</span>Product.<span class="me1">find</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:id</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Para finalizar, basta modificar nossa view.</p>

<pre class="text"><code>&lt;h1&gt;&lt;%= @product.name %&gt;&lt;/h1&gt;
&lt;%= @product.description %&gt;</code></pre>

<p>Para o caso de partials, o funcionamento é basicamente o mesmo. No entanto, em vez de fazer a renderização no próprio presenter, é mais fácil retornar o nome da partial que deve ser renderizada.</p>

<p>Imagine que nossa view tenha mais um <code>if</code> que irá renderizar uma partial diferente para produtos gratuitos.</p>

<pre class="text"><code>&lt;% if @product.paid? %&gt;
  &lt;%= render &quot;order&quot;, product: @product %&gt;
&lt;% else %&gt;
  &lt;%= render &quot;download&quot;, product: @product %&gt;
&lt;% end %&gt;</code></pre>

<p>Podemos implementar um método chamado <code>ProductPresenter#checkout_partial</code> que irá fazer aquele <code>if</code>, retornando apenas o nome da partial.</p>

<pre class="rails"><code><span class="kw1">class</span> ProductPresenter
  delegate <span class="re3">:name</span>, to: :<span class="st0">&quot;@product&quot;</span>
&nbsp;
  <span class="kw1">def</span> initialize<span class="br0">&#40;</span>product<span class="br0">&#41;</span>
    <span class="re1">@product</span> = product
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">def</span> description
    <span class="kw1">if</span> <span class="re1">@product</span>.<span class="me1">description</span>.<span class="me1">present</span>?
      helpers.<span class="kw5">content_tag</span><span class="br0">&#40;</span><span class="re3">:p</span>, <span class="re1">@product</span>.<span class="me1">description</span>, <span class="kw1">class</span>: <span class="st0">&quot;description&quot;</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">def</span> checkout_partial
    <span class="re1">@product</span>.<span class="me1">paid</span>? ? <span class="st0">&quot;order&quot;</span> : <span class="st0">&quot;download&quot;</span>
  <span class="kw1">end</span>
&nbsp;
  private
  <span class="kw1">def</span> helpers
    ApplicationController.<span class="me1">helpers</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>E na nossa view, basta renderizar o retorno do método <code>ProductPresenter#checkout_partial</code>.</p>

<pre class="text"><code>&lt;%= render @product.checkout_partial, product: @product %&gt;</code></pre>

<p>A esta altura, você já deve ter percebido como presenters podem remover completamente a lógica das views. Embora seja muito fácil fazer isso sem a necessidade de bibliotecas, algumas coisas precisam ser implementadas toda vez. É o caso de helpers, rotas e métodos de internacionalização.</p>

<p>Pensando nisso, decidi extrair aquela organização de código que eu estava utilizando em uma gem chamada <a rel="external" href="http://rubygems.org/gems/simple_presenter">simple_presenter</a>.</p>

<h3>Usando o simple_presenter</h3>

<p>Para instalar, basta executar o comando abaixo:</p>

<pre class="text"><code>$ gem install simple_presenter</code></pre>

<p>Lembre-se de adicionar a gem ao arquivo Gemfile.</p>

<pre class="rails"><code>source <span class="re3">:rubygems</span>
gem <span class="st0">&quot;rails&quot;</span>, <span class="st0">&quot;3.1.3&quot;</span>
gem <span class="st0">&quot;simple_presenter&quot;</span>, <span class="st0">&quot;~&gt; 0.1&quot;</span></code></pre>

<p>Aquele mesmo presenter que definimos pode ser trocado por algo como isto:</p>

<pre class="rails"><code><span class="kw1">class</span> ProductPresenter &lt; Presenter
  expose <span class="re3">:name</span>, <span class="re3">:description</span>
&nbsp;
  <span class="kw1">def</span> description
    <span class="kw1">if</span> <span class="re1">@subject</span>.<span class="me1">description</span>.<span class="me1">present</span>?
      h.<span class="kw5">content_tag</span><span class="br0">&#40;</span><span class="re3">:p</span>, <span class="re1">@subject</span>.<span class="me1">description</span>, <span class="kw1">class</span>: <span class="st0">&quot;description&quot;</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">def</span> checkout_partial
    <span class="re1">@subject</span>.<span class="me1">paid</span>? ? <span class="st0">&quot;order&quot;</span> : <span class="st0">&quot;download&quot;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Note que não precisamos mais definir o método <code>ProductPresenter#initialize</code>, nem o método <code>ProductPresenter#helpers</code>. Também tivemos que mudar todas as referências a <code>@product</code> para <code>@subject</code>; isso é necessário  porque, por padrão, o nome do objeto que receberá os métodos delegados é <code>@subject</code>.</p>

<p>O simple_presenter adiciona os métodos <code>helpers</code> e <code>h</code> que permite acessar os helpers do Rails. Os helpers de rotas podem ser acessados com os métodos <code>routes</code> e <code>r</code>. E, finalmente, os helpers de internacionalização podem ser acessados por <code>translate</code> e <code>t</code>, e <code>localize</code> e <code>l</code>.</p>

<h3>Escrevendo testes</h3>

<p>Escrever testes para presenters é muito simples. No caso do RSpec, basta criar o diretório <code>spec/presenters</code>. Aquele nosso presenter pode ter testes como este:</p>

<pre class="rails"><code><span class="kw3">require</span> <span class="st0">&quot;spec_helper&quot;</span>
&nbsp;
describe ProductPresenter <span class="kw1">do</span>
  let<span class="br0">&#40;</span><span class="re3">:product</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> mock<span class="br0">&#40;</span>Product, name: <span class="st0">&quot;Some product&quot;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>
  subject <span class="br0">&#123;</span> described_class.<span class="kw5">new</span><span class="br0">&#40;</span>product<span class="br0">&#41;</span> <span class="br0">&#125;</span>
&nbsp;
  its<span class="br0">&#40;</span><span class="re3">:name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> should eql<span class="br0">&#40;</span><span class="st0">&quot;Some product&quot;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>
&nbsp;
  describe <span class="st0">&quot;#description&quot;</span> <span class="kw1">do</span>
    it <span class="st0">&quot;returns content&quot;</span> <span class="kw1">do</span>
      product.<span class="me1">stub</span> description: <span class="st0">&quot;Some description&quot;</span>
      expected = %<span class="br0">&#91;</span>&lt;p <span class="kw1">class</span>=<span class="st0">&quot;description&quot;</span>&gt;Some description&lt;/p&gt;<span class="br0">&#93;</span>
&nbsp;
      subject.<span class="me1">description</span>.<span class="me1">should</span> eql<span class="br0">&#40;</span>expected<span class="br0">&#41;</span>
    <span class="kw1">end</span>
&nbsp;
    it <span class="st0">&quot;returns no message&quot;</span> <span class="kw1">do</span>
        subject.<span class="me1">description</span>.<span class="me1">should</span> be_blank
    <span class="kw1">end</span>
  <span class="kw1">end</span>
&nbsp;
  describe <span class="st0">&quot;#checkout_partial&quot;</span> <span class="kw1">do</span>
    it <span class="st0">&quot;returns partial for paid products&quot;</span> <span class="kw1">do</span>
      product.<span class="me1">stub</span> paid?: <span class="kw2">true</span>
      subject.<span class="me1">checkout_partial</span>.<span class="me1">should</span> eql<span class="br0">&#40;</span><span class="st0">&quot;order&quot;</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
&nbsp;
    it <span class="st0">&quot;returns partial for free products&quot;</span> <span class="kw1">do</span>
      product.<span class="me1">stub</span> paid?: <span class="kw2">false</span>
      subject.<span class="me1">checkout_partial</span>.<span class="me1">should</span> eql<span class="br0">&#40;</span><span class="st0">&quot;download&quot;</span><span class="br0">&#41;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<h3>Finalizando</h3>

<p>Você deve ter percebido que presenters permitem tornar suas views muito mais simples. Além disso, eles tem a vantagem de serem fáceis de testar.</p>

<p>A coisa mais difícil dos presenters é se acostumar com eles. Mas depois que você se acostuma, dificilmente terá uma view complicada e também nem vai querer deixar de usá-los!</p>

<p><strong>UPDATE 1:</strong> O <a rel="external" href="http://twitter.com/#!/josevalim/status/148709799574511616">Valim me lembrou</a> que à partir do Rails 3 não é mais preciso adicionar diretórios <code>app/*</code>, pois o Rails faz isso automaticamente. Eu sabia disso, mas o costume ainda permanece.</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/YfZMHoHchUc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/usando-presenters-no-rails/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/usando-presenters-no-rails/</feedburner:origLink></item>
		<item>
		<title>Gravando screencasts com o ScreenFlow</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/7S13MYZYmnw/</link>
		<comments>http://simplesideias.com.br/gravando-screencasts-com-o-screenflow/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 16:29:12 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Mac OS X]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=696</guid>
		<description><![CDATA[Uma das melhores ferramentas para quem precisa gravar screencasts no Mac é o ScreenFlow. Ele possui uma série de funcionalidades avançadas que são muito simples de usar como animações e zoom, dentre outras. No HOWTO as aulas são gravadas para quem quer assistir depois. O grande problema é que, como as aulas são longas (por [...]]]></description>
			<content:encoded><![CDATA[<p>
  Uma das melhores ferramentas para quem precisa gravar screencasts no Mac é o
  <a rel="external" href="http://www.telestream.net/screen-flow/">ScreenFlow</a>.
  Ele possui uma série de funcionalidades avançadas que são muito simples de usar
  como animações e zoom, dentre outras.
</p>

<p>
  No <a rel="external" href="http://howtocode.com.br">HOWTO</a> as aulas são gravadas
  para quem quer assistir depois. O grande problema é que, como as aulas são longas
  (por volta de 2 horas de duração), os vídeos ficam muito grandes. Tentando resolver
  este problema, consegui encontrar a <strong>configuração perfeita</strong> para
  quem precisa exportar vídeos longos.
</p>

<h3>Antes</h3>

<p>
  Antes de encontrar estas configurações, não tinha muito o que fazer. Eu modificava
  o <em>preset</em> Web &ndash; High como o screenshot abaixo.
</p>

<p>
  <img src="http://m.simplesideias.com.br/screenflow-h264.jpg"
    alt="Configurações personalizadas de Web - High com o codec H.264" />
</p>

<p>
  A minha última tentativa de exportação de uma aula de 2h15 levou 4 horas
  para exportar o vídeo e resultou em um arquivo de 665MB. A qualidade ficou
  muito boa, mas o tamanho do arquivo é, obviamente, um problema.
</p>

<p>
  Antes, eu usava o <a rel="external" href="http://www.shinywhitebox.com/ishowu-v1/">iShowU</a>
  e um vídeo com a mesma duração ficava por volta de 300MB, o que já é um tamanho extremamente
  razoável. A grande vantagem do iShowU é que você não precisa exportar o vídeo depois de gravá-lo
  (obviamente isso tem um ponto negativo que é a falta de recursos que o ScreenFlow oferece, mas
  se você não precisa, nem vai sentir falta) e que tornava a liberação do vídeo muito mais rápida,
  já que bastava fazer o upload do vídeo.
</p>

<p>
  Mas, então, porque deixei de usar o iShowU? Bem, nas duas últimas gravações tive problemas com
  ele: um dos vídeos ficou sem áudio e o outro ficou com a imagem fixa. E esses erros aconteceram
  mais ou menos no meio do vídeo, sem nenhuma explicação.
</p>

<h3>Depois</h3>

<p>
  Dado o tamanho do arquivo gerado pelo ScreenFlow, comecei a procurar configurações melhores que
  reduzissem drasticamente o tamanho do vídeo. Fazendo algumas buscas madrugada adentro, encontrei esse
  <a rel="external" href="http://blogs.telestream.net/screenflow/2010/02/apple-h-264-vs-x264-in-screenflow-better-exports/">artigo</a> no blog da própria <a rel="external" href="http://telestream.net/">Telestream</a>,
  empresa que criou o ScreenFlow.
</p>

<p>
  Neste artigo eles mostram como configurar o ScreenFlow com um codec chamado x264. Mesmo seguindo este artigo, você precisará modificar algumas outras configurações que não são mencionadas.
</p>

<p>
  Para instalar este codec, que é gratuito, basta você fazer o download no
  <a rel="external" href="http://www003.upp.so-net.ne.jp/mycometg3/">site do desenvolvedor</a>.
  Depois, copie o arquivo <code>x264Encoder.component</code> para o diretório
  <code>~/Library/QuickTime</code>. Pronto! Agora, basta configurar o ScreenFlow com este
  novo codec. Reinicie o ScreenFlow para que ele faça a detecção.
</p>

<p>
  Na hora de exportar (<kbd>&#x2318;+E</kbd>), clique no botão &ldquo;Customize > Video > Settings&rdquo;.
  Na opção &ldquo;Compression Type&rdquo;, selecione o codec &ldquo;x264Encoder&rdquo;. Altere as
  configurações desta janela para as mesmas do screenshot abaixo.
</p>

<p>
  <img src="http://m.simplesideias.com.br/screenflow-video-settings.jpg"
    alt="Configurações de vídeo com o codec x264Encoder" />
</p>

<p>
  Você vai precisar configurar também o próprio codec. Para isso, nesta mesma janela clique no
  botão &ldquo;Options&rdquo;. Isso abrirá uma janela com todas as opções de personalização do
  codec. Modifique as opções como o screenshot abaixo.
</p>

<p>
  <img src="http://m.simplesideias.com.br/screenflow-x264.jpg"
    alt="Configurações do codec x264Encoder" />
</p>

<p>
  Por último, se o seu screencast é baseado em voz, com quase nenhuma trilha sonora,
  você também pode modificar as configurações do áudio, diminuindo ainda mais o tamanho
  do vídeo exportado. Basta você modificar a qualidade do áudio para 64kbps de bitrate,
  como no screenshot abaixo.
</p>

<p><img src="http://m.simplesideias.com.br/screenflow-audio.jpg"
    alt="Configurações de áudio" />
</p>

<p>
  Meu Macbook Pro não é lá essas coisas (Mid 2009, com processador Core 2 Duo 2.26 GHz),
  então demorou <em>um pouquinho</em>. Depois de <strong>6 horas</strong>, aquele mesmo vídeo
  que tinha ficado com 665MB de tamanho foi exportado como <strong>266MB</strong>.
</p>

<p>O meu servidor agradece, e os alunos também!</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/7S13MYZYmnw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/gravando-screencasts-com-o-screenflow/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/gravando-screencasts-com-o-screenflow/</feedburner:origLink></item>
		<item>
		<title>Classe singleton e definição de métodos de classe</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/3ib0-VjRdKk/</link>
		<comments>http://simplesideias.com.br/classe-singleton-e-definicao-de-metodos-de-classe/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 22:33:37 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=688</guid>
		<description><![CDATA[Quando falei sobre classes singleton no Ruby, mostrei como era possível atuar no contexto da classe. Uma coisa muito comum entre os desenvolvedores é definir métodos de classe através da classe singleton. class Person class &#60;&#60; self def description &#34;It defines an user&#34; end end end No exemplo acima estamos definindo uma método de classe [...]]]></description>
			<content:encoded><![CDATA[<p>Quando falei sobre <a href="http://simplesideias.com.br/ruby-object-model-singleton-class/">classes singleton no Ruby</a>, mostrei como era possível atuar no contexto da classe. Uma coisa muito comum entre os desenvolvedores é definir métodos de classe através da classe singleton.</p>

<pre class="ruby"><code><span class="kw1">class</span> Person
  <span class="kw1">class</span> &lt;&lt; <span class="kw2">self</span>
    <span class="kw1">def</span> description
      <span class="st0">&quot;It defines an user&quot;</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>No exemplo acima estamos definindo uma método de classe <code>Person.description</code>. Infelizmente, quando a quantidade de métodos é muito grande, a legibilidade fica prejudicada; você não consegue saber rapidamente se este método é de classe ou instância.</p>

<p>Na maioria das vezes essa escolha é feita sem um objetivo; a explicação é que é possível salvar alguns caracteres ao não digitar <code>self</code> de novo e de novo.</p>

<p>Particularmente, acho que o código acima fica muito mais legível quando escrito desta forma:</p>

<pre class="ruby"><code><span class="kw1">class</span> Person
  <span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">description</span>
    <span class="st0">&quot;It defines an user&quot;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Isso não significa que você não deva usar nunca a classe singleton. Eu uso constantemente. Mas não para definir métodos dessa maneira. Eu gosto, por exemplo, de definir atributos.</p>

<pre class="ruby"><code><span class="kw1">class</span> Config
  <span class="kw1">class</span> &lt;&lt; <span class="kw2">self</span>
    attr_accessor <span class="re3">:root_dir</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></code></pre>

<p>Um outro uso é quando preciso modificar alguma classe quando um hook é executado, como em plugins do ActiveRecord.</p>

<pre class="ruby"><code><span class="kw1">module</span> MyPlugin
  <span class="kw1">module</span> ClassMethods; <span class="kw1">end</span>
  <span class="kw1">module</span> InstanceMethods; <span class="kw1">end</span>
&nbsp;
  <span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">extended</span><span class="br0">&#40;</span>base<span class="br0">&#41;</span>
    <span class="kw1">class</span> &lt;&lt; base
      <span class="kw1">include</span> InstanceMethods
      extend ClassMethods
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span>
&nbsp;
<span class="re2">ActiveRecord::Base</span>.<span class="me1">extend</span><span class="br0">&#40;</span>MyPlugin<span class="br0">&#41;</span></code></pre>

<p>O método <code>Module#include</code> é privado. Uma alternativa seria injetar este módulo com o método <code>Object#send</code>. Eu só não faço isso pois terei que estender este objeto com os métodos de classe, então prefiro usar a classe singleton para manter o código mais legível.</p>

<h3>Finalizando</h3>

<p>Definir muitos métodos com a classe singleton pode ser prático, mas prejudica a legibilidade e você não quer que isto aconteça. Prefira a classe singleton para métodos que não estão disponíveis no contexto da classe como o <code>attr_accessor</code>. <strong>Não é porque você pode fazer algo, que você deve fazê-lo mesmo assim.</strong></p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/3ib0-VjRdKk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/classe-singleton-e-definicao-de-metodos-de-classe/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/classe-singleton-e-definicao-de-metodos-de-classe/</feedburner:origLink></item>
		<item>
		<title>Steve Jobs, 1955-2011</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/Y0a_nTQGcds/</link>
		<comments>http://simplesideias.com.br/steve-jobs-1955-2011/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 13:31:06 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=679</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<div style="font-size: 200px; margin: 40px 0;"></div><img src="http://feeds.feedburner.com/~r/simplesideias/~4/Y0a_nTQGcds" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/steve-jobs-1955-2011/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/steve-jobs-1955-2011/</feedburner:origLink></item>
		<item>
		<title>Saindo da zona de conforto</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/H03mevSVMmI/</link>
		<comments>http://simplesideias.com.br/saindo-da-zona-de-conforto/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 18:46:03 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=671</guid>
		<description><![CDATA[Hoje é meu último dia na Locaweb. Depois de quase dois anos (tudo isso, acredita?), decidi sair da minha zona de conforto. Após bater um papo com um dos meus chefes (que na verdade era para ser uma comida de rabo, em inglês, feita de forma elegante), percebi que tinha passado da hora de eu [...]]]></description>
			<content:encoded><![CDATA[<img src="http://m.simplesideias.com.br/comfort-zone.jpg" alt="" class="align-right" />

<p>Hoje é meu último dia na <a rel="external" href="http://locaweb.com.br/">Locaweb</a>. Depois de quase dois anos (<a href="/contrate-o-nando-vieira/">tudo isso, acredita?</a>), decidi sair da minha zona de conforto. Após bater um papo com um dos meus chefes (que na verdade era para ser uma comida de rabo, em inglês, feita de forma elegante), percebi que tinha passado da hora de eu seguir o meu próprio caminho. Com muitas coisas rolando ao mesmo tempo, eu já não conseguia me dedicar à Locaweb como as pessoas esperavam que eu fizesse. Pensei bastante sobre tudo isso e sempre chegava à mesma conclusão. Era hora de seguir em frente.</p>

<p>A Locaweb é uma grande empresa para se trabalhar. Pessoas inteligentes, ambiente descontraído… se você entrar lá e estiver disposto à aprender, vai sair muito mais esperto. Eu aprendi muita coisa lá e também fiz muitas amizades (vocês sabem quem são). Não era minha intenção sair neste momento, mas tem coisas que vem para dar um chacoalhão, meio que dizendo “E aí? Vamos em frente de verdade agora?”.</p>

<p>Bem. E agora, qual é o plano? Continuarei fazendo as coisas que já fazia. O <a rel="external" href="http://codeplane.com.br/?post=comfort-zone">Codeplane</a> vai muito bem, obrigado. Isso não significa que não tenha coisas para melhorar. Já estou trabalhando em um bug tracker, que está demorando mais do que eu tinha planejado, por causa dessa minha saída da Locaweb. Também quero implementar outras coisas como webhooks e, quem sabe, a tão pedida visualização de código, nos mesmos moldes do <a rel="external" href="http://github.com/">Github</a>.</p>

<p>Tem o <a rel="external" href="http://howtocode.com.br/?post=comfort-zone">HOWTO</a>, que está muito bem, também. Sempre com turmas lotadas (mais de 300 pessoas já passaram por lá), consigo fazer ali algo que sempre quis: ensinar. Para quem acha que caí de paraquedas nisso, minha intenção desde que estava na faculdade era ensinar. Era isso que eu fazia no meu estágio, e era isso que eu pretendia fazer profissionalmente no futuro. Consegui suprir essa minha necessidade por algum tempo escrevendo tutoriais, sempre pensando em quem fosse ler. Quando comecei a aprender Node.js e consegui criar uma versão realmente útil do <a href="/conheca-o-presentta/">Presentta</a>, vi que eu podia investir nisso. Recebi bastante elogios na forma como os workshops são apresentados, então acho que estou fazendo um bom trabalho.</p>

<p>Existem outras ideias que irei tirar do papel aos poucos. Alguns produtos que quero fazer… enfim, o futuro promete! Eu tenho plena certeza de que a jornada será dura. Mais dura do que qualquer coisa que já enfrentei até então. Tenho picos de medo, alternados com aquele sentimento de que tudo vai dar certo. Sorte a minha que tenho <a rel="external" href="http://twitter.com/bete">uma esposa</a> que me encoraja em tudo, um pai que sempre está lá quando preciso, e amigos que acreditam em mim. Mas mesmo assim, desejem-me sorte. Nunca é de mais.</p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/H03mevSVMmI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/saindo-da-zona-de-conforto/feed/</wfw:commentRss>
		<slash:comments>64</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/saindo-da-zona-de-conforto/</feedburner:origLink></item>
		<item>
		<title>Novo app: Codeplane</title>
		<link>http://feedproxy.google.com/~r/simplesideias/~3/hXxhBm8SXMc/</link>
		<comments>http://simplesideias.com.br/novo-app-codeplane/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 10:23:07 +0000</pubDate>
		<dc:creator>Nando Vieira</dc:creator>
				<category><![CDATA[Produtos & Serviços]]></category>

		<guid isPermaLink="false">http://simplesideias.com.br/?p=665</guid>
		<description><![CDATA[Há uns 3 meses decidi que precisava de uma alternativa para repositórios privados no Git. Cancelei minha conta paga no Github e comecei a armazenar no Dropbox e no servidor do Simples Ideias. Não é que eu não goste do Github*. O único problema do Github é que os limites são muito baixos. O plano [...]]]></description>
			<content:encoded><![CDATA[<p>Há uns 3 meses decidi que precisava de uma alternativa para repositórios privados no Git. Cancelei minha conta paga no Github e comecei a armazenar no Dropbox e no servidor do Simples Ideias. </p>

<p>Não é que eu não goste do Github*. O único problema do Github é que os limites são muito baixos. O plano mais básico de US$ 7 dá direito a 5 repositórios privados e apenas 1 colaborador. </p>

<p><img src="http://m.simplesideias.com.br/github-pricing.png" alt="Preços do Github"/></p>

<p>A grande questão é que tenho uns 30 repositórios privados. Neste caso, eu teria que assinar um plano &#034;Business&#034;, que não sairia por menos US$ 100, ou seja, totalmente inviável.</p>

<p>O Dropbox + Servidor funcionou por um tempo, mas uma coisa começou a me irritar. Todo o processo de criação dos repositórios era manual.</p>

<pre class="text"><code>$ mkdir repo.git
$ cd repo
$ git init --bare</code></pre>

<p>E a coisa piorava quando eu precisava dar permissão para alguém acessar algum repositório privado. Foi quando decidi fazer o meu próprio &#034;Github&#034;. Trabalhei em cima da ideia por algum tempo, mostrei para algumas pessoas e finalmente resolvi tirá-la do papel. Foi assim que nasceu o <a href="http://codeplane.com" rel="external">Codeplane</a>.</p>

<p>
    <a href="http://codeplane.com" rel="external">
        <img src="http://m.simplesideias.com.br/codeplane-thumb.png" alt="Codeplane"/>
    </a>
</p>

<p>O <a rel="external" href="http://codeplane.com">Codeplane</a> é um serviço que começa como um Git hosting, mas minha intenção é evoluir para um produto para pequenos times e freelancers. Tenho muitas outras ideias que apenas o tempo e o uso do produto irão dizer se são viáveis. O Codeplane ainda não tem preço, mas devo fazer isso nos próximos dias.</p>

<p>Se você usa Git e precisa de repositórios privados, dê uma olhada no <a rel="external" href="http://codeplane.com">Codeplane</a>. Ele também está disponível na versão em <a rel="external" href="http://codeplane.com.br">português</a>.</p>

<p><em>*Agora, só uso o Github para manter meus projetos OpenSource. Nesse ponto ele é imbatível!</em></p><img src="http://feeds.feedburner.com/~r/simplesideias/~4/hXxhBm8SXMc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://simplesideias.com.br/novo-app-codeplane/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		<feedburner:origLink>http://simplesideias.com.br/novo-app-codeplane/</feedburner:origLink></item>
	</channel>
</rss>

