<?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>Ruby Vault</title>
	
	<link>http://www.tbueno.com/blog</link>
	<description>Explorando o maravilhoso mundo de Ruby</description>
	<lastBuildDate>Tue, 24 Aug 2010 03:02:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Buenoruby" /><feedburner:info uri="buenoruby" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>Buenoruby</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>RS on Rails 2010</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/05zrrKvS4jE/</link>
		<comments>http://www.tbueno.com/blog/sinatra/2010/08/rs-on-rails-2010/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 03:02:44 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rack]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Sinatra]]></category>
		<category><![CDATA[Eventos]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=332</guid>
		<description><![CDATA[O RS on Rails desse ano foi um sucesso absoluto. Auditório com ótima ocupação, palestras inspiradas e lightning talks interessantes marcaram esta segunda edição do evento. Deixo aqui meus agradecimentos aos organizadores e ao público presente. Abaixo, segue minha apresentação sobre aplicações Rack. Aplicações Rack &#8211; RS on Rails 2010 View more presentations from thibusil.]]></description>
			<content:encoded><![CDATA[<p>O <a href="http://www.rsrails.com.br/">RS on Rails</a> desse ano foi um sucesso absoluto. Auditório com ótima ocupação, palestras inspiradas e <em>lightning talks</em> interessantes marcaram esta segunda edição do evento.</p>
<p>Deixo aqui meus agradecimentos aos organizadores e ao público presente. Abaixo, segue minha apresentação sobre aplicações Rack.</p>
<div style="width:425px" id="__ss_5042732"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/thibusil/rack-rs-on-rails" title="Aplicações Rack - RS on Rails 2010">Aplicações Rack &#8211; RS on Rails 2010</a></strong><object id="__sse5042732" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rack-rsonrails-100823210931-phpapp02&#038;stripped_title=rack-rs-on-rails" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5042732" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rack-rsonrails-100823210931-phpapp02&#038;stripped_title=rack-rs-on-rails" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/thibusil">thibusil</a>.</div>
</div>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/05zrrKvS4jE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/sinatra/2010/08/rs-on-rails-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/sinatra/2010/08/rs-on-rails-2010/</feedburner:origLink></item>
		<item>
		<title>Estou Vivo ( E Melhor do Que Nunca)</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/UebIcUk5BpY/</link>
		<comments>http://www.tbueno.com/blog/blog/2009/12/estou-vivo-e-melhor-do-que-nunca/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 19:22:32 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Eventos]]></category>
		<category><![CDATA[Vagas]]></category>
		<category><![CDATA[Empregos]]></category>
		<category><![CDATA[Off-topic]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=309</guid>
		<description><![CDATA[Andei extremamente relapso em relação a este blog, e esse post é um pedido de desculpa aos leitores. O fato é que este segundo semestre de 2009 foi um turbilhão (no bom sentido) na minha vida. Em alguns meses fiz muito mais coisas que havia feito em anos. Entre elas, posso citar algumas realizações importantes. [...]]]></description>
			<content:encoded><![CDATA[<p>Andei extremamente relapso em relação a este blog, e esse post é um pedido de desculpa aos leitores.</p>
<p>O fato é que este segundo semestre de 2009 foi um turbilhão (no bom sentido) na minha vida. Em alguns meses fiz muito mais coisas que havia feito em anos. Entre elas, posso citar algumas realizações importantes.</p>
<h2>ThoughtWorks</h2>
<p><img alt="" src="http://www.tech2morrow.org/images/thoughtworks.jpg" title="ThoughtWorks" class="alignnone" width="265" height="101" /></p>
<p>Após 5 anos trabalhando na <a href="http://www.hp.com">HP</a>, anuncio feliz que estou me transferindo para a <a href="http://www.thoughtworks.com/">ThoughtWorks</a>! Me sinto extremamente orgulhoso de sair de uma empresa da importância da HP e assumir novos desafios no recém criado escritório brasileiro da TW. </p>
<h2>Mestrado</h2>
<p>Após quase pirar tendo que trabalhar 40 horas semanais e cumprir a agenda de trabalhos/aulas/provas do mestrado, finalmente posso dizer que estou prestes a vencer a primeira etapa do processo todo. Agora terei &#8220;apenas&#8221; a dissertação pela frente. :-)</p>
<h2>Realizações Técnicas</h2>
<p>Como se as atividades citadas acima não fossem suficiente, estou quase acabando o desenvolvimento de meu primeiro aplicativo para Iphone e já posso considerar Objective-C mais uma linguagem na minha caixa de ferramentas! Além disso, consegui comparecer nos <a href="http://codingdojo.tw/">dois</a> <a href="http://www.rubyinside.com.br/coding-dojo-aberto-em-porto-alegre-2677">primeiros</a> Conding Dojos de Porto Alegre, conheci pessoalmente caras incríveis do mundo Ágil brasileiro, como <a href="http://twitter.com/manoelp">Manoel Pimentel</a> e <a href="http://twitter.com/viniciusteles">Vinicius Telles</a>, no <a href="http://agileday2009.guma-rs.org/">Agile Day</a> e realizei mais uns freelas por aí. Tudo isso e mais os diversos experimentos relativos ao mestrado, que incluiram tópicos como HTML 5, CSS 3, Processamento de Linguagem Natural,  Simulação&#8230;</p>
<h2>Tá, mas e o Blog?</h2>
<p>Voltarei agora a dedicar mais tempo ao Blog. Farei algumas modificações aqui para que o blog não fique com o escopo muito fechado, e tratarei de alguns temas que venho estudando e que considero interessante de compartilhar com todos. Com certeza não abandonarei o Ruby como assunto principal, mas acho que é bom sempre discutirmos assuntos relevantes da área também.</p>
<p>Que venha 2010!!</p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/UebIcUk5BpY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/blog/2009/12/estou-vivo-e-melhor-do-que-nunca/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/blog/2009/12/estou-vivo-e-melhor-do-que-nunca/</feedburner:origLink></item>
		<item>
		<title>Superguia Rack – Parte 3 – Middlewares</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/4ZV6Z7sZioA/</link>
		<comments>http://www.tbueno.com/blog/rack/2009/10/superguia-rack-parte-3-middlewares/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 18:40:24 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rack]]></category>
		<category><![CDATA[Midlewares]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=295</guid>
		<description><![CDATA[Se você quer entender rapidamente o que é um Middleware, pense em um filtro. Algo que permite que todas as requisições e respostas passem por ele, permitindo assim, que ele altere-as como bem entender. Middlewares devem possuir o mesmo método call de qualquer outro objeto Rack, porém em seu construtor, eles devem receber outra aplicação [...]]]></description>
			<content:encoded><![CDATA[<p>Se você quer entender rapidamente o que é um Middleware, pense em um filtro. Algo que permite que todas as requisições e respostas passem por ele, permitindo assim, que ele altere-as como bem entender. Middlewares devem possuir o mesmo método <em>call</em> de qualquer outro objeto Rack, porém em seu construtor, eles devem receber outra aplicação como argumento. Esta é uma maneira simples de empilhar diversas aplicações. Se você vem de outras linguagens como Java ou C# e já leu sobre Design Patterns, deve estar reconhecendo o padrão Decorator. A idéia é  semelhante, mas com Ruby as coisas se tornam muito mais simples.</p>
<h2>Nosso primeiro middleware</h2>
<p>Se pegarmos o exemplo simples do HelloWorld apresentado no início desta sequência de posts sobre Rack, podemos acomplar um middleware a ele, adicionando funcionalidades extras à aplicação original.</p>
<p>Primeiros, vamos criar nosso Middleware. O exemplo é muito simples. Após imprimirmos um &#8220;Hello World!&#8221;, vamos informar a hora.</p>
<pre class="brush: ruby">
class Middleware
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    response_body = ""
    response.each { |part| response_body += part }
    response_body += " --- #{Time.now}"
    headers["Content-Length"] = response_body.length.to_s
    [status, headers, [response_body]]
  end
end
</pre>
<p>Não se assuste se você não entender tudo de cara. A parte mais complicada é cocatenar a informação de tempo na resposta, e isso é feito usando um each, devido ao fato de o response poder ser qualquer objeto que responda a esse método. Além disso, para que nossa resposta seja válida, é interessante colocar no cabeçalho HTTP o comprimento do nosso body.</p>
<p>Mas além do middleware, devemos dizer que nossa aplicação original quer usar ele. E isso deve ser feito em um arquivo .ru:</p>
<pre class="brush: ruby">
#config.ru
require 'rack'
require 'middleware'
require 'hello_world'      

use Middleware
run HelloWorld.new
</pre>
<p>Agora rodando &#8220;rackup config.ru&#8221; na linha de comando, teremos o seguinte no nosso servidor:</p>
<p><span id="more-295"></span><br />
Hello World! &#8212; 2009-10-05 14:05:58 -0300</p>
<h2>Outros Exemplos de Middlewares</h2>
<p>Na primeira parte dessa série de <a href="http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/#more-253">artigos</a>, citei o projeto <a href="http://github.com/rack/rack-contrib">rack-contrib</a>, que consistia em uma coleção de Middlewares criados pela comunidade e disponibilizado em um único projeto. Além de serem de extrema utilidade no desenvolvimento, eles também servem como um ótimo objeto de estudo para quem quer aprender sobre o funcionamento de um Middleware. Se olharmos o código do exemplo garbagecollection.rb, veremos que o funcionamento é extremamente simples, consistindo apenas de uma chamada forçada do Garbage Collector a cada request na aplicação.</p>
<pre class="brush: ruby">
module Rack
  # Forces garbage collection after each request.
  class GarbageCollector
    def initialize(app)
      @app = app
    end

    def call(env)
      @app.call(env)
    ensure
      GC.start
    end
  end
end
</pre>
<p>Sem entrar no mérito da utilidade do exemplo, é interessante notar a simplicidade do código. Em <a href="http://github.com/ambethia/rack-google_analytics">outro exemplo</a>, podemos ver integração fácil do código do Google Analytics em sua aplicação a com 2 linhas:</p>
<pre class="brush: ruby">
require "rack/google_analytics"
use Rack::GoogleAnalytics, :web_property_id => "UA-000000-1"
</pre>
<p>E o código, propriamente dito, é algo simples:</p>
<pre class="brush: ruby">
module Rack #:nodoc:
  class GoogleAnalytics < Struct.new :app, :options

    def call env
      status, headers, response = app.call(env)

      if headers["Content-Type"] =~ /text\/html|application\/xhtml\+xml/
        body = ""
        response.each { |part| body << part }
        index = body.rindex("</body>")
        if index
          body.insert(index, tracking_code(options[:web_property_id]))
          headers["Content-Length"] = body.length.to_s
          response = [body]
        end
      end

      [status, headers, response]
    end

    private

      # Returns JS to be embeded. This takes one argument, a Web Property ID
      # (aka UA number).
      def tracking_code web_property_id
        return <<-EOF
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("#{web_property_id}");
pageTracker._trackPageview();
} catch(err) {}</script>
EOF
      end

  end
end
</pre>
<p>Um outro exemplo interessante é o Middleware CommonLogger, incorporado ao código do projeto Rack. É uma implementação de logs para aplicações Rack, baseada no projeto <a href="http://commons.apache.org/logging/">Commons Logging da Apache</a> . Primeiro, vejamos o código para depois analisar-mos seu funcionamento.</p>
<pre class="brush: ruby">

module Rack
  # Rack::CommonLogger forwards every request to an +app+ given, and
  # logs a line in the Apache common log format to the +logger+, or
  # rack.errors by default.
  class CommonLogger
    # Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
    # lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
    # %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
    FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n}

    def initialize(app, logger=nil)
      @app = app
      @logger = logger
    end

    def call(env)
      began_at = Time.now
      status, header, body = @app.call(env)
      log(env, status, header, began_at)
      [status, header, body]
    end

    private

    def log(env, status, header, began_at)
      now = Time.now
      length = extract_content_length(header)

      logger = @logger || env['rack.errors']
      logger.write FORMAT % [
        env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
        env["REMOTE_USER"] || "-",
        now.strftime("%d/%b/%Y %H:%M:%S"),
        env["REQUEST_METHOD"],
        env["PATH_INFO"],
        env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
        env["HTTP_VERSION"],
        status.to_s[0..3],
        length,
        now - began_at ]
    end

    def extract_content_length(headers)
      headers.each do |key, value|
        if key.downcase == 'content-length'
          return value.to_s == '0' ? '-' : value
        end
      end
      '-'
    end
  end
end
</pre>
<p>Como podemos ver, este é outro exemplo simples de um Middleware muito útil. No método call, é criado um registro simples do momento em que a aplicação principal é chamada, e um método de log pega todas as informações recebidas e formata em uma string que será impressa no servidor. Apesar de parecer difícil de entender a primeira vista, o método log apenas coleta e formata informações contidas no objeto env para adicionar ao log.</p>
<h2>Outros Middleware</h2>
<p>Existem outros ótimos exemplos de Middlewares pela rede. Optei por citar os mais simples aqui por questões didáticas. Dentre os que eu poderia citar como fundamentais, estão o <a href="http://github.com/rtomayko/rack-cache">rack-cache</a> do Ryan Tomayko, que é utilizado largamente em aplicações desenvolvidas com Rails. Posso citar também o &#8220;encolhedor&#8221; de javascript <a href="http://github.com/lucianopanaro/rack-javascript-minifier">Javascript Minifier</a>, o criador de <em>responses</em> JSON &#8220;Rack::JSONP&#8221; também é um bom exemplo, bem como &#8220;Rack::MailExceptions&#8221; e outros contidos no projeto rack-contrib.</p>
<p>Até o próximo post!</p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/4ZV6Z7sZioA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/rack/2009/10/superguia-rack-parte-3-middlewares/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/rack/2009/10/superguia-rack-parte-3-middlewares/</feedburner:origLink></item>
		<item>
		<title>Superguia Rack – Parte 2 – Dissecando o Rack</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/wzwtqMjHgPc/</link>
		<comments>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-2-dissecando-o-rack/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 21:01:45 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rack]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=266</guid>
		<description><![CDATA[Continuando nossa saga iniciada no post anterior, voltaremos ao exemplo do HelloWorld para entendermos mais profundamente a estrutura de um objeto Rack. Como mencionado anteriormente, um este objeto deve possuir (na verdade responder a) um método call(env), retornando em sua resposta um array com 3 elementos. Veremos mais profundamente cada um desses elementos. class HelloWorld [...]]]></description>
			<content:encoded><![CDATA[<p>Continuando nossa saga iniciada <a href="http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/">no post anterior</a>, voltaremos ao exemplo do HelloWorld para entendermos mais profundamente a estrutura de um objeto Rack. Como mencionado anteriormente, um este objeto deve possuir (na verdade responder a) um método call(env), retornando em sua resposta um array com 3 elementos. Veremos mais profundamente cada um desses elementos.</p>
<pre class="brush: ruby">
class HelloWorld
  def call(env)
    [200, {"Content-Type" => "text/html"}, "Hello World"]
  end
end
</pre>
<h2>O método def call(env)</h2>
<h3>Env</h3>
<p>O parâmetro recebido pelo método call é uma hash com as propriedades do ambiente do visitante da aplicação. Se alterarmos o nosso HelloWorld para imprimir o objeto <em>env</em> ao invés da string, teremos algo parecido com isso:</p>
<pre>
{
"REQUEST_METHOD"=>"GET",
"REQUEST_PATH"=>"/",
"REQUEST_URI"=>"/",
"HTTP_VERSION"=>"HTTP/1.1",
"HTTP_HOST"=>"localhost:9292",
"HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/530.18 (KHTML, like Gecko) Version/4.0.1 Safari/530.18",
"HTTP_ACCEPT"=>"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", "HTTP_ACCEPT_LANGUAGE"=>"en-us", "HTTP_ACCEPT_ENCODING"=>"gzip,deflate",
"HTTP_CONNECTION"=>"keep-alive", "GATEWAY_INTERFACE"=>"CGI/1.2",
"SERVER_NAME"=>"localhost",
"SERVER_PORT"=>"9292",
"SERVER_PROTOCOL"=>"HTTP/1.1",
"SERVER_SOFTWARE"=>"Mongrel 1.1.5",
 "PATH_INFO"=>"/",
 "SCRIPT_NAME"=>"",
 "REMOTE_ADDR"=>"127.0.0.1", "rack.version"=>[0, 1], "rack.input"=>#, "rack.errors"=>#>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "rack.url_scheme"=>"http",
 "QUERY_STRING"=>""}
 </pre>
<p>Dentre as informações impressas, algumas são bem importantes, como:</p>
<ul>
<li><strong>REQUEST_METHOD</strong>: Informa qual o <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">verbo HTTP</a>  (GET, PUT, DELETE&#8230;) usado pelo usuário ao acessar a página.</li>
<li><strong>HTTP_USER_AGENT</strong>: Informa o browser do usuário, facilitando o tratamento para browsers diferente em sua aplicação.</li>
<li><strong>QUERY_STRING</strong>: Informa os argumentos passados após o &#8220;?&#8221; da url, útil para fazer parsing dos parâmetros.</li>
</ul>
<h3>Status</h3>
<p>O primeiro objeto retornado no array de resposta é um inteiro, representando o status da resposta que sua aplicação retornará no método. O 200 do nosso exemplo, representa &#8220;OK&#8221; segundo a <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">especificação do HTTP</a>. É aqui seu controle de exceção jogará aquele lindo &#8220;Erro 404&#8243; quando o usuário digitar incorretamente um sub-caminho de sua aplicação. ;-)</p>
<h3>HTTP Headers</h3>
<p>Cabeçalhos HTTP informam o tipo de retorno do pacote. O segundo objeto do nosso retorno deve OBRIGATORIAMENTE responder a um método &#8220;each&#8221; e devolver chaves e valores de seus elementos, tipicamente um Hash, como no nosso exemplo. A chave Content-Type, por exemplo, deve retornar o tipo de retorno a ser esperado, podendo ser HTML(&#8220;Content-Type&#8221; => &#8220;text/html&#8221;), XML, MP3 (&#8216;Content-Type&#8217; => &#8216;audio/mp3&#8242;), entre outros.</p>
<h3>Response Body</h3>
<p>O retorno &#8220;Body&#8221; deve responder ao método <em>each</em> retornando um array de strings. Este será o conteúdo que será apresentado ao usuário no navegador.</p>
<p><strong>ATENÇÃO</strong>: Segundo a documentação atual do Rack, o Body não deve mais ser uma simples string(como nos exemplos do post anterior). Aparentemente isto quebrará no Ruby 1.9.</p>
<h2>Rack:Builder</h2>
<p>É uma ferramenta que nos permite construir aplicações Rack utilizando uma DSL para &#8220;costurar&#8221; diferentes middlewares e aplicações. Os Builders são os parafusos das estantes, ou a cola que une as estruturas separadas criando uma inteiramente nova. Na verdade, o Builder é o cara que torna o a idéia do Rack tão genial. A facilidade que ele proporciona na criação de Middlewares ficará bem claro no próximo post.</p>
<p>Os métodos fornecidos pela DSL do Buider são:</p>
<p><span id="more-266"></span></p>
<ul>
<li>run</li>
<li>use</li>
<li>map</li>
</ul>
<h3>Rack::Builder#run</h3>
<p>É o método que o servidor web procurará para a execução da aplicação Rack. No exemplo abaixo, nosso builder é informado para rodar o bloco chamado clock a cada resquisição à porta 9292. Nada demais, por enquanto. Mas na medida que a aplicação for crescendo, é possível criar estruturas extremamente complexas que veremos posteriormente.</p>
<pre class="brush: ruby">
clock = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now}"]]}
builder = Rack::Builder.new do
  run clock
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<h3>Rack::Builder#use</h3>
<p>É o método utilizado para acomplar novas middlewares à sua aplicação. No exemplo abaixo, o middleware <a href="http://rack.rubyforge.org/doc/Rack/CommonLogger.html">CommonLogger</a> é adicionado à nossa aplicação com apenas uma linha de código:</p>
<pre class="brush: ruby">
clock = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now}"]]}
builder = Rack::Builder.new do
  use Rack::CommonLogger
  run clock
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<p>CommonLogger é um Middleware que adiciona a funcionalidade de log ao seu servidor. Rodando este exemplo, você terá um log semelhante ao de Rails e Sinatra em seu console, como no exemplo abaixo:</p>
<p>127.0.0.1 &#8211; - [25/Sep/2009 17:17:03] &#8220;GET / HTTP/1.1&#8243; 200 30 0.0002<br />
127.0.0.1 &#8211; - [25/Sep/2009 17:17:14] &#8220;GET / HTTP/1.1&#8243; 200 30 0.0002<br />
127.0.0.1 &#8211; - [25/Sep/2009 17:17:15] &#8220;GET /2 HTTP/1.1&#8243; 200 30 0.0002<br />
127.0.0.1 &#8211; - [25/Sep/2009 17:17:28] &#8220;GET /testand_log HTTP/1.1&#8243; 200 30 0.0002</p>
<h3>Rack::Builder#map</h3>
<p>Método utilizado para mapear (jura?) suas rotas HTTP. Não a toa, é semelhante ao routes.rb do Rails, afinal, ambos são implementações diretas das <em>best practices</em> de desenvolvimento web atual.</p>
<p>Para ilustrar, criaremos um exemplo de aplicação que além de informar as horas, oferece um caminho para que o usuário seja informado em que ano ele se encontra. </p>
<pre class="brush: ruby">
clock = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now}"]]}
builder = Rack::Builder.new do
  use Rack::CommonLogger
  map '/' do
    run clock
  end

  map '/year' do
    run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.new.year}"]] }
  end
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<p>Com este exemplo, se após iniciarmos a nossa aplicação tentarmos acessar a url http://localhost:9292/year, receberemos o ano atual em nosso browser.</p>
<p>Ok, mas e rotas aninhadas? Extremamente simples também! Acompanhem o exemplo abaixo.</p>
<pre class="brush: ruby">
builder = Rack::Builder.new do
  use Rack::CommonLogger
  map '/' do
    run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Welcome to my page"]]}
  end

  map '/clock' do
    map '/' do
      run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now}"]] }
    end

    map '/year' do
      run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now.year}"]] }
    end

    map '/hour' do
      run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now.hour}"]] }
    end    

  end
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<p>Ok, mas nós podemos seguir o conceito de DRY para evitar código desnecessário:</p>
<pre class="brush: ruby">
def create_proc(body_return)
  Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{body_return}"]]}
end

builder = Rack::Builder.new do
  use Rack::CommonLogger
  map '/' do
    run create_proc('Welcome to my page')
  end

  map '/clock' do
    map '/' do
      run create_proc(Time.now)
    end

    map '/year' do
      run create_proc(Time.now.year)
    end

    map '/hour' do
      run create_proc(Time.now.hour)
    end    

  end
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<p>Desta maneira, criamos uma aplicação com as seguintes rotas disponíveis:</p>
<ul>
<li>http://localhost:9292/</li>
<li>http://localhost:9292/clock</li>
<li>http://localhost:9292/clock/year</li>
<li>http://localhost:9292//clock/hour</li>
</ul>
<h2>Cenas do Próximo Capítulo</h2>
<p>Após aprendermos o <a href="http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/">conceito do Rack</a>, sua estrutura e os 3 principais métodos oferecidos para criação de aplicações, nos focaremos na criação de Middlewares no próximo post. Entenderemos seus conceitos e investigaremos alguns exemplos bem sucedidos disponíveis na web. Fiquem ligados!</p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/wzwtqMjHgPc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-2-dissecando-o-rack/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-2-dissecando-o-rack/</feedburner:origLink></item>
		<item>
		<title>Superguia Rack – Parte 1</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/IGDmyfq1Neg/</link>
		<comments>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 03:30:28 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rack]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=253</guid>
		<description><![CDATA[Este é o primeiro de uma série de posts dedicado ao Rack. No início, Rack me parecia muito obscuro e estes posts serão criados com o intuito de clarear as idéias de quem ainda possui dificuldade para entender este pequeno framework. Introdução da Introdução Em fevereiro de 2007, Christian Neukirchen postou em seu blog um [...]]]></description>
			<content:encoded><![CDATA[<p><em>Este é o primeiro de uma série de posts dedicado ao <a href="http://rack.rubyforge.org/">Rack</a>. No início, Rack me parecia muito obscuro e estes posts serão criados com o intuito de clarear as idéias de quem ainda possui dificuldade para entender este pequeno framework.</em></p>
<p><center><img alt="" src="http://rack.rubyforge.org/rack-logo.png" class="alignnone" width="400" height="200" /></center></p>
<h2>Introdução da Introdução</h2>
<p>Em fevereiro de 2007, Christian Neukirchen  postou em seu blog um artigo chamado <a href="http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html">&#8220;Introduzindo Rack&#8221;</a> no qual falava sobre a quantidade de código duplicado que ele achava em diferentes Frameworks Web escritos em Ruby. Ao anunciar a sua criação, o autor  tocava em um ponto importante aonde escrevia, com razão, sobre um assunto que na verdade não era culpa dos desenvolvedores.</p>
<p>Sendo todos frameworks web, era de se esperar que muitas coisas fossem parecidas. A grande sacada do criador de Rack, foi o fato de ter percebido que web pode, em grande parte, ser resumida como uma série de requisições e respostas HTTP. O resto é framework que vai por cima.</p>
<p>HTTP pode ser resumido de maneira muito simples, como uma série de REQUESTS e RESPONSES. Rack utiliza-se muito bem dessa “simplicidade” para encapsular praticamente todo o controle dessa troca de mensagens em um objeto Ruby. Ao encapsular as requisições HTTP, Rack é capaz de prover interfaces para aplicações entre web servers, web frameworks e middlewares.</p>
<h2>O que é Rack?</h2>
<p>Podemos considerar o Rack uma especificação para a criação de aplicações web desenvolvidas com ruby. Segundo Dan Webb em sua apresentação &#8220;<a href="http://www.slideshare.net/danwrong/8-minutes-on-rack-presentation">8 minutes on Rack</a>&#8220;:</p>
<blockquote><p>&#8220;Se você tem um objeto Ruby que possui um método call cujo o único argumento é env e retorna um array com 3 elementos ([200, {"Content-Type" =&gt; "text/html"}, "Hello World!"] ), então ele pode ser conectado a qualquer web server que suporte Rack&#8221;</p></blockquote>
<p>Mas a definição mais simples possível é a que Rack provê uma interface mínima entre web servers e web frameworks escritos em Ruby.<br />
<span id="more-253"></span><br />
Essa definição é interessante, mas Rack nos proporciona mais que isso. Com seu Builder (que será explorado em um post mais adiante) é possível integrar e ordenar módulos (ou middlewares) empilhados formando uma aplicação com os recursos desde módulos agrupados.</p>
<p><center><img class="alignnone" title="Rack módulos empilhados" src="http://img3.imageshack.us/img3/3743/rackp.jpg" alt="" width="351" height="269" /></center></p>
<h2>Por que usar Rack?</h2>
<h3>Oferece controle de requisições, sessões e cookies automaticamente.</h3>
<p>Como Rack é uma especificação, desenvolvedores podem criar códigos que funcionam em qualquer aplicação e compartilhar módulos para uso de outros desenvolvedores. Dessa idéia já surgiu o <a href="http://github.com/rack/rack-contrib">rack-contrib</a>, uma coleção de Midlewares e ferramentas disponível para que qualquer um utilize em sua aplicação.</p>
<h3>Desenvolva middlewares que funcionam com Rails, Sinatra, Ramaze&#8230;</h3>
<p>Qualquer servidor web que ofereça suporte a Rack rodará sua aplicação normalmente. Além disso, ela poderá ser transferida e replicada em servidores diferentes sem a necessidade de configurações diferentes.</p>
<p>A lista de servidores que já suportam Rack é grande. Até agora, os seguintes já suportam:</p>
<ul>
<li>Mongrel</li>
<li>EventedMongrel</li>
<li>SwiftipliedMongrel</li>
<li>WEBrick</li>
<li>FCGI</li>
<li>CGI</li>
<li>SCGI</li>
<li>LiteSpeed</li>
<li>Thin</li>
<li>Ebb</li>
<li>Fuzed</li>
<li>Phusion Passenger</li>
<li>Unicorn</li>
</ul>
<p>Além dos servidores, praticamente todos os frameworks web desenvolvidos em Ruby já possuem adaptadores para Rack. A lista atual inclui os seguintes frameworks:</p>
<ul>
<li>Camping</li>
<li>Coset</li>
<li>Halcyon</li>
<li>Mack</li>
<li>Maveric</li>
<li>Merb</li>
<li>Racktools::SimpleApplication</li>
<li>Ramaze</li>
<li>Ruby on Rails</li>
<li>Rum</li>
<li>Sinatra</li>
<li>Sin</li>
<li>Vintage</li>
<li>Waves</li>
<li>Wee</li>
</ul>
<h2>Um exemplo minúsculo</h2>
<p>O Rack possui uma ferramenta chamada rackup, que roda arquivos do tipo .ru. Neste exemplo, crie um arquivo chamado hello.ru e digite a seguinte linha:</p>
<pre class="brush: ruby">
    run Proc.new {|env| [200, {"Content-Type" => "text/html"}, "Hello Horld!"]}
</pre>
<p>Agora rode o arquivo via linha de comando usando rackup:</p>
<blockquote><p>
> rackup hello.ru</p></blockquote>
<p>E acesse o seguinte endereço em seu browser: http://localhost:8765/.</p>
<p>Pronto, você acabou de criar a página web no com o menor número de caracteres possível!</p>
<h2>Um segundo exemplo um pouco maior</h2>
<pre class="brush: ruby">
require 'rubygems'
require 'rack'
class HelloWorld
  def call(env)
    [200, {"Content-Type" => "text/html"}, "Hello Horld!"]
  end
 end
Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292
</pre>
<p>Apesar de sua função ser a mesma do anterior, este exemplo merece ser explicado. Como todo objeto Rack, nosso exemplo responde a um método call, retornando um array com os três elementos principais do Rack (que serão explicados no próximo post). Após definirmos esse simples método na nossa classe, basta instanciarmos um servidor (Mongrel nesse caso) que receberá requisições por uma porta (9292) e retornará o conteúdo do terceiro objeto do array do método call.</p>
<p>Se esse início já clareou um pouco mais as idéias sobre o Rack, fique ligado para os posts que seguirão a série para saber mais sobre Middlewares, Rails Metal, Builders e todos os outros elementos do maravilhoso mundo ro Rack!</p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/IGDmyfq1Neg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/</feedburner:origLink></item>
		<item>
		<title>Super Ruby Loops</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/OzIwtWd7r7Q/</link>
		<comments>http://www.tbueno.com/blog/ruby/2009/08/super-ruby-loops/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 18:16:48 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=206</guid>
		<description><![CDATA[Uma das coisas que mais me confundiu a cabeça quando comecei a aprender Ruby foram os loops. Vindo de Java e C, não me entrava na cabeça como uma coisa simples como um loop poderia ser escrito de tantas maneiras diferentes. Isso simplesmente não parecia certo pra mim. Passado um bom tempo, comecei a compreender [...]]]></description>
			<content:encoded><![CDATA[<p>Uma das coisas que mais me confundiu a cabeça quando comecei a aprender Ruby foram os loops. Vindo de Java e C, não me entrava na cabeça como uma coisa simples como um loop poderia ser escrito de tantas maneiras diferentes. Isso simplesmente não parecia certo pra mim. Passado um bom tempo, comecei a compreender essa liberdade dada ao programador e a creditar isso ao poder e dinamicidade do Ruby.</p>
<p>Por curiosidade, resolvi tentar descobri todas as maneiras possíveis de se executar um loop com Ruby, e tentarei lista-las aqui.</p>
<h2>While</h2>
<p>Loops do tipo While no Ruby são exatamente iguais aos encontrados em Java, C# e outros. Um bloco deve ser executado <em>enquanto uma condição for verdadeira</em>.</p>
<pre class="brush: ruby">
x = 1
while(x <4)
	puts x
	x +=1
end

=> 1
   2
   3
</pre>
<p>O while também pode ser usado ao final de um bloco, de maneira semelhando ao &#8220;DO&#8230;WHILE&#8221; de outras linguagens.</p>
<pre class="brush: ruby">
x =1
begin
	puts x
	x+=1
end while (x<4)

=> 1
   2
   3
</pre>
<p>Irmão  inverso do while, o until executa um bloco de código <em>até que uma condição seja verdadeira</em>.</p>
<pre class="brush: ruby">
x = 1
until(x>3)
  puts x
  x +=1
end

=> 1
   2
   3
</pre>
<p>E, como no while, também pode ser usado como condição de execução ao fim de um bloco.</p>
<pre class="brush: ruby">
x = 1
begin
  puts x
  x+=1
end until (x>3)

=> 1
   2
   3
</pre>
<p><span id="more-206"></span></p>
<h2>For</h2>
<p>Outro loop clássico das linguagens, o for assume algumas particularidades no Ruby. Os <i>ranges</i> de Ruby podem ser usados em um for. Tanto na versão &#8220;intervalo aberto e fechado&#8221;.</p>
<pre class="brush: ruby">
#Intervalo aberto
for i in 1..3
  puts i
end

=> 1
   2
   3
#Intervalo fechado
for i in 1...4
  puts i
end

=> 1
   2
   3
</pre>
<p>Além disso, podemos iterar sobre letra do alfabeto, como no exemplo abaixo:</p>
<pre class="brush: ruby">
for x in 'a'..'d'
  puts x
end

=> a
   b
   c
   d
</pre>
<h2>Iteradores</h2>
<p>O  <em>iterator</em>, é um padrão de projeto que nos permite percorrer objetos agregados sem que sua verdadeira relação com o grupo ao qual pertence seja exposto. Ruby já fornece o padrão iterator através do método <em>each</em>.</p>
<pre class="brush: ruby">
[1,2,3].each do |i|
  puts i
end

=> 1
   2
   3
</pre>
<p>Que também pode ser usado com ranges:</p>
<pre class="brush: ruby">
(1..3).each do |i|
  puts i
end

=> 1
   2
   3
</pre>
<h2>Métodos da Classe Fixnum</h2>
<p>As opções não param nas citadas acima. Ainda temos alguns métodos da flasse Fixnum que nos fornecem comportamentos semelhante aos loops clássicos.</p>
<p>O método Fixnum#times recebe um bloco como parâmetro, e o executa o mesmo número de vezes do objeto Fixnum que o executou.</p>
<pre class="brush: ruby">
i = 1
3.times do
  puts i
  i+=1
end

=> 1
   2
   3
</pre>
<p>Temos também os métodos upto e downto que, como o times, também recebe um bloco e o executa, porém com um objeto de índice do bloco.</p>
<pre class="brush: ruby">
1.upto(3) {|i| puts i}

=> 1
   2
   3

3.downto(1) {|i| puts i}

=> 3
   2
   1
</pre>
<h2>Outras Esquisitices</h2>
<p>Em Ruby também temos um loop infinito, semelhante a um while(true), que deve ser quebrado mediante alguma condição definida dentro do bloco de execução. Um exemplo prático poderia ser uma verificação de senha via linha de comando:</p>
<pre class="brush: ruby">
loop do
  puts "Enter your password"
  gets
  chomp
  break if $_ =="123"
  puts "WRONG! Try again!"
end
</pre>
<p>E por fim, algumas malandragens típicas do Ruby. Como eu usei o mesmo exemplo em todo esse post, aqui vão algumas outras maneiras de imprimir na tela os números:</p>
<pre class="brush: ruby">
puts (1..3).to_a* "\n"

puts (1..3).to_a

puts *(1..3)

puts 1,2,3
</pre>
<p>Será que eu me esqueci de algum?</p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/OzIwtWd7r7Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/ruby/2009/08/super-ruby-loops/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/ruby/2009/08/super-ruby-loops/</feedburner:origLink></item>
		<item>
		<title>Delicious-Ext Atualizado</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/W_eIHwH3OYc/</link>
		<comments>http://www.tbueno.com/blog/ruby/2009/08/delicious-ext-atualizado/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 22:02:06 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Projetos]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Scraping]]></category>
		<category><![CDATA[Delicious]]></category>
		<category><![CDATA[Delicious-Ext]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=231</guid>
		<description><![CDATA[Quando eu fiz um post descrevendo a extensão da API do Delicious feita com scraping, um dos riscos que eu citei era de o site mudar sua estrutura, fazendo com que os scripts de scraping quebrassem. Pois há dois dias atrás aconteceu, o Delicious sofreu reformulações e a implementação que eu tinha foi pro espaço. [...]]]></description>
			<content:encoded><![CDATA[<p>Quando eu <a href="http://www.tbueno.com/blog/scraping/2009/02/extendendo-apis-com-scraping/">fiz um post descrevendo a extensão da API</a> do Delicious feita com scraping, um dos riscos que eu citei era de o site mudar sua estrutura, fazendo com que os <em>scripts</em> de <em>scraping</em> quebrassem. </p>
<p>Pois há dois dias atrás aconteceu, o <a href="http://blog.delicious.com/blog/2009/08/delicious-homepage-gets-%e2%80%9cfresh%e2%80%9d.html">Delicious sofreu reformulações</a> e a implementação que eu tinha foi pro espaço.  </p>
<p>Já consertei todos os problemas e consegui implementar já algumas funções novas, como a busca por &#8220;Fresh links&#8221; que retornam páginas mais atuais, seguindo a tendência de <em>instant search</em> que anda sendo discutida bastante atualmente. Algumas features novas ainda não foram mapeadas, mas estas não afetam o funcionamento das atuais.</p>
<p>Hoje eu dei um <em>push</em> das correções pro Github e atualizei o <em>readme</em> para quem quiser usar. O código atualizado pode ser encontrado aqui:<br />
<a href="http://github.com/tbueno/delicious-ext/tree/master">http://github.com/tbueno/delicious-ext/tree/master</a></p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/W_eIHwH3OYc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/ruby/2009/08/delicious-ext-atualizado/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/ruby/2009/08/delicious-ext-atualizado/</feedburner:origLink></item>
		<item>
		<title>Ruby, Jruby e Processing = ruby-processing</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/h-HHergTCSc/</link>
		<comments>http://www.tbueno.com/blog/jruby/2009/07/ruby-jruby-e-processing-ruby-processing/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 04:19:10 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Visualização]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ruby-processing]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=211</guid>
		<description><![CDATA[Um dos motivos que me fizeram ficar distante do blog por uns tempos foi o meu mestrado, cujo semestre acabou essa semana. E como estou trabahando direto com Java atualmente, tive que usar a imaginação para continuar praticando meus conhecimentos em Ruby. Para quem não sabe, estou fazendo mestrado em Sistemas Interativos de Visualização, com [...]]]></description>
			<content:encoded><![CDATA[<p>Um dos motivos que me fizeram ficar distante do blog por uns tempos foi o meu mestrado, cujo semestre acabou essa semana.  E como estou trabahando direto com Java atualmente, tive que usar a imaginação para continuar praticando meus conhecimentos em Ruby. Para quem não sabe, estou fazendo mestrado em Sistemas Interativos de Visualização, com muitas cadeiras ligadas a Computação Gráfica, Animação e Visualização de Dados.  Em muito dos trabalhos, utilizei uma das minha ferramentas favoritas, o <a href="http://processing.org">Processing</a>, mais precisamente sua alternativa rubista: o <a href="http://wiki.github.com/jashkenas/ruby-processing">ruby-processing</a>.</p>
<h2> O Poder do JRuby </h2>
<p>Uma das melhores vantagens fornecidas pelo JRuby é a possibilidade de utilizarmos as trocentas ferramentas já existentes no mundo Java utilizando Ruby. E foi exatamente isso que Jeremy Ashkenas fez. Perceba que a integração é relativamente simples entre as duas linguagens:</p>
<pre class="brush: ruby">
require 'java'

module Processing

  # Conditionally load core.jar
  require "#{RP5_ROOT}/lib/core/core.jar" unless Processing.online? || Processing.embedded?
  import "processing.core"
  .
  .
  .
class App < PApplet
  .
  .
</pre>
<p><span id="more-211"></span><br />
Ao importar o .jar do Processing , temos à disposição todas as classes, inclusive a PApplet que é a que nos disponibiliza as principais funções de desenho.  O resto do código é praticamente formado apenas por wrappers e funções auxiliares de integração. A lógica toda já está pronta, e em Java. </p>
<p>Aconselho fortemente uma olhada no código do ruby-processing para quem quiser aprender como se faz uma aplicação completa usando JRuby</p>
<h2>Os Corais de Bach</h2>
<p>Em uma disciplina de Visualização de Dados, um trabalho consistia em escolher um dataset do site <a href="http://archive.ics.uci.edu/ml/index.html">Machine Learning Repository</a> e criar uma maneira de visualizar esses dados. Escolhi os <a href="http://archive.ics.uci.edu/ml/datasets/Bach+Chorales">Corais de Bach</a>, devido ao fato de eu ser fã do magnífico compositor alemão.</p>
<p>O primeiro desafio foi destrinchar a base de dados. Para vocês terem uma idéia, aqui segue um exemplo de uma peça de coral contida na coleção:</p>
<p><code>(1 ((st 8 ) (pitch 67) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 12) (pitch 67) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 20) (pitch 74) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 24) (pitch 71) (dur 6) (keysig 1) (timesig 12) (fermata 0))((st 30) (pitch 69) (dur 2) (keysig 1) (timesig 12) (fermata 0))((st 32) (pitch 67) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 36) (pitch 67) (dur 6) (keysig 1) (timesig 12) (fermata 0))((st 42) (pitch 69) (dur 2) (keysig 1) (timesig 12) (fermata 0))((st 44) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 48 ) (pitch 69) (dur 8 ) (keysig 1) (timesig 12) (fermata 1))((st 56) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 60) (pitch 74) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 68 ) (pitch 72) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 72) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 76) (pitch 69) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 84) (pitch 67) (dur 8 ) (keysig 1) (timesig 12) (fermata 1))((st 92) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 96) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 100) (pitch 72) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 104) (pitch 74) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 108 ) (pitch 74) (dur 6) (keysig 1) (timesig 12) (fermata 0))((st 114) (pitch 72) (dur 2) (keysig 1) (timesig 12) (fermata 0))((st 116) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 120) (pitch 69) (dur 8 ) (keysig 1) (timesig 12) (fermata 1))((st 128) (pitch 67) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 132) (pitch 71) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 140) (pitch 72) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 144) (pitch 74) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 152) (pitch 72) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 156) (pitch 71) (dur 12) (keysig 1) (timesig 12) (fermata 0))((st 168) (pitch 67) (dur 8 ) (keysig 1) (timesig 12) (fermata 1))((st 176) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 180) (pitch 74) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 188 ) (pitch 72) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 192) (pitch 71) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 200) (pitch 69) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 204) (pitch 67) (dur 6) (keysig 1) (timesig 12) (fermata 0))((st 210) (pitch 69) (dur 2) (keysig 1) (timesig 12) (fermata 0))((st 212) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 216) (pitch 69) (dur 8 ) (keysig 1) (timesig 12) (fermata 1))((st 224) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 228 ) (pitch 74) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 236) (pitch 72) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 240) (pitch 71) (dur 4) (keysig 1) (timesig 12) (fermata 0))((st 244) (pitch 69) (dur 8 ) (keysig 1) (timesig 12) (fermata 0))((st 252) (pitch 67) (dur 8 ) (keysig 1) (timesig 12) (fermata 1)))<br />
</code></p>
<p>Pra quem conhece Lisp, essa bizarrice não assusta tanto, mas eu precisava de uma maneira de tornar essa maçaroca em algo entendível. Aí vem a beleza do Ruby e sua facilidade para processamento de texto. Com poucas linhas, um arquivo com 100 peças de corais como a mostrada acima vira uma estrutura simples com tudo que eu preciso para minha visualização:</p>
<pre class="brush: ruby">
lines = []
  File.open("bach.lisp", "r") do |infile|
       while (line = infile.gets)
           lines << "#{line}" unless line.size == 1 #ignora linhas em branco
       end
  end
