<?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>caioariede.com weblog</title>
	<atom:link href="http://caioariede.com/feed" rel="self" type="application/rss+xml" />
	<link>http://caioariede.com</link>
	<description>— coding for great good</description>
	<lastBuildDate>Mon, 30 Aug 2010 14:22:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP&#8217;s require_once() equivalent for Ruby</title>
		<link>http://caioariede.com/2010/phps-require_once-equivalent-for-ruby</link>
		<comments>http://caioariede.com/2010/phps-require_once-equivalent-for-ruby#comments</comments>
		<pubDate>Thu, 22 Jul 2010 19:37:13 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=676</guid>
		<description><![CDATA[Simple as it must be:

﻿﻿def require_once path
    require File.expand_path path
end

And just use &#8220;require_once&#8221; instead of &#8220;require&#8221;:

require_once 'lib/file' # loaded
require_once 'lib/file' # not loaded
require_once './lib/file' # not loaded

]]></description>
			<content:encoded><![CDATA[<p>Simple as it must be:</p>
<pre lang="ruby">
﻿﻿def require_once path
    require File.expand_path path
end
</pre>
<p>And just use &#8220;require_once&#8221; instead of &#8220;require&#8221;:</p>
<pre lang="ruby">
require_once 'lib/file' # loaded
require_once 'lib/file' # not loaded
require_once './lib/file' # not loaded
</pre>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2010/phps-require_once-equivalent-for-ruby/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Documentação Offline do Django</title>
		<link>http://caioariede.com/2010/django-docs-offline</link>
		<comments>http://caioariede.com/2010/django-docs-offline#comments</comments>
		<pubDate>Fri, 14 May 2010 13:08:38 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=661</guid>
		<description><![CDATA[Como nem sempre se tem uma conexão ali, a sua disposição, você pode utilizar a documentação offline do Django.
Para isso, antes de ficar desconectado, baixe a versão desejada do Django na sua máquina, 1.1.1 no meu caso.
$ wget http://www.djangoproject.com/download/1.1.1/tarball/
Descompacte:
$ tar xvf Django-1.1.1.tar
Acesse o diretório da documentação
$ cd Django-1.1.1/docs
Instale o Sphinx, o criador de documentações para [...]]]></description>
			<content:encoded><![CDATA[<p>Como nem sempre se tem uma conexão ali, a sua disposição, você pode utilizar a documentação offline do <a class="bbli" href="http://sledge.boo-box.com/list/page/cHl0aG9uXyMjX2JveF8jI190YWdnaW5nLXRvb2wtd3BfIyNfMjgzNDg0-56">Django<img class="bbic" src="http://boo-box.com/bbli" alt="[bb]" /></a>.</p>
<p>Para isso, antes de ficar desconectado, baixe a versão desejada do Django na sua <a class="bbli" href="http://sledge.boo-box.com/list/page/bWFjYm9vayUyQytzb255K3ZhaW9fIyNfYmFyXyMjX3RhZ2dpbmctdG9vbC13cF8jI18yODM0ODQ=-76">máquina<img class="bbic" src="http://boo-box.com/bbli" alt="[bb]" /></a>, 1.1.1 no meu caso.</p>
<pre lang="bash">$ wget http://www.djangoproject.com/download/1.1.1/tarball/</pre>
<p>Descompacte:</p>
<pre lang="bash">$ tar xvf Django-1.1.1.tar</pre>
<p>Acesse o diretório da documentação</p>
<pre lang="bash">$ cd Django-1.1.1/docs</pre>
<p>Instale o Sphinx, o criador de documentações para projetos Python.</p>
<pre lang="bash">$ sudo easy_install -U Sphinx</pre>
<p>* Caso também não tenha o easy_install, instale ele primeiro.</p>
<p>Construa e leia a documentação</p>
<pre lang="bash">$ make html</pre>
<p>Abra, através do seu navegador, o arquivo: <em>_build/html/index.html</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2010/django-docs-offline/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monitorando Processos em Erlang</title>
		<link>http://caioariede.com/2010/monitorando-processos-em-erlang</link>
		<comments>http://caioariede.com/2010/monitorando-processos-em-erlang#comments</comments>
		<pubDate>Wed, 14 Apr 2010 05:10:10 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[linux + livro]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=625</guid>
		<description><![CDATA[Erlang possui uma característica própria para manipular erros entre processos. Quando um processo termina, uma mensagem é enviada a todos os processos que estão ligados a ele.
Com essa característica, é possível criar estruturas hierárquicas em seus programas, onde alguns processos podem supervisionar outros processos, e manter certo controle. Por exemplo: reiniciar processos terminados por alguma [...]]]></description>
			<content:encoded><![CDATA[<p>Erlang possui uma característica própria para manipular erros entre processos. Quando um processo termina, uma mensagem é enviada a todos os processos que estão ligados a ele.</p>
<p>Com essa característica, é possível criar estruturas hierárquicas em seus programas, onde alguns processos podem supervisionar outros processos, e manter certo controle. Por exemplo: reiniciar processos terminados por alguma falha.</p>
<p>Basicamente, existem duas formas de monitorar processos em Erlang: utilizando interligações e monitores.</p>
<h2>Monitoramento por interligações</h2>
<p>Esse tipo de monitoramento é realizado através de processos interligados: os processos a serem monitorados, e o processo que os monitora.</p>
<pre lang="erlang">Process1 = spawn(?MODULE, loop, [0]),
spawn(?MODULE, monitor, [Process1])</pre>
<p>Aqui, chamamos o nosso processo de <em>Process1</em>, armazenamos o seu <em>Pid</em>, e logo criamos outro processo, que será utilizado para monitorar o processo <em>Process1</em>.</p>
<pre lang="erlang">loop(10) -&gt;
    exit(reason_here);

loop(Counter) -&gt;
    timer:sleep(random:uniform(500)),
    loop(Counter + 1).</pre>
<p>Temos acima, a função <em>loop/1</em>, que é a responsável pelo processo <em>Process1</em>. A função <em>loop/1</em> nada mais é do que um contador, que espera um determinado número de milisegundos antes de cada contagem. Ao chegar em 10, ela emite um sinal de erro: <em>reason_here</em>.</p>
<p>Sabendo que o comportamento de um processo em Erlang, em caso de falhas, é: emitir o sinal de erro, através de todos os processos interligados, o que devemos fazer aqui, é interligar o processo do monitor, ao processo <em>Process1</em>. Fazemos isso através da função <em>link/1</em>, como abaixo.</p>
<pre lang="erlang">monitor(Pid) -&gt;
    link(Pid).</pre>
<p>O que a função <em>link/1</em> faz aqui é ligar o processo atual, ao processo passado por parâmetro</p>
<p>Agora temos dois processos interligados: o <em>Process1</em> e o seu monitor, com isso, dizemos que quando o <em>Process1</em> terminar, ele informará ao processo monitor que ele também deve terminar, pois estão ligados.</p>
<p>Em Erlang, por padrão, quando um processo termina com um motivo diferente de <em>normal</em>, todos os processos interligados a ele devem terminar também, com o mesmo motivo. Mas você pode contornar isso, especificando uma flag no processo.</p>
<pre lang="erlang">process_flag(trap_exit, true)</pre>
<p>A flag <em>trap_exit</em>, faz com que todos os sinais de saída sejam transformados em mensagens. Assim podemos trata-los.</p>
<p>* Nota: A flag trap_exit não faz efeito caso o sinal de saída tenha o motivo <em>kill</em>. Saídas com o motivo <em>kill</em> fazem com que os processos interligados interminem incondicionalmente.</p>
<pre lang="erlang">monitor(Pid) -&gt;
    process_flag(trap_exit, true),
    link(Pid),
    receive
        {'EXIT', Pid, reason_here} -&gt;
            io:format("* process exit: ~p~n", [Pid])
    end.</pre>
<p>Agora podemos dizer sim, que o nosso processo monitor está monitorando o processo <em>Process1</em>.</p>
<p>O código completo do módulo de exemplo, ficaria assim:</p>
<pre lang="erlang">-module(proc_link).
-compile(export_all).

start() -&gt;
    Process1 = spawn(?MODULE, loop, [0]),
    Process2 = spawn(?MODULE, loop, [0]),
    spawn(?MODULE, monitor, [Process1]),
    spawn(?MODULE, monitor, [Process2]),
    ok.

loop(10) -&gt;
    exit(reason_here);

loop(Counter) -&gt;
    timer:sleep(random:uniform(500)),
    loop(Counter + 1).

monitor(Pid) -&gt;
    io:format("start monitoring: ~p~n", [Pid]),
    process_flag(trap_exit, true),
    link(Pid),
    receive
        {'EXIT', Pid, reason_here} -&gt;
            io:format("* process exit: ~p~n", [Pid])
    end.</pre>
<h2>Monitoramento através de monitores</h2>
<p>A vantagem do monitoramento através de monitores, é que você pode criar, facilmente, vários monitores para um único processo, devido ao fato dos monitores serem unidirecionais.</p>
<p>Ao contrário da função <em>link/1</em>, que chamada repetidas vezes não causará efeito. A função <em>erlang:monitor/2</em>, chamada repetidas vezes, criará uma série de novos monitores, retornando uma referência diferente para cada um deles.</p>
<pre lang="erlang">Process = spawn(?MODULE, loop, [0]),
Ref = erlang:monitor(process, Process)</pre>
<p>Aqui não é necessário especificar uma flag para o processo, com <em>process_flag(trap_exit, true)</em>.</p>
<p>Nesse exemplo, criei um monitor que, ao verificar que determinado processo falhou, o iniciará novamente, e assim monitorando-o novamente também, infinitas vezes.</p>
<pre lang="erlang">monitor(Ref) -&gt;
    receive
        {'DOWN', Ref, process, Pid, reason_here} -&gt;
            io:format("- process exit: ~p~n~n", [Pid]),
            NewRef = start_process(),
            monitor(NewRef)
    end.</pre>
<p>O código completo do módulo de exemplo, ficaria assim:</p>
<pre lang="erlang">-module(proc_monitor).
-compile(export_all).

start() -&gt;
    Ref = start_process(),
    monitor(Ref),
    ok.

start_process() -&gt;
    Process = spawn(?MODULE, loop, [0]),
    Ref = erlang:monitor(process, Process),
    io:format("| started process: ~p~n", [Process]),
    Ref.

loop(10) -&gt;
    exit(reason_here);

loop(Counter) -&gt;
    timer:sleep(random:uniform(1000)),
    loop(Counter + 1).

monitor(Ref) -&gt;
    io:format("| start monitoring process~n"),
    receive
        {'DOWN', Ref, process, Pid, reason_here} -&gt;
            io:format("- process exit: ~p~n~n", [Pid]),
            NewRef = start_process(),
            monitor(NewRef)
    end.</pre>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2010/monitorando-processos-em-erlang/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Estendendo módulos em Erlang</title>
		<link>http://caioariede.com/2010/estendendo-modulos-em-erlang</link>
		<comments>http://caioariede.com/2010/estendendo-modulos-em-erlang#comments</comments>
		<pubDate>Tue, 06 Apr 2010 00:32:51 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Erlang]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=616</guid>
		<description><![CDATA[A possibilidade de estender módulos em Erlang é interessante, e lembra alguns aspectos da programação orientada a objetos.
Qualquer módulo pode ser estendido, sem a necessidade de adicionar qualquer atributo a ele, apenas ao módulo que está estendendo-o, vejamos.
-module(test).
-extends(lists).
Veja que nesse caso, criamos um módulo chamado test, que estenderá o módulo lists.
$ erlc test.erl
Compilamos, e temos:
1&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>A possibilidade de estender módulos em Erlang é interessante, e lembra alguns aspectos da programação orientada a objetos.</p>
<p>Qualquer módulo pode ser estendido, sem a necessidade de adicionar qualquer atributo a ele, apenas ao módulo que está estendendo-o, vejamos.</p>
<pre lang="erlang">-module(test).
-extends(lists).</pre>
<p>Veja que nesse caso, criamos um módulo chamado <em>test</em>, que estenderá o módulo <em>lists</em>.</p>
<pre lang="bash">$ erlc test.erl</pre>
<p>Compilamos, e temos:</p>
<pre lang="erlang">1&gt; lists:sum([2,2]).
4
2&gt; test:sum([2,2]).
4</pre>
<p>Agora, indo para um exemplo mais prático, temos um módulo chamado <em>product</em> (produto), que será estendido posteriormente pelo módulo <em>tshirt</em> (camiseta).</p>
<pre lang="erlang">-module(product).
-export([new/2, name/1, value/1]).

-include("product.hrl").

new(_, Value) when not is_float(Value) -&gt;
    {badarg, Value};

new(Name, Value) -&gt;
    #product_info{name=Name, value=Value}.

name(#product_info{name=Name}) -&gt;
    Name.

value(#product_info{value=Value}) -&gt;
    Value.</pre>
<p>Observe que nesse módulo, exportamos 3 funções:</p>
<ul>
<li>new/2 &#8211; cria e retorna um novo produto</li>
<li>name/1 &#8211; retorna o nome de um produto</li>
<li>value/2 &#8211; retorna o valor de um produto</li>
</ul>
<p>Vale notar também, que utilizamos um arquivo externo (product.hrl), que contém informações a serem compartilhadas entre os módulos &#8220;filhos&#8221;.</p>
<pre lang="erlang">-record(product_info, {name, value = 0.0, type = undefined, details = undefined}).
-record(product_details, {sizes, colors}).</pre>
<p>Podemos abrir a shell do Erlang para apreciarmos o nosso novo módulo:</p>
<pre lang="bash">$ erl</pre>
<pre lang="erlang">1&gt; c(product).
{ok,product}
2&gt; Produto = product:new("Camiseta", 20,0).
{product_info,"Camiseta",20.0,undefined,undefined}
3&gt; product:name(Produto).
"Camiseta"
4&gt; product:value(Produto).
20.0</pre>
<p>Até aqui, o que temos é um registro de um produto genérico, sem detalhes. Para adicionarmos mais detalhes a esse produto, sugiro estender esse módulo, adicionando tais detalhes.</p>
<p>Pode-se ver que já foram reservados 2 espaços no registro do produto, preenchidos por padrão com o valor <em>undefined</em>.</p>
<pre lang="erlang">{product_info,"Camiseta",20.0,undefined,undefined}</pre>
<p>Ambos serão preenchidos com os respectivos valores: <em>type</em> (tipo) e <em>details</em> (detalhes).</p>
<p>Criamos então um novo módulo, chamado <em>tshirt</em> (camiseta), que estende o módulo <em>product</em> (produto).</p>
<pre lang="erlang">-module(tshirt)
-export([new/4,sizes/1,colors/1]).

-extends(product).

-include("product.hrl").

-define(base, ?BASE_MODULE).

new(Name, Value, Sizes, Colors) -&gt;
    case ?base:new(Name, Value) of
        {badarg, _} = Fail -&gt;
            Fail;
        Product -&gt;
            Details = #product_details
            {
                sizes=Sizes,
                colors=Colors
            },
            Product#product_info{type=tshirt,details=Details}
    end.

sizes(#product_info{details=#product_details{sizes=Sizes}}) -&gt;
    Sizes.

colors(#product_info{details=#product_details{colors=Colors}}) -&gt;
    Colors.</pre>
<p>Aqui, defini um macro para facilitar o desenvolvimento, chamado <em>base</em>, que nada mais é que um atalho para outro macro chamado <em>BASE_MODULE</em>.</p>
<p>Prosseguindo, sobrecarreguei a função <em>new/1</em> do módulo <em>product</em>, adicionando o tipo do produto, e alguns detalhes como <em>sizes</em> (tamanhos) e <em>colors</em> (cores).</p>
<pre lang="erlang">
1> c(tshirt).
{ok,tshirt}
2> Camiseta = tshirt:new("Camiseta", foo, [small, large], [black, white]).
{badarg, foo}
3> f(Camiseta). % limpar a variável, já que já foi utilizada.
ok
4> Camiseta = tshirt:new("Camiseta", 15.90, [small, large], [black, white]).
{product_info,"Camiseta",15.9,tshirt,
              {product_details,[small,large],[black,white]}
5> tshirt:name(Camiseta).
"Camiseta"
6> tshirt:sizes(Camiseta).
[small,large]
7> tshirt:colors(Camiseta).
[black,white]
8> tshirt:value(Camiseta).
15.9
</pre>
<p>Se quiser praticar um pouco mais, que tal criar outro módulo? Outro tipo de produto? Boa prática.</p>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2010/estendendo-modulos-em-erlang/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bitwise Operators</title>
		<link>http://caioariede.com/2009/bitwise-operators</link>
		<comments>http://caioariede.com/2009/bitwise-operators#comments</comments>
		<pubDate>Mon, 09 Nov 2009 01:53:11 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=578</guid>
		<description><![CDATA[Uma forma muito elegante de armazenar uma série de regras, utilizando um só valor, é utilizando os Bitwise Operators.
O PHP faz isso a um bom tempo já, e um bom exemplo é a função error_reporting, onde podemos utilizar uma série de regras para denominar quais os erros devem ser reportados.
error_reporting(E_ERROR &#124; E_WARNING);
No exemplo acima, foi [...]]]></description>
			<content:encoded><![CDATA[<p>Uma forma muito elegante de armazenar uma série de regras, utilizando um só valor, é utilizando os Bitwise Operators.</p>
<p>O PHP faz isso a um bom tempo já, e um bom exemplo é a função <a href="http://br2.php.net/manual/en/function.error-reporting.php">error_reporting</a>, onde podemos utilizar uma série de regras para denominar quais os erros devem ser reportados.</p>
<pre lang="php">error_reporting(E_ERROR | E_WARNING);</pre>
<p>No exemplo acima, foi denominado que somente os tipos de erro E_ERROR e E_WARNING devem ser reportados. Se quiséssemos que o tipo de erro E_PARSE fosse reportado também, bastariamos adiciona-lo na regra:</p>
<pre lang="php">error_reporting(E_ERROR | E_WARNING | E_PARSE);</pre>
<h3>Mas como isso funciona?</h3>
<p>Utilizando como exemplo, essas contantes do PHP contém os seguintes valores:</p>
<pre>E_ERROR		1
E_WARNING	2
E_PARSE		4</pre>
<p>O operador | é uma operação &#8220;Or&#8221; inclusiva, o que indica que, <em>todo bit que estiver presente em A <strong>ou</strong> B, será utilizado</em>.</p>
<pre>0001 ou
0010
=
0011</pre>
<p>Podemos verificar o valor em binário de cada uma das constantes, utilizando a função <a href="http://br2.php.net/manual/en/function.printf.php">printf</a>:</p>
<pre lang="bash">$ php -r 'printf("%04b", E_ERROR);'
0001
$ php -r 'printf("%04b", E_WARNING);'
0010
$ php -r 'printf("%04b", E_PARSE);'
0100</pre>
<p>Portanto, voltando ao exemplo inicial da função error_reporting, temos:</p>
<pre lang="php">E_ERROR | E_WARNING</pre>
<p>E se fizermos a operação, obteremos 0011, vejamos:</p>
<pre lang="php">$ php -r 'printf("%04b", E_ERROR | E_WARNING);'
0011</pre>
<p>E como verificamos se <code>E_ERROR</code> esta contido em <code>E_ERROR | E_WARNING</code>?</p>
<p>Simples. Basta utilizar o operador &amp;, que realiza uma operação &#8220;And&#8221;, onde <em>somente são utilizados os bits presentes em A <strong>e</strong> B</em>.</p>
<pre lang="php">(E_ERROR | E_WARNING) &amp; E_ERROR</pre>
<p>Traduzindo em bits, ficaria:</p>
<pre>0011 e
0001
=
0001</pre>
<p>Veja que o resultado tem o mesmo valor de B, e é assim que funciona, basta comparar <code>E_ERROR</code> com o resultado de <code>(E_ERROR | E_WARNING) &amp; E_ERROR</code>.</p>
<p>Agora em PHP, já que um exemplo vale mais que mil palavras:</p>
<pre lang="php">if (E_ERROR == ((E_ERROR | E_WARNING) &amp; E_ERROR))
{
	echo 'E_ERROR presente nas regras';
}</pre>
<h3>Criando a sua própria série de regras</h3>
<p>Imagine uma situação, onde você possui um sistema com vários usuários, e cada usuário pode conter as permissões P_READ (leitura), P_WRITE (escrita), P_REMOVE (remoção).</p>
<p>Criamos então, uma permissão &#8220;base&#8221;, chamada P_NONE (nada).</p>
<pre lang="php">
define('P_NONE',	100);
</pre>
<p>E em seguida, as outras permissões:</p>
<pre lang="php">
define('P_READ',	P_NONE << 1);
define('P_WRITE',	P_NONE << 2);
define('P_REMOVE',	P_NONE << 3);
</pre>
<p>Logo, podemos criar uma regra para um usuário:</p>
<pre lang="php">
$mode = P_READ | P_WRITE;
</pre>
<p>E armazena-la em um banco de dados. Aqui utilizei um campo <code>int</code>, em um banco de dados MySQL.</p>
<pre lang="php">
mysql_query("update users set mode = $mode where id = $id");
</pre>
<p>Posteriormente, você pode listar os usuários que tem permissão para escrita:</p>
<pre lang="php">
$mode = P_WRITE;
$users = mysql_query("select * from users where (mode &#038; $mode) = $mode");
</pre>
<p>Para verificar com PHP:</p>
<pre lang="php">
if (P_READ == ($user->mode &amp; P_READ))
{
	echo 'Este usuário possui permissão para leitura.';
}
</pre>
<h3>Conclusão</h3>
<p>Você pode especificar várias e várias regras, utilizando apenas um valor, uma variável ou um campo no banco de dados. Basta utilizar alguns bits e operações lógicas.</p>
<p>Para maiores informações sobre os Bitwise Operators do PHP, basta acessar a URL:</p>
<p><a href="http://br2.php.net/language.operators.bitwise">http://br2.php.net/language.operators.bitwise</a></p>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2009/bitwise-operators/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Usando o Git para deploy de sites</title>
		<link>http://caioariede.com/2009/usando-git-para-deploy-sites</link>
		<comments>http://caioariede.com/2009/usando-git-para-deploy-sites#comments</comments>
		<pubDate>Mon, 02 Nov 2009 16:48:40 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=568</guid>
		<description><![CDATA[Neste artigo, assume-se que você tenha um site hospedado em um servidor, que esteja rodando Git e SSH.
Repositório local
Crie um repositório local normalmente, caso já tenha, pule esta etapa.
$ mkdir meusite.com.br
$ cd meusite.com.br
$ git init
Repositório remoto
Neste exemplo, vou utilizar a estrutura que o Plesk utiliza para aos domínios.
Precisamos de uma pasta que fique fora de [...]]]></description>
			<content:encoded><![CDATA[<p>Neste artigo, assume-se que você tenha um site hospedado em um <a href="http://sledge.boo-box.com/list/page/bGludXhfIyNfYm94XyMjX3RhZ2dpbmctdG9vbC13cF8jI18=-48" class="bbli">servidor<img src="http://boo-box.com/bbli" alt="[bb]" class="bbic" /></a>, que esteja rodando Git e SSH.</p>
<h2>Repositório local</h2>
<p>Crie um repositório local normalmente, caso já tenha, pule esta etapa.</p>
<pre lang="bash">$ mkdir meusite.com.br
$ cd meusite.com.br</pre>
<pre lang="bash">$ git init</pre>
<h2>Repositório remoto</h2>
<p>Neste exemplo, vou utilizar a estrutura que o Plesk utiliza para aos domínios.</p>
<p>Precisamos de uma pasta que fique fora de visibilidade da web, portanto, utilizarei a pasta private, que fica na raiz do domínio.</p>
<pre lang="bash">$ cd /var/www/vhosts/meusite.com.br/private</pre>
<p>Criamos a pasta do repositório:</p>
<pre lang="bash">$ mkdir meusite.git/
$ cd meusite.git/</pre>
<p>Iniciamos um repositório &#8220;crú&#8221; no mesmo local:</p>
<pre lang="bash">$ git --bare init</pre>
<p>E então configuramos o Git com as seguintes opções:</p>
<pre lang="bash">$ git config core.worktree /var/www/vhosts/meusite.com.br/httpdocs
$ git config core.bare false
$ git config receive.denycurrentbranch ignore</pre>
<p>Configuramos também o Hook que será executado após toda atualização:</p>
<pre lang="bash">$ cat > hooks/post-receive
#!/bin/bash
SITE_PATH=/var/www/vhosts/meusite.com.br

cd $SITE_PATH/httpdocs
git --work-tree=. --git-dir=$SITE_PATH/private/meusite.git checkout -f</pre>
<p>E colocamos permissão para execução:</p>
<pre lang="bash">$ chmod +x hooks/post-receive</pre>
<h2>Processo de atualização</h2>
<p>O processo para atualização é bem simples. Primeiro criamos outro &#8220;master&#8221; branch, chamado &#8220;web&#8221;.</p>
<pre lang="bash">$ git remote add web ssh://meusite@servidor.com.br/var/www/vhosts/meusite.com.br/private/meusite.git</pre>
<p>Em seguida, realize qualquer alteração:</p>
<pre lang="bash">$ echo "funcionou!" > teste.html
$ git commit -am 'teste'</pre>
<pre lang="bash">$ git push web +master:refs/heads/master</pre>
<p>Tente acessar: http://meusite.com.br/teste.html</p>
<p>Após isso, você pode atualizar somente com &#8220;git push web&#8221;, configurando:</p>
<pre lang="bash">$ git config push.default current</pre>
<p>Quaisquer dúvidas sobre o Git, podem ser retiradas através do canal #git na irc.freenode.net.</p>
<p>Este material foi baseado no <a href="http://toroid.org/ams/git-website-howto">Using Git to manage a web site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2009/usando-git-para-deploy-sites/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Criando o seu próprio encurtador de URL&#8217;s usando a API do 307.to</title>
		<link>http://caioariede.com/2009/criando-o-seu-proprio-encurtador-de-urls-usando-php-e-a-api-do-307to</link>
		<comments>http://caioariede.com/2009/criando-o-seu-proprio-encurtador-de-urls-usando-php-e-a-api-do-307to#comments</comments>
		<pubDate>Fri, 21 Aug 2009 18:51:45 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=547</guid>
		<description><![CDATA[Demonstrar de forma simples objetiva, que é totalmente possível criar o seu próprio encurtador de URL&#8217;s de maneira simples, sem se preocupar com banco de dados, estatísticas, etc&#8230;
A explicação demonstra como requisitar links, como criar uma página de erro personalizada, e como utilizar o seu domínio para acessa-los.
Porém não há limites. Basta usar o seu [...]]]></description>
			<content:encoded><![CDATA[<p>Demonstrar de forma simples objetiva, que é totalmente possível criar o seu próprio encurtador de URL&#8217;s de maneira simples, sem se preocupar com banco de dados, estatísticas, etc&#8230;</p>
<p>A explicação demonstra como requisitar links, como criar uma página de erro personalizada, e como utilizar o seu domínio para acessa-los.</p>
<p>Porém não há limites. Basta usar o seu conhecimento junto da sua criatividade para criar o seu próprio encurtador, sem maiores preocupações.</p>
<p><a href="http://caioariede.com/arquivos/my-shortener.zip">Faça o download do código completo.</a></p>
<h3>Vamos tomar como exemplo o seguinte cenário:</h3>
<p>Você possui um blog ou uma agência digital, e quer espalhar os seus links através de um domínio próprio, no qual os seus clientes confiem meramente, e que não tenham medo de acessar achando que é algum vírus.</p>
<h3>Neste tutorial, teremos 4 arquivos:</h3>
<p><strong>.htaccess</strong></p>
<p><em>Para melhor o &#8220;visual&#8221; das URL&#8217;s</em></p>
<p><strong>307.class.php</strong><br />
<em>Classe para manipulação de links do 307.to</em></p>
<p><strong>shorturl.php</strong><br />
<em>Onde utilizamos a classe do 307.to</em></p>
<p><strong>404.php</strong><br />
<em>Página de erro personalizada</em></p>
<h3>A classe do 307</h3>
<p>A classe <em>class307</em> possui os seguintes métodos:</p>
<pre lang="php">public function set_format($format)</pre>
<p>Específica o formato do retorno, podendo ser json ou text.</p>
<pre lang="php">public function set_account_key($key)</pre>
<p>Específica a chave da sua conta.</p>
<pre lang="php">public function get($u)</pre>
<p>Requisita um link.</p>
<pre lang="php">public function post($u)</pre>
<p>Cria um link, se <em>account_key</em> for específicado o link será anexado a sua conta.</p>
<h3>Utilizando a classe</h3>
<p>Esse é o script principal do sistema, onde é utilizada a classe do 307 para requisitar os links.</p>
<p>Como você pode ver abaixo, o método <em>set_account_key</em> foi comentado para fins de demonstração, porém ele é extremamente importante, pois permita que somente os links criados por você possam ser acessados através do seu domínio.</p>
<pre lang="php">&lt;?php

require '307.class.php';

$class307 = new class307;
// optional
//$class307-&gt;set_account_key('&lt;YOUR ACCOUNT KEY&gt;');

try
{
	if (is_array($_GET['link']) || empty($_GET['link']))
	{
		throw new Exception();
	}

	$link = $_GET['link'];
	$url = $class307-&gt;get($link);

	//header('Location: ' . $url, TRUE, 307);
	header('Location: http://307.to/' . $link);
}
catch (Exception $error)
{
	include '404.php';
}</pre>
<p>Indo logo para a parte mais importante do código, verificamos se a variável &#8220;link&#8221; é do tipo Array ou se esta vazia. Caso um dos dois casos ocorra, geramos uma exceção.</p>
<pre lang="php">if (is_array($_GET['link']) || empty($_GET['link']))
{
...
}</pre>
<p>Logo depois, requisitamos o endereço através do método <strong>get</strong>:</p>
<pre lang="php">$url = $class307-&gt;get($link);</pre>
<p>Caso o link não exista, o método <strong>get</strong> gerará uma exceção, caso contrário continuará a execução.</p>
<p>Veja que ocorrendo alguma exceção, o arquivo <strong>404.php</strong> será chamado e logo em seguida a execução terminará.</p>
<h3>Utilizando a URL retornada</h3>
<p>Se o método <strong>get</strong> conseguir encontrar a URL, ela será armazenada na variável <strong>$url</strong>, no script de exemplo, eu somente utilizei o método <em>get</em> para verificar se o link existe ou não, e então redirecionei para a página do próprio 307.to onde serão geradas estatísticas de acesso e tudo mais. Mas nada impede que você faça a sua própria coleta de estatísticas e então redirecione o usuário para a página final.</p>
<h3>Testando o script</h3>
<p>Para testar o script, basta realizar as seguintes requisições:</p>
<pre>http://seusite.com.br/shorturl.php?link=rG</pre>
<p>e</p>
<pre>http://seusite.com.br/shorturl.php?link=ESSE_LINK_NAO_EXISTE</pre>
<p>Veja que a primeira requisição irá redirecionar para http://307.to/rG, enquanto a segunda exibirá uma página de erro (404.php).</p>
<h3>Personalizando a URL (Escondendo o shorturl.php)</h3>
<p>Para encurtar o link, você pode usar algumas regras no .htaccess, que permitem que você esconda o nome do arquivo, no caso &#8220;shorturl.php&#8221;.</p>
<p>.htaccess</p>
<pre lang="apache">RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

RewriteRule ^(.*)$ shorturl.php?link=$1</pre>
<p>Agora para acessar o seu link, basta requisitar o endereço:</p>
<pre>http://seusite.com.br/rG</pre>
<h3>Personalizando a página de erro (404.php)</h3>
<p>Para personalizar a página de erro, basta ter um pouco de conhecimento de HTML:</p>
<p>404.php</p>
<pre lang="php">&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="content-type" content="text/html;charset=UTF-8" /&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;Erro - Link não encontrado&lt;/h1&gt;

&lt;em&gt;
&lt;?php
printf('%d - %s', $error-&gt;getCode(), $error-&gt;getMessage());
?&gt;
&lt;/em&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<h3>Download do código</h3>
<p>Para fazer o download do código completo citado, basta clicar no link abaixo:</p>
<p><a href="http://caioariede.com/arquivos/my-shortener.zip">Download<br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2009/criando-o-seu-proprio-encurtador-de-urls-usando-php-e-a-api-do-307to/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Instalando o emesene no Gentoo Linux</title>
		<link>http://caioariede.com/2009/instalando-o-emesene-no-gentoo-linux</link>
		<comments>http://caioariede.com/2009/instalando-o-emesene-no-gentoo-linux#comments</comments>
		<pubDate>Sun, 26 Jul 2009 17:51:41 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Dicas Rápidas]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=533</guid>
		<description><![CDATA[O emesene (emesene.org), não esta disponível oficialmente nos repositórios do Gentoo, porém pode ser instalado através de um Overlay.
Um Overlay é uma árvore separada da árvore principal de pacotes do Gentoo, mantida por terceiros.
O Overlay onde o emesene esta disponível, chama-se dottout, e requer a instalação do git.
Portanto, primeiramente instale o git:
# emerge dev-util/git
* Vá [...]]]></description>
			<content:encoded><![CDATA[<p>O <strong>emesene</strong> (<a href="http://emesene.org/">emesene.org</a>), não esta disponível oficialmente nos repositórios do Gentoo, porém pode ser instalado através de um Overlay.</p>
<p>Um <strong>Overlay</strong> é uma árvore separada da árvore principal de pacotes do Gentoo, mantida por terceiros.</p>
<p>O Overlay onde o emesene esta disponível, chama-se <strong>dottout</strong>, e requer a instalação do <strong>git</strong>.</p>
<p>Portanto, primeiramente instale o <strong>git</strong>:</p>
<pre># emerge dev-util/git</pre>
<p>* Vá tomar um cafézinho, pois demora um pouco!</p>
<p>Depois do café, adicione o Overlay, através do <strong>layman</strong>:</p>
<pre># layman -a dottout</pre>
<p>Depois disso, antes de instalar o emesene, é preciso satisfazer uma dependência, que é a <strong>libmimic</strong>.</p>
<p>Crie o arquivo /etc/portage/package.keywords/libmimic, especificando a arquitetura da sua máquina, no meu caso &#8220;~x86&#8243;:</p>
<pre># cat &gt;/etc/portage/package.keywords/libmimic
media-libs/libmimic ~x86</pre>
<p>E em seguida dê emerge:</p>
<pre># emerge media-libs/libmimic</pre>
<p>Após a instalação, especifique também a arquitetura da sua máquina para a instalação do emesene:</p>
<pre># cat &gt;/etc/portage/package.keywords/emesene
net-im/emesene ~x86</pre>
<p>E então, dê emerge:</p>
<pre># emerge emesene</pre>
<p>Vá até o diretório do emesene, normalmente localizado em /usr/share/emesene, e execute o <strong>setup.py</strong>:</p>
<pre># cd /usr/share/emesene
# python setup.py build_ext -i</pre>
<p>emesene instalado!</p>
<p>* Lembre-se, o emesene não roda como usuário <strong>root</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2009/instalando-o-emesene-no-gentoo-linux/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajudando a traduzir o site do Kohana PHP</title>
		<link>http://caioariede.com/2009/ajudando-a-traduzir-o-site-do-kohana-php</link>
		<comments>http://caioariede.com/2009/ajudando-a-traduzir-o-site-do-kohana-php#comments</comments>
		<pubDate>Thu, 18 Jun 2009 23:01:25 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Kohana]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=530</guid>
		<description><![CDATA[Esclarecerei aqui, como ajudar na tradução do site do projeto Kohana PHP.
Primeiramente, baixe e instale o Subversion.
Caso você utilize Ubuntu/Linux, Debian, ou alguma distribuição parecida, você pode instalar através do terminal, usando o comando:
sudo apt-get install subversion
Caso você utilize outra distribuição, ou Windows, mais informações para download estão disponíveis em http://subversion.tigris.org/getting.html#binary-packages
Após a instalação
Após instalar o [...]]]></description>
			<content:encoded><![CDATA[<p>Esclarecerei aqui, como ajudar na tradução do site do projeto Kohana PHP.</p>
<p>Primeiramente, baixe e instale o <a href="http://pt.wikipedia.org/wiki/Subversion">Subversion</a>.</p>
<p>Caso você utilize Ubuntu/Linux, Debian, ou alguma distribuição parecida, você pode instalar através do terminal, usando o comando:</p>
<pre>sudo apt-get install subversion</pre>
<p>Caso você utilize outra distribuição, ou Windows, mais informações para download estão disponíveis em <a href="http://subversion.tigris.org/getting.html#binary-packages">http://subversion.tigris.org/getting.html#binary-packages</a></p>
<h3>Após a instalação</h3>
<p>Após instalar o Subversion, caso esteja no Linux, abra o terminal.</p>
<p>Caso esteja no Windows, vá em Iniciar &gt; Executar, digite &#8220;cmd&#8221; e execute.</p>
<p>Crie uma pasta, no lugar que desejar. Aqui eu optei por ~/kohana.</p>
<p>Esta é a pasta onde você baixará os arquivos do site do Kohana, para fazer isso, vá até a pasta e execute o comando abaixo:</p>
<pre>svn co http://source.kohanaphp.com/branches/website/application kohana-website</pre>
<p>Esse comando baixará somente a pasta <em>application</em>, pois fora dela, não há conteúdo a ser traduzido.</p>
<p>Após o término, você terá os arquivos em sua máquina.</p>
<h3>Realizando o primeiro Patch</h3>
<p>O Patch, ou Correção, nada mais é que a diferença entre o arquivo antigo e o novo (modificado).</p>
<p>Portanto, você irá modificar o arquivo em questão, e realizar o patch através do SVN mesmo. Ele possui uma ferramenta que faz isso.</p>
<p>Para montar esse Mini How To, eu realizarei um patch, no arquivo: <em>i18n/pt_BR/layout.php</em></p>
<p>Realizei algumas alterações no arquivo, comparando com a versão atual em inglês  <em>i18n/en_US/layout.php</em>, adicionei duas traduções que faltavam: <em>menu_redmine</em> e <em>menu_projects</em>.</p>
<p>Após isso, é bastante simples. Somente fui até a pasta, através do terminal e gerei o patch, com o comando:</p>
<pre>svn diff i18n/pt_BR/layout.php &gt; patch_i18n_pt_BR_layout.patch</pre>
<p>Eu acho importante manter uma padronização no nome dos patches.</p>
<h3>Finalizando, envio do Patch</h3>
<p>Foi criado um Ticket no site do Kohana, onde devem ser adicionados os patches, para isso basta se cadastrar no site, ir até o Ticket e enviar o arquivo.</p>
<p>O Ticket criado para isso, foi o <a href="http://dev.kohanaphp.com/issues/1799">#1799</a>.</p>
<p>Espero que esse documento seja de bastante utilidade, e que todos consigam compreender bem.</p>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2009/ajudando-a-traduzir-o-site-do-kohana-php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kohana PHP: Brincando com os Hooks</title>
		<link>http://caioariede.com/2009/kohana-php-brincando-com-os-hooks</link>
		<comments>http://caioariede.com/2009/kohana-php-brincando-com-os-hooks#comments</comments>
		<pubDate>Tue, 26 May 2009 13:59:11 +0000</pubDate>
		<dc:creator>Caio Ariede</dc:creator>
				<category><![CDATA[Kohana]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://caioariede.com/?p=525</guid>
		<description><![CDATA[Os Hooks do Kohana PHP são realmente úteis. Demonstrarei como utiliza-los, exemplificando a sua utilização em uma situação real.
O que são Hooks?
Hooks são arquivos que são carregados na inicialização do Kohana, permitindo você adicionar ou modificar funções, chamadas callbacks, que são disparadas pelo Kohana.
Essas funções (ou callbacks) são colocados em uma lista dentro do seu [...]]]></description>
			<content:encoded><![CDATA[<p>Os Hooks do <a href="http://kohanaphp.com/">Kohana <a href="http://sledge.boo-box.com/list/page/ZnJhbWV3b3JrJTJDK3BocCs1JTJDK2VkaXRvciUyQytsaW51eCUyQytvcmllbnRhJUU3JUUzbythK29iamV0b3NfIyNfYm94XyMjX3RhZ2dpbmctdG9vbC13cF8jI18yODM0ODQ=-136" class="bbli">PHP<img src="http://boo-box.com/bbli" alt="[bb]" class="bbic" /></a></a> são realmente úteis. Demonstrarei como utiliza-los, exemplificando a sua utilização em uma situação real.</p>
<h3>O que são Hooks?</h3>
<p>Hooks são arquivos que são carregados na inicialização do Kohana, permitindo você adicionar ou modificar funções, chamadas <em>callbacks</em>, que são disparadas pelo Kohana.</p>
<p>Essas funções (ou <em>callbacks</em>) são colocados em uma lista dentro do seu evento específico, chamada Event Queue.</p>
<h3>O que são Eventos?</h3>
<p>Durante a inicialização, e até mesmo durante a execução, em alguns casos, o núcleo do Kohana dispara vários eventos. Eventos que são definidos pelo próprio núcleo.</p>
<p>Você pode ver a lista completa de eventos disparados pelo Kohana, na documentação: <a href="http://docs.kohanaphp.com/general/events">http://docs.kohanaphp.com/general/events</a></p>
<h3>Habilitando os Hooks no Kohana</h3>
<p>Para começar a brincar com os Hooks, é necessário habilitá-los. Para isso, basta configurar a opção <em>enable_hooks</em> no <em>config/config.php</em>, para <em>TRUE</em>:</p>
<pre lang="php">$config['enable_hooks'] = TRUE;</pre>
<h3>Exemplo de utilização de Hooks</h3>
<p>Suponha que tenhamos um site com sistema de autenticação.</p>
<p>Quando um visitante chega, ele é logo direcionado ao <em>controller</em> padrão, definido em <em>config/routes.php</em>, pela seguinte linha:</p>
<pre lang="php">$config['_default'] = 'site';</pre>
<p style="text-align: justify;">O <em>controller</em> site, contém os métodos (páginas): Home (com formulário de autenticação), Quem Somos, Ajuda&#8230;</p>
<p>Agora, o que fazer quando este visitante já estava autenticado anteriormente, e retorna ao site?</p>
<p>A solução mais simples a se fazer, é criar uma verificação no <em>controller</em> site, e caso o usuário já esteja autenticado ele será redirecionado à outro <em>controller</em>, chamado <span style="text-decoration: underline;">painel</span>.</p>
<h4>Problema</h4>
<p>A cada redirecionamento do <em>controller</em> site ao controller <em>painel</em>, seria realizado outra inicialização do sistema completo.</p>
<h4>Solução</h4>
<p>Uma solução elegante e correta para isso, é utilizar um Hook para informar ao <em>Router</em>, o <em>controller</em> correto a ser chamado.</p>
<p>O <em>Router</em> é quem define através da URL, qual <em>controller</em> deverá ser chamado, portanto a única coisa que terá de ser feita, é dizer à ele qual <em>controller</em> ele deverá chamar.</p>
<p>Criamos então, o arquivo <em>hooks/site.php</em>, o nome não importa, a não ser por fácil identificação posteriormente.</p>
<p>No arquivo, é especificado que no momento do evento <em>system.routing</em>, uma função (leia-se <em>callback</em>) será chamada, antes do <em>Router::setup</em>.</p>
<p>Esse <em>callback</em> definirá o <em>controller</em> correto à ser carregado.</p>
<pre lang="php">&lt;?php defined('SYSPATH') OR die('No direct access allowed.');

function hook_define_controller_padrao()
{
	if (!empty(Router::$current_uri)) return;
	if (Session::instance()-&gt;get('user'))
		// usuário logado
		Router::$current_uri = 'painel';
}</pre>
<p>Você pode também impossibilitar o acesso à página de autenticação, quando o usuário já estiver autenticado, modificação a função <em>callback</em> acima, da seguinte forma:</p>
<pre lang="php">function hook_define_controller_padrao()
{
	$logado = Session::instance()-&gt;get('user');
	if (empty(Router::$current_uri) &amp;&amp; $logado)
		// usuário autenticado
		Router::$current_uri = 'painel';
	elseif (Router::$current_uri == 'site/login' &amp;&amp; $logado)
		// exibir "página não encontrada"
		Event::run('system.404');
}</pre>
<p>Criada a função, é necessário que seja adicionada à lista de eventos a serem realizados, isso pode ser feito logo abaixo da função, ou no final do arquivo Hook.</p>
<pre lang="php">Event::add_before(
	'system.routing',
	array('Router', 'setup'),
	'hook_define_controller_padrao'
);</pre>
<p>Existe também como definir novos eventos, mas isso fica para outro artigo, pois este é somente uma introdução sobre o assunto.</p>
<p>Utilize os Hooks sempre que possível, eles poderão reduzir inúmeras linhas no seu código, tornando-o mais enxuto, legível e organizado.</p>
]]></content:encoded>
			<wfw:commentRss>http://caioariede.com/2009/kohana-php-brincando-com-os-hooks/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