</pre>
<p>Com tudo mastigado, basta partirmos para as operações matemáticas.</p>
<h2>Hora do Desenho</h2>
<p>Na minha busca por reconhecer padrões nas músicas em minhas visualizações, escolhi arcos, porque eles passam uma noção de duração facilmente perceptível, e as cores foram escolhidas para as notas, ficando o eixo X para o momento em que as notas iniciam.</p>
<pre class="brush: ruby">
def draw
  background 0,0,0
  draw_labels
  draw_rectangles
  @arcs.each do |ar|
    noFill
    stroke(ar.c)
    smooth
    semicircle(ar.st+ar.duration, X_AXIS, ar.st,X_AXIS )
    line(ar.st+ar.duration, X_AXIS+10, ar.st+ar.duration, X_AXIS+10+(ar.pitch*2))
  end

end

def semicircle xLeft, yLeft, xRight, yRight
  pushMatrix
    diameter = dist xLeft, yLeft, xRight, yRight
    angle = atan2(yRight - yLeft, xRight - xLeft)
    arc((xLeft + xRight)/2, (yLeft + yRight) / 2, diameter, diameter, angle, angle + PI)
  popMatrix
end
</pre>
<p>O resultado, pode ser conferido nos screenshots abaixo:</p>
<p><a href="http://www.tbueno.com/blog/wp-content/uploads/2009/07/chorales2.png"><img src="http://www.tbueno.com/blog/wp-content/uploads/2009/07/chorales2-300x263.png" alt="chorales2" title="chorales2" width="300" height="263" class="alignnone size-medium wp-image-212" /></a></p>
<p><a href="http://www.tbueno.com/blog/wp-content/uploads/2009/07/chorales.jpg"><img src="http://www.tbueno.com/blog/wp-content/uploads/2009/07/chorales-300x177.jpg" alt="chorales" title="chorales" width="300" height="177" class="alignnone size-medium wp-image-214" /></a></p>
<p>Se levarmos em conta o tempo curto entre os trabalho, o resultado alcançado foi interessante. Meu código possui muitas duplicações e o algoritmo não está nada otimizado. Com mais tempo, faço uma versão melhor, aonde qualquer arquivo de música MIDI possa ser interpretado.</p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/h-HHergTCSc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/jruby/2009/07/ruby-jruby-e-processing-ruby-processing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/jruby/2009/07/ruby-jruby-e-processing-ruby-processing/</feedburner:origLink></item>
		<item>
		<title>Diga Ao Mundo</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/o2z0EFKoBxk/</link>
		<comments>http://www.tbueno.com/blog/rails/2009/07/diga-ao-mundo/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 16:25:05 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=208</guid>
		<description><![CDATA[O Ozéias Sant&#8217;ana posto no blog dele: O Working With Rails, mais conhecido como wwr, é uma app que indexa todos os desenvolvedores que trabalham com Rails. Oferece formas de analisar a comunidade por autoridade, popularidade e por país. Falando em país, posso dizer que já estivemos quase no top, mas hoje estamos amargando a [...]]]></description>
			<content:encoded><![CDATA[<p>O Ozéias Sant&#8217;ana posto <a href="http://railsbox.org/">no blog dele</a>:</p>
<blockquote><p>O Working With Rails, mais conhecido como wwr, é uma app que indexa todos os desenvolvedores que trabalham com Rails. Oferece formas de analisar a comunidade por autoridade, popularidade e por país.</p>
<p>Falando em país, posso dizer que já estivemos quase no top, mas hoje estamos amargando a 4 posição &#8211; atrás dos United States, United Kingdom e India.</p>
<p>Temos muito mais que 1000 desenvolvedores por aqui e precisamos mostrar isto. Nós, brasileiros, não estamos acostumados a cuidar do nosso marketing pessoal, perdemos feio para os Indianos &#8211; nossos maiores concorrentes no mercado de offshore outsourcing.</p></blockquote>
<p>A lembrança é muito pertinente, e resolvi ecoar por aqui também o chamamento dele. Vamos fortalecer a imagem do Brasil como celeiro de grandes desenvolvedores Rails. Indique as pessoas que você acredita que agregam conhecimento à comunidade Rails Brasil.</p>
<p>Este é o meu <a href="http://www.workingwithrails.com/person/9184-thiago-bueno-silva">perfil</a>, e este é o do <a href="http://workingwithrails.com/recommendation/new/person/8228-oz-ias-sant-ana">Oséias</a>, caso achem que a gente merece indicação. ;-)</p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/o2z0EFKoBxk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/rails/2009/07/diga-ao-mundo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/rails/2009/07/diga-ao-mundo/</feedburner:origLink></item>
		<item>
		<title>A Comunidade Ruby no FISL 10</title>
		<link>http://feedproxy.google.com/~r/Buenoruby/~3/x7xksGwHo-s/</link>
		<comments>http://www.tbueno.com/blog/eventos/2009/06/a-comunidade-ruby-no-fisl-10/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 04:41:44 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Eventos]]></category>
		<category><![CDATA[Fisl]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=192</guid>
		<description><![CDATA[Depois de muitos dias ausente, volto para postar um pequeno relato sobre o lado Rubista do décimo Fórum Internacional do Sofware Livre em Porto Alegre. Apesar da correria que permeia esses meus últimos meses, devido ao trabalho e ao mestrado, consegui acompanhar (quase) todas a palestras de Ruby do Fórum, pois trabalho a poucos metros [...]]]></description>
			<content:encoded><![CDATA[<p>Depois de muitos dias ausente, volto para postar um pequeno relato sobre o lado Rubista do décimo Fórum Internacional do Sofware Livre em Porto Alegre. Apesar da correria que permeia esses meus últimos meses, devido ao trabalho e ao mestrado, consegui acompanhar (quase) todas a palestras de Ruby do Fórum, pois trabalho a poucos metros de onde o evento ocorreu.</p>
<p>Tudo começou na quarta, as 9:00 com a <a href="http://www.makemesimple.com/blog/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/">palestra de TDD e Rails do Lucas Húngaro</a>. Quando cheguei, cerca de 15 pessoas assistiam ao começo da apresentação. Confesso que senti medo e uma certa vergonha, afinal, sou da cidade organizadora e não gostaria de um evento dessa magnitude entregue às moscas. Mas o povo foi chegando&#8230;chegando&#8230;e quando me dei conta, assistia a uma ótima palestra sobre diversas ferramentas de teste acompanhado de mais de 100 pessoas.  Um começo com chave de ouro. Recomendo a todos que dêem uma olhada no materia do Lucas <a href="http://www.makemesimple.com/blog/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/">aqui</a>. Foi uma palestra excelente.</p>
<p>A palestra seguinte seria sobre o Seaside, framework web feito em SmallTalk, que seria apresentado com paralelos sendo traçados com Rails, mas o Fábio Kung não pôde aparecer. Foi uma pena, pois Seaside era um dos assuntos que eu mais queria conhecer no FISL. Enfim, a palestra substituta acabou sendo legal, mas fugiu completamente do que eu esperava.</p>
<div class="wp-caption aligncenter" style="width: 510px"><img alt="A Propaganda é a alma do negócio. Crédito: Akita." src="http://img200.yfrog.com/img200/8776/fu5.jpg" width="500" height="400" /><p class="wp-caption-text">A Propaganda é a alma do negócio. Crédito: Akita.</p></div>
<p>Na sexta, o negócio começou a pegar fogo. A visita do nosso PRESIDENTE atraiu curiosos de todos os tipos. Helicópteros sobrevoavam o campus da PUCRS, detectores de metais e batalões de repórteres que tiravam fotos até de mascotes fazendo embaixadinhas tornavam o ambiente um caos. Saí do trabalho e rumei para ver a palestra do Akita.</p>
<p><span id="more-192"></span></p>
<p>Ao chegar, tomei um susto ao receber o aviso que não poderia entrar pois o auditório estava LOTADO.  Sim, um auditório pra, sei lá, umas 300 pessoas, LOTADO. Com sorte, consegui entrar e perceber porque o Akita é sem dúvida, nosso Ruby Rockstar. Uma palestra sensacional, passeando alucinadamente por todos os pontos importantes do ecossistema do Rails, com demos, vídeos, live-coding e tudo mais. Sério, mais alguns minutos e eu acho que o cara iria dançar e cantar! Tenho certeza que os que não conheciam Rails &#8211; cerca de metade do público levantou a mão quando Akita questionou -, sairam impressionados da sala.</p>
<p>Os slides estão <a href="http://www.slideshare.net/akitaonrails/fisl-10 ">aqui</a> e o código <a href="http://github.com/akitaonrails/fisl_10_demo/tree/master">aqui</a> (Note que os capítulos estão separado por branches). </p>
<p>Em seguida foi a vez de <a href="http://mergulhao.info">Sylvestre Mergulhão</a> apresentar outra palestra interessantíssima sobre escalabilidade em projetos Rails, afinal, todos sabemos que Rails não escala :-P. O mais interessante da palestra de Sylvestre, pelo menos pra mim, foi a oportunidade de conhecer um bom exemplo de site com um bom número de visitas, rodando completamente em Rails, sobre nginx, hospedado na Engine Yard. Ou seja, um case que utiliza tudo que volta e meia a gente lê em blogs no exterior, portado e mantido por brasileiros!</p>
<p>Infelizmente, tive que voltar voando para o trabalho e não consegui trocar uma idéia com o Akita no estande da Locaweb. O papo terá que ser adiado para a Rails Summit desse ano :-). Aliás, foi uma pena minha falta de tempo para aproveitar mais as palestras. Queria ter visto outras apresentações como a do Boo-Blox ou a do Peter Sunde, criador do Pirate Bay que lotou 3 auditórios e engasgou as transmissões streaming do evento.</p>
<p>A parte rubista no FISL foi encerrada com a palestra de <a href="http://fisl.softwarelivre.org/10/papers/pub/programacao/596">PubSub do Pablo Lorenzzoni</a>. Infelizmente, não consegui comparecer, mas espero achar informações na internet para saber como foi este encerramento.</p>
<p>O saldo final foi extremamente positivo ao meu ver. Posso afirmar que estamos, como Rubistas, maduros suficientes para entrar em qualquer evento de informática e fazer bonito e surpreender outros desenvolvedores com a força de nosso conhecimento e o poder das ferramentas criadas em torno de nós.</p>
<img src="http://feeds.feedburner.com/~r/Buenoruby/~4/x7xksGwHo-s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/eventos/2009/06/a-comunidade-ruby-no-fisl-10/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.tbueno.com/blog/eventos/2009/06/a-comunidade-ruby-no-fisl-10/</feedburner:origLink></item>
	</channel>
</rss>
