<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Papo de Corredor</title>
	<atom:link href="http://papodecorredor.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://papodecorredor.wordpress.com</link>
	<description>Tudo que rola nos papos de corredor por aí...</description>
	<lastBuildDate>Thu, 22 Sep 2011 04:01:15 +0000</lastBuildDate>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='papodecorredor.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Papo de Corredor</title>
		<link>http://papodecorredor.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://papodecorredor.wordpress.com/osd.xml" title="Papo de Corredor" />
	<atom:link rel='hub' href='http://papodecorredor.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Resumo do Curso CSPO – Primeiro dia</title>
		<link>http://papodecorredor.wordpress.com/2010/06/29/resumo-curso-cspo-dia-1/</link>
		<comments>http://papodecorredor.wordpress.com/2010/06/29/resumo-curso-cspo-dia-1/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 03:19:02 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[eventos]]></category>
		<category><![CDATA[motivacional]]></category>
		<category><![CDATA[scrum]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[cspo]]></category>
		<category><![CDATA[po]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=264</guid>
		<description><![CDATA[Já faz algum tempo que não publico nada aqui no meu blog, bem acho que inicialmente preciso compartilhar a minha felicidade de estar já a três meses na Locaweb, que além de uma empresa competitiva no ramo de serviços de internet (Líder na prestação de serviços hospedados de TI), também é um excelente lugar para [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=264&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Já faz algum tempo que não publico nada aqui no meu blog, bem acho que inicialmente preciso compartilhar a minha felicidade de estar já a três meses na <a href="http://www.locaweb.com.br/default.html" target="_self">Locaweb</a>, que além de uma empresa competitiva no ramo de serviços de internet (<a href="http://www.locaweb.com.br/sobre-locaweb/empresa.html">Líder na prestação de serviços hospedados de TI</a>), também é um excelente lugar para trabalhar.</p>
<p>Entre os vários benefícios e atrativos que a empresa oferece, tais como um excelente ambiente de trabalho, desafios constantes e etc., ela também investe pesado em treinamento e aprecia ter pessoas ligadas a comunidade de software no seu quadro de colaboradores.</p>
<p>Nesse espírito de investir nos seus funcionários a Locaweb custeou a ida de algumas pessoas para o Agile Brazil 2010 em Porto Alegre e além disso possibilitou que algumas pessoas fizessem alguns cursos e é aí que eu entro, eu fui um dos premiados a fazer o curso do <a href="http://www.adaptworks.com.br/treinamentos/cspo.html" target="_self">CSPO (Certified Scrum Product Owner)</a>!</p>
<p><a href="http://papodecorredor.files.wordpress.com/2010/06/img_0250.jpg"><img class="aligncenter size-medium wp-image-271" title="Inicio do curso CSPO" src="http://papodecorredor.files.wordpress.com/2010/06/img_0250.jpg?w=300&#038;h=225" alt="Inicio do curso CSPO" width="300" height="225" /></a></p>
<p>O curso foi excelente, ministrado pelo <a href="http://blog.adaptworks.com.br/" target="_blank">Alexandre Magno</a> com o parceria do <a href="https://twitter.com/lcparzianello" target="_self">Luiz C. Parzianello</a>, apesar de o formato do curso com dois &#8220;Mestres de Cerimônia&#8221; não tenha ficado tão bom quanto o esperado, a integração dos assuntos abordados pelos dois foi excelente!</p>
<p>Para saber mais informações de como foi o dia a dia do curso, recomendo a leitura do post de um amigo que fiz lá o <a href="http://blog.anascimento.net/" target="_blank">André Nascimento</a> e de meu amigo <a href="http://locawebers.com.br/">locaweber</a> <a href="http://rafaelrosafu.com/">Rafael Rosa Fu</a>.</p>
<p>A partir de agora vou repassar um pouco do resumo que fui fazendo ao longo do curso, espero que aproveitem!</p>
<ul>
<li><strong>PO &#8211; todas as empresas tem problemas com esse papel do Scrum.</strong></li>
<p>Uma das primeiras frases do Alexandre Magno no curso foi que o papel do PO é um papel que merece mais atenção nas empresas pois ainda muita falta de experiência para executá-lo.</ul>
<ul>
<li><strong>No início havia muito foco no papel do time.</strong></li>
<p>Focava-se muito esforços no papel do time (Integrantes do time + Scrum Master) e agora é o momento de focar-se mais no papel do PO.</ul>
<ul>
<li><strong>Nada adianta um bom time se o produto está sendo desenvolvido errado.</strong></li>
<p>Aqui o recado é que não adianta ter ótimos técnicos no seu time e um Scrum Master excelente em facilitação, se o produto desenvolvido não estiver focado nas necessidades do cliente.</ul>
<ul>
<li><strong>Pouco adianta práticas de engenharia para o produto errado.</strong></li>
<p>Vale o mesmo recado da sentença anterior, TDD, Pair Programming, Continuos Integration pouco terão valor se o produto está errado no aspecto de negócio.</ul>
<ul>
<li><strong>Devemos focar mais esforço no negócio.</strong></li>
<p>Nossos esforços devem estar mais direcionado a atender as necessidades de negócio.</ul>
<ul>
<li><strong>Pouco material técnico e mais práticas para deixar as pessoas mais focadas (curso).</strong></li>
<p>Aqui foi uma frase que me chamou atenção, onde o Alexandre Magno deixou claro que o foco dele seria nas práticas e não em apostilinhas!</ul>
<p><a href="http://papodecorredor.files.wordpress.com/2010/06/img_0251.jpg"><img class="aligncenter size-medium wp-image-291" title="Excelentes Discussões" src="http://papodecorredor.files.wordpress.com/2010/06/img_0251.jpg?w=300&#038;h=225" alt="Excelentes Discussoes" width="300" height="225" /></a></p>
<ul>
<li><strong>Discussão do gerente de produto na (sua) empresa. Quais são as atribuições do Gerente Produto?</strong></li>
<p>Neste momento tivemos uma excelente discussão de qual seria o papel do Gerente de Produtos, se quiser saber a conclusão faça o curso <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  !</ul>
<ul>
<li><strong>Onde o GP e o PO se encontram (papéis)?</strong></li>
<p>Outra excelente discussão, onde falamos muito sobre a intersecção do papel do PO e do cargo Gerentes de Produtos.</ul>
<ul>
<li><strong>Scrum foi pensado para projetos e não para empresas.</strong></li>
<p>O Magno deu um recado que apesar de muito claro, tem muita gente que ainda não compreende que é o Scrum foi pensado para projetos e não para gestão de empresas! Ele foi bastante enfático nesse momento.</ul>
<ul>
<li><strong>PO é um papel do projeto e não da empresa&#8230; o GP é um cargo na empresa.</strong></li>
<p>Mais um recado muito claro do Magno, o PO é um papel e o gerente de Produtos é (deveria ser) um cargo na empresa.</ul>
<ul>
<li><strong>A necessidade de um PO inicia quando o projeto inicia, não antes!</strong></li>
<p>Não deveria ter PO eternos na empresa, a necessidade de um PO inicia quando o projeto inicia e não antes!</ul>
<ul>
<li><strong>Se não há projeto, não há Product Owner.</strong></li>
<p>Resumindo: &#8220;Se não há projeto, não deveria haver Product Owner!&#8221;</ul>
<ul>
<li><strong>Time de alto desempenho as vezes não entregam valor por causa do PO ruim.</strong></li>
<p>Um cruzado de direita do Magno, mesmo tendo um time de alto desempenho é muito provável não entregar nada de valor caso o PO for muito ruim.</ul>
<ul>
<li><strong>No mundo perfeito, todo PO será do cliente.</strong></li>
<p>O ideal seria que o PO sempre fosse do cliente, ou seja, muito ligado ao produto, mas nem sempre isso é possível.</ul>
<ul>
<li><strong>De nada adianta um PO do cliente se ele não priorizar, ou priorizar mal.</strong></li>
<p>Porém de nada adianta um PO do cliente se ele não for hábil para priorizar ou na pior das hipóteses priorizar mal.</ul>
<ul>
<li><strong>Mais difícil é encontrar lideres com objetivos do que times auto gerenciados.</strong></li>
<p>Esta sentença para mim está muito ligada ao que o Magno disse no início do curso, muito foi focado no time, agora é muito mais fácil encontrar times auto-gerenciados do que lideres com objetivos bem definidos.</ul>
<ul>
<li><strong>O comum é lideres com time sheeting do que com objetivos claros.</strong></li>
<p>Em muitas empresas que se auto denominam &#8220;Ágeis&#8221;, na verdade é comum encontrar liderem com um o gráfico de gantt e planilhinha de horas!</ul>
<ul>
<li><strong>PO deve ter um cuidado com o product backlog.</strong></li>
<p>O product backlog deve ser um filho para o PO, que deve cuidar, proteger, defender <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> !</ul>
<ul>
<li><strong>PO desenvolve a visão do produto e os passos para atingir o objetivo da visão.</strong></li>
<p>A tão falada visão do produto deve ser desenvolvida pelo PO assim como os passos para atingir o objetivo determinado na visão.</ul>
<ul>
<li><strong>O macro management fica na mão do PO.</strong></li>
<p>O macro management fica a cargo do PO, verificando as features e os releases numa perspectiva macro para atingir o objetivo do produto.</ul>
<ul>
<li><strong>O passos para atingir o objetivos das estórias (micro management) fica a cargo do time.</strong></li>
<p>Já o micro management fica com o time, ou seja, os passos (tarefas) para atingir o objetivo da sprint.</ul>
<ul>
<li><strong>O PO tem que realmente ser um porco do projeto (é difícil ser porco em dois projetos).</strong></li>
<p>O recado aqui é que é difícil dar o sangue (couro no caso do porco, <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ) em mais de um projeto, o PO sempre tem que se perguntar se será capaz de focar no projeto antes de ingressar nele.</ul>
<ul>
<li><strong>Scrum é incompleto e não precisa somente de práticas de engenharia, existem outro pontos (análise de risco, controle).</strong></li>
<p>Aqui um recado do Parzianello, todos sabemos que o Scrum é incompleto, mas não é somente pela falta de práticas de engenharia, na verdade também lhe falta análise de risco e outras disciplinas ligadas ao negócio.</ul>
<ul>
<li><strong>Scrum é controle! (reunião diária, review, definition of done).</strong></li>
<p>Apesar de soar muito estranho, mas Scrum é controle! Reunião diária, Review, Definition of Done, são provas que há sim, muito controle no Scrum, o que não tem é Comando!</ul>
<ul>
<li><strong>É interessante o time ter um integrante como Scrum Master exclusivo.</strong></li>
<p>Sempre que possível é interessante ter um protetor do Scrum e do time, esse papel responde pelo nome de Scrum Master, mas claro, se o time for maduro a ponto de achar interessante que esse papel possa ser executado por um integrante do time não há problemas.</ul>
<ul>
<li><strong>Quais são os seus valores?</strong></li>
<p>Aqui mais uma discussão aberta pelo Magno: Qual são seu valores? O que realmente importa para você?</ul>
<ul>
<li><strong>Dá para estimar o valor e o tempo com práticas ágeis?</strong></li>
<p>Mais uma discussão sobre a possibilidade de se fazer estimativas de valor e de prazo com práticas ágeis, mas com certeza deverá haver uma quebra de paradigmas de quem for fazer a estimativa, bem como de quem for recebê-la.</ul>
<ul>
<li><strong>Product roadmap com práticas ágeis tem que quebrar paradigmas.</strong></li>
<p>Ainda relacionado com a sentença anterior, deve-se quebrar paradigmas para se executar, receber e interpretar um product roadmap com práticas ágeis, caso contrário será difícil ter sucesso no projeto.</ul>
<ul>
<li><strong>Todo o ambiente de projeto deveria entender o que é Scrum para ter sucesso (principalmente patrocinadores e clientes!).</strong></li>
<p>Essa é mais uma sentença auto explicativa, para ter sucesso todo mundo tem que compreender o Scrum!</ul>
<ul>
<li><strong>Premissa para o PO: você realmente tem disponibilidade para esse papel?</strong></li>
<p>Ou seja, ou você estará disponível, envolvido ao projeto, caso contrário esse papel de PO <strong>NÃO</strong> é para você. Simples assim!</ul>
<p><a href="http://papodecorredor.files.wordpress.com/2010/06/img_0253.jpg"><img class="aligncenter size-medium wp-image-292" title="Agenda do PO" src="http://papodecorredor.files.wordpress.com/2010/06/img_0253.jpg?w=300&#038;h=224" alt="Agenda do PO" width="300" height="224" /></a></p>
<ul>
<li><strong>Atribuições do PO</strong></li>
<p>Definir a visão (com workshops etc.)<br />
Manter o product backlog<br />
Maximizar o ROI<br />
Gerenciar, planejar release<br />
Define as metas<br />
Leva as informações do projeto para fora (divulgar o projeto)<br />
Gerenciar conflitos de cliente, prioridades<br />
Fazer gerenciamento macro<br />
Bastante coisa, não?</ul>
<ul>
<li><strong>Meta: ou atingiu ou não atingiu!</strong></li>
<p>Simples, atingiu a meta ou não atingiu a meta, não existe meia meta!</ul>
<ul>
<li><strong>PO sem poder de decisão ou com baixa disponibilidade ou que não foi preparado para exercer o papel.</strong></li>
<p>Com um PO nessas condições será praticamente impossível ter um projeto de sucesso, ou se mitiga esses riscos ou é melhor nem iniciar o projeto.</ul>
<ul>
<li><strong>PO deve estar próximo no momento de quebrar tarefas.</strong></li>
<p>E muito importante o PO estar próximo (sempre que possível) quando se for quebrar as tarefas, para auxiliar o time, para que essa atividade tenha o máximo de precisão possível.</ul>
<ul>
<li><strong>QA junto com PO para descobrir estórias e definir critérios de aceitação.</strong></li>
<p>Outra dica do Magno, ter o QA próximo do PO no momento de descoberta de estórias e na definição dos critérios de aceitação.</ul>
<ul>
<li><strong>A cada review deve ser apresentado o que foi gerado para entregar aquele release!</strong></li>
<p>Esse foi um soco de esquerda, a cada review o time deve apresentar o que foi gerado para entregar aquele release, mas também é importante que o PO tenha em mãos tudo para o próximo release que será desenvolvido.</ul>
<ul>
<li><strong>Retrabalho nível 2 &#8211; problemas intrínsecos do projeto nível 1</strong></li>
<p>Aqui eu não me lembro, assim que eu lembrar atualizo aqui (poxa, o curso era de manhã!)</ul>
<ul>
<li><strong>Prestar atenção e conhecer Lean!</strong></li>
<p>Apesar de neste momento o Magno e o Parzianello estarem falando de Lean, fica a dica de também prestarem atenção ao Kanban.</ul>
<ul>
<li><strong>Proteger receita e diminuir custo.</strong></li>
<p>Aqui uma dica no Parzianello que fez a diferença, nós sempre pensamos no produto para aumentar as receitas ou lucros, mas muitas vezes poderíamos estar focados em proteger a receita atual e diminuir o custo. Esta discussão iniciou quando eu trouxe um problema enfrentado pelo meu time, sobre como eliminar o legado e entregar valor, nós não conseguíamos ver a possibilidade disso, mas na verdade o que nós queriamos era proteger a receita da empresa (manter os produtos atuais) porém diminuir o custo (software funcionando, manuteníveis, extensíveis com o mínimo possível de bugs), resumindo entregando valor sim!</ul>
<ul>
<li><strong>As vezes não é debito técnico, mas sim melhoria tecnológica.</strong></li>
<p>Ainda na discussão anterior, as vezes não podemos encarar tudo como débito técnico, mas sim melhoria tecnológica que na verdade também é entrega de valor.</ul>
<ul>
<li><strong>Técnica Elevator Statement para definir a visão do produto.</strong></li>
<p>Aqui fizemos uma excelente dinâmica para definir uma declaração que define a visão do produto, mais informações no curso.</ul>
<p><a href="http://papodecorredor.files.wordpress.com/2010/06/img_0254.jpg"><img class="aligncenter size-medium wp-image-294" title="Product Vision Box" src="http://papodecorredor.files.wordpress.com/2010/06/img_0254.jpg?w=300&#038;h=225" alt="Product Vision Box" width="300" height="225" /></a></p>
<ul>
<li><strong>Desenvolver o product vision box.</strong></li>
<p>Outra dinâmica show, foi o desenvolvimento do product vision box, o melhor, além da técnica e a explicação do Magno é claro, foi a integração com as outra pessoas que estavam fazendo o curso conosco. Foi um momento super descontraído e divertido!</ul>
<p>E assim terminamos o primeiro dia do CSPO e agora fico devendo o segundo post, até lá!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/264/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=264&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/06/29/resumo-curso-cspo-dia-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>

		<media:content url="http://papodecorredor.files.wordpress.com/2010/06/img_0250.jpg?w=300" medium="image">
			<media:title type="html">Inicio do curso CSPO</media:title>
		</media:content>

		<media:content url="http://papodecorredor.files.wordpress.com/2010/06/img_0251.jpg?w=300" medium="image">
			<media:title type="html">Excelentes Discussões</media:title>
		</media:content>

		<media:content url="http://papodecorredor.files.wordpress.com/2010/06/img_0253.jpg?w=300" medium="image">
			<media:title type="html">Agenda do PO</media:title>
		</media:content>

		<media:content url="http://papodecorredor.files.wordpress.com/2010/06/img_0254.jpg?w=300" medium="image">
			<media:title type="html">Product Vision Box</media:title>
		</media:content>
	</item>
		<item>
		<title>Ruby + Rails no Mundo Real 2010 &#8211; Resumo</title>
		<link>http://papodecorredor.wordpress.com/2010/05/31/ruby-rails-no-mundo-real-2010-resumo/</link>
		<comments>http://papodecorredor.wordpress.com/2010/05/31/ruby-rails-no-mundo-real-2010-resumo/#comments</comments>
		<pubDate>Mon, 31 May 2010 05:38:55 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[broadcast]]></category>
		<category><![CDATA[eventos]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ruby mundo real evento rails broadcast]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=259</guid>
		<description><![CDATA[No sábado passado (25/10/2010) aconteceu o Ruby + Rails no Mundo Real 2010, evento idealizado e organizado pelo Guru-SP (Grupo de Usuários Ruby de São Paulo). Bem, resumindo, esse post é apenas um broadcast de um excelente post escrito por Rodrigo Ribeiro, com um Resumo deste evento. Este post ficou tão bem feito que eu [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=259&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>No sábado passado (25/10/2010) aconteceu o <a href="http://guru-sp.com/evento/">Ruby + Rails no Mundo Real 2010</a>, evento idealizado e organizado pelo <a href="http://www.guru-sp.org/" target="_blank">Guru-SP</a> (Grupo de Usuários Ruby de São Paulo).</p>
<p>Bem, resumindo, esse post é apenas um <strong>broadcast</strong> de um excelente post escrito por <a href="http://templariodatecnologia.wordpress.com/about/">Rodrigo Ribeiro</a>, com um Resumo deste evento. Este post ficou tão bem feito que eu não tenho o que complementar ou escrever, apenas para convidar à todos para participar do grupo, das listas de discussão e dos próximos eventos!</p>
<p>Aproveitem!</p>
<p><a href="http://templariodatecnologia.wordpress.com/2010/05/31/minhas-impressoes-rubyrails-no-mundo-real-2010-290510/" target="_self">Minhas impressões – Ruby+Rails no mundo real 2010</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/259/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=259&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/05/31/ruby-rails-no-mundo-real-2010-resumo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>
	</item>
		<item>
		<title>Duck Typing Club</title>
		<link>http://papodecorredor.wordpress.com/2010/03/08/duck-typing-club/</link>
		<comments>http://papodecorredor.wordpress.com/2010/03/08/duck-typing-club/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 05:41:16 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[pragmatismo]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[duck typing]]></category>
		<category><![CDATA[teste]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=231</guid>
		<description><![CDATA[Sempre que pessoas que não conhecem o Duck Typing se deparam com esse estilo de programação torcem o nariz como um sinal de descrença. - Ah, mas na minha linguagem é mais seguro, é muito mais claro saber o tipo de objeto. Ok, na sua linguagem tem suas vantagens, mas o duck typing também tem [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=231&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:center;"><a href="http://papodecorredor.files.wordpress.com/2010/03/cartoon_duck.jpg"><img class="aligncenter size-full wp-image-240" style="border:0 none;" title="duck_typing" src="http://papodecorredor.files.wordpress.com/2010/03/cartoon_duck.jpg?w=300&#038;h=172" alt="Duck Typing" width="300" height="172" /></a></p>
<p>Sempre que pessoas que não conhecem o <a href="http://en.wikipedia.org/wiki/Duck_typing" target="_blank">Duck Typing</a> se deparam com esse estilo de programação torcem o nariz como um sinal de descrença.</p>
<blockquote><p><em>- Ah, mas na minha linguagem é mais seguro, é muito mais claro saber o tipo de objeto.</em></p></blockquote>
<p>Ok, na sua linguagem tem suas vantagens, mas o duck typing também tem as suas. Vamos a um exemplo numa linguagem que não faz parte do <strong>Duck Typing Club</strong>:</p>
<p><pre class="brush: java;">
import java.io.*;
public interface Musica{

	void setNome(String nome);
	String getNome();
	void setArtista(String artista);
	String getArtista();

	void adicionaParaArquivo(File arquivo);
}
</pre></p>
<p>O exemplo é simples, dada uma música queremos adicioná-la a um arquivo, como bons programadores, vamos escrever o código de teste.</p>
<p><pre class="brush: java;">
import java.io.*;
public class MusicaTest{

	@Test
	public void testAdicionarMusicaParaArquivo(){
		File arquivo = new File(&quot;arquivoTest.txt&quot;);
		Musica musica = new MusicaImpl(&quot;Sex Machine&quot;,&quot;James Brown&quot;);
		musica.adicionaParaArquivo(arquivo);

		...

	}

}
</pre></p>
<p>Vamos parar de escrever esse código por aqui, não aceitaremos ninguém que estiver fora do club!<br />
Percebam que como a interface diz que o método recebe um File, nós precisaremos passar um arquivo para ele!<br />
Um arquivo é um recurso relativamente barato, mas em outros casos escrever esse teste não seria uma tarefa tão fácil.</p>
<h3>Classes não são Tipos</h3>
<p>Apesar das linguagens estaticamente tipadas nos fazerem acreditar nisso, mesmo nelas, o tipo de um objeto muitas vezes é um conjunto de classes!<br />
Mas em Ruby, definitivamente, uma Classe não é um tipo de objeto, ao inves disso, em Ruby um objeto é definido pelo o que ele é capaz de fazer. Se ele anda como um pato, fala como um pato, dança como um pato, tem como amigo um rato, então ele é o <strong>Pato Donnald</strong>!</p>
<p>Vamos agora para o exemplo de um integrante do Duck Typing Club o Ruby!</p>
<p><pre class="brush: ruby;">
class Musica
  def initialize(nome, artista)
    @nome = nome
    @artista = artista
  end

  def adiciona_para_arquivo(arquivo)
    arquivo &lt;&lt; @nome &lt;&lt; &quot; - &quot; &lt;&lt; @artista
  end
end
</pre></p>
<p>Novamente, como pragmáticos que somos, já temos o teste para esta unidade de código:</p>
<p><pre class="brush: ruby;">
require 'test/unit'
require 'musica'

class TestMusica &lt; Test::Unit::TestCase
  def test_adiciona_para_arquivo
    musica = Musica.new(&quot;Sex Machine&quot;, &quot;James Brown&quot;)
    arquivo = File.open(&quot;musicas.txt&quot;,&quot;w&quot;) do |f|
      musica.adiciona_para_arquivo(f)
    end

    File.open(&quot;musicas.txt&quot;) do |f|
      assert_equal(&quot;Sex Machine - James Brown&quot;, f.gets)
    end
  ensure
    File.delete(&quot;musicas.txt&quot;) if File.exists?(&quot;musicas.txt&quot;)
  end
end
</pre></p>
<p>Trabalhoso né? Tivemos que criar o arquivo, reabrir para leitura e assegurar que ele foi apagado no fim do processo, pensando como &#8220;Pato&#8221;, nós só precisávamos de um objeto que respondesse a &#8220;&lt;&lt;&quot;, não é mesmo?</p>
<h3>Programando como um Pato</h3>
<p>Veja agora esse exemplo:</p>
<p><pre class="brush: ruby;">
require 'test/unit'
require 'musica'

class TestMusica &lt; Test::Unit::TestCase
  def test_adiciona_para_arquivo
    musica = Musica.new(&quot;Sex Machine&quot;, &quot;James Brown&quot;)
    arquivo = &quot;&quot;
    musica.adiciona_para_arquivo(arquivo)
    assert_equal(&quot;Sex Machine - James Brown&quot;, arquivo)
  end
end
</pre></p>
<p>E agora? Bem mais simples né, e como sabemos String responde a &#8220;&lt;&lt;&quot;, assim nosso teste funciona e fica muito mais simples, poderia até ser um Array, veja:</p>
<p><pre class="brush: ruby;">
require &#39;test/unit&#39;
require &#39;musica&#39;

class TestMusica &lt; Test::Unit::TestCase
  def test_adiciona_para_arquivo
    musica = Musica.new(&quot;Sex Machine&quot;, &quot;James Brown&quot;)
    arquivo = []
    musica.adiciona_para_arquivo(arquivo)
    assert_equal([&quot;Sex Machine&quot;,&quot; - &quot;,&quot;James Brown&quot;], arquivo)
  end
end
</pre></p>
<p>Mas você, cético que é, apesar de codificar com uma linguagem que faz parte do Clube, ainda assim tem motivos mais que plausíveis para dizer que precisa verificar o tipo do objeto recebido. Vamos ver se é isso que precisa:</p>
<p><pre class="brush: ruby;">
class Musica
  def initialize(nome, artista)
    @nome = nome
    @artista = artista
  end

  def adiciona_para_arquivo(arquivo)
    unless arquivo.kind_of?(File)
      fail TypeError.new(&quot;Um arquivo era esperado&quot;)
    end
    arquivo &lt;&lt; @nome &lt;&lt; &quot; - &quot; &lt;&lt; @artista
  end
end
</pre><br />
Pronto, zuou tudo agora!!! Parabéns, se era isso que você queria, conseguiu!<br />
Não né, você não é tão radical, a idéia era algo mais meio termo, vamos ver se é isso:<br />
<pre class="brush: ruby;">
class Musica
  def initialize(nome, artista)
    @nome = nome
    @artista = artista
  end

  def adiciona_para_arquivo(arquivo)
    unless arquivo.respond_to?(:&lt;&lt;)
      fail TypeError.new(&quot;&#39;arquivo&#39; precisa responder a &#39;&lt;&lt;&#39;&quot;)
    end
    arquivo &lt;&lt; @nome &lt;&lt; &quot; - &quot; &lt;&lt; @artista
  end

end
</pre></p>
<p>É, assim o testes passam, mas saiu do clube, mas ainda assim é bem melhor que o código anterior. Este você guarda para quando realmente for necessário, ok?</p>
<p>Então é isso, bem vindo ao Duck Typing Club!</p>
<p>Este post foi baseado na leitura do livro <a href="http://www.pragprog.com/titles/ruby3/programming-ruby-1-9" target="_blank">Programming in Ruby 1.9</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/231/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=231&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/03/08/duck-typing-club/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>

		<media:content url="http://papodecorredor.files.wordpress.com/2010/03/cartoon_duck.jpg" medium="image">
			<media:title type="html">duck_typing</media:title>
		</media:content>
	</item>
		<item>
		<title>JMS e JRuby é com o JSparrow!</title>
		<link>http://papodecorredor.wordpress.com/2010/02/28/jms-e-jruby-e-com-o-jsparrow/</link>
		<comments>http://papodecorredor.wordpress.com/2010/02/28/jms-e-jruby-e-com-o-jsparrow/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 18:49:15 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[engenharia de software]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jms]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[pragmatismo]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=219</guid>
		<description><![CDATA[Quem já trabalhou com JMS sabe que esta API não é muito trivial para trabalhar com mensageria, mas com Java por mais que utilize um framework para abstrair a complexidade, nós sempre chegaremos bem próximos do JMS e conseqüentemente deixaremos nosso códigos complexos! Bem com JRuby isso já não é um problema, existe um projeto [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=219&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Quem já trabalhou com <a href="http://java.sun.com/products/jms/" target="_blank">JMS</a> sabe que esta API não é muito trivial para trabalhar com mensageria, mas com Java por mais que utilize um framework para abstrair a complexidade, nós sempre chegaremos bem próximos do JMS e conseqüentemente deixaremos nosso códigos complexos!</p>
<p>Bem com <a href="http://jruby.org/" target="_blank">JRuby</a> isso já não é um problema, existe um projeto que abstrai (onde é possível) a complexidade do JMS e torna nosso trabalho bem mais simples e sabem o melhor? <strong>É DO BRASIL</strong>!!!</p>
<p><a href="http://github.com/leandrosilva/jsparrow" target="_blank">JSparrow</a>, é um projeto hospedado no <a href="https://github.com/" target="_blank">github</a>, está em pleno desenvolvimento e tem como idealizador <a href="http://leandrosilva.com.br/" target="_blank">Leandro Silva</a>. Na última versão a 1.1.1 o projeto ganhou, entre outras features, a possibilidade de implementação de um Listener (tanto para filas e tópicos) e isto possibilitará a conclusão deste post.</p>
<p>Neste tópico vamos escrever um código clássico, para quem aprendeu JMS por livros com certeza já escreveu um Chat básico para ser usado na linha de comando, então, é isso que faremos agora.</p>
<p>O exemplo é muito simples, vamos criar um tópico em um Application Server, no meu caso foi no <a href="http://www.oracle.com/appserver/weblogic/enterprise-edition.html" target="_blank">Weblogic</a>, por que? Porque eu gosto de sofrer, oras! Depois vamos nos registrar nesse tópico e criar um listener para ficar escutando-o, tudo bem simples.</p>
<p>Então vamos ficar assim, o pré-requisito é que você tenha um provedor JMS, no meu caso como eu disse foi o Weblogic, mas eu <span style="text-decoration:line-through;"><strong>não</strong></span> o recomendo, a escolha mais simples caso você não tenha experiência é o <a href="http://openjms.sourceforge.net/" target="_blank">OpenJMS</a>, o mesmo usado nos exemplos do JSparrow.</p>
<p>O exemplo escrito em Java pode ser visto no site <a href="http://onjava.com/pub/a/onjava/excerpt/jms_ch2/index.html?page=2" target="_blank">onjava.com</a> e o nosso veremos a seguir:</p>
<p>Instalando a gem</p>
<p><pre class="brush: plain;">
gem install jsparrow
</pre></p>
<p>Crie um arquivo chamado chat_com_jsparrow.rb.<br />
Adicionando a gem ao exemplo:</p>
<p><pre class="brush: ruby;">
require 'rubygems'
require 'jsparrow'
</pre></p>
<p>Recebendo parâmetros de linha e parametrizando a conexão com o provider.</p>
<p><pre class="brush: ruby;">
$NOME = ARGV[0] if ARGV[0]

JSparrow::Connection.configure do |connection|
  # adicione aqui a lib do client do seu provider
  connection.use_jms_client_jar '/Users/alan/Oracle/Middleware/wlserver_10.3/server/lib/weblogic.jar'

  # verifique as configurações do seu provider
  connection.use_jndi_properties :initial_context_factory =&gt; 'weblogic.jndi.WLInitialContextFactory',
                                 :provider_url            =&gt; 't3://localhost:7001',
                                 :security_principal      =&gt; 'weblogic',
                                 :security_credentials    =&gt; 'weblogic123'
   # o nome da factory e do topico que voce criou
  connection.enable_connection_factories :topic_connection_factory =&gt; 'ConnectionFactory'
  connection.enable_topics :chat_topic =&gt; 'MyTopic'
end
</pre></p>
<p>Iniciando a conexão e criando o sender para enviar as mensagens.</p>
<p><pre class="brush: ruby;">
jms_client = JSparrow::Connection.new_client
jms_client.start
topic_sender = jms_client.topic_sender(:chat_topic)
</pre></p>
<p>Criando a implementação do listener.</p>
<p><pre class="brush: ruby;">
class ChatTopicListener &lt; JSparrow::Connection::Listener
   listen_to :topic =&gt; :chat_topic

   def on_receive_message(received_message)
      puts &quot;#{received_message.text}&quot;
   end
end
</pre></p>
<p>Registrando o listener e iniciando a &#8220;escutação&#8221; rs!</p>
<p><pre class="brush: ruby;">
listener = JSparrow::Connection.new_listener :as =&gt; ChatTopicListener
listener.start_listening
</pre></p>
<p>Enviando as mensagens, começando a diversão!</p>
<p><pre class="brush: ruby;">
texto = &quot;&quot;
while texto != &quot;exit&quot;
   print &quot;Escreva seu texto: &quot;
   texto = STDIN.gets.strip
   mensagem = texto
   mensagem = &quot;#{$NOME} escreveu: #{mensagem}&quot; if $NOME
   topic_sender.send_text_message(mensagem)
end
</pre></p>
<p>Finalizando.</p>
<p><pre class="brush: plain;">
listener.stop_listening
jms_client.stop
</pre></p>
<p>Fácil né? Vamos colocar para rodar!</p>
<p><pre class="brush: plain;">
bash$&gt; jruby chat_com_jsparrow.rb Um_nome
</pre></p>
<p>E em outro terminal</p>
<p><pre class="brush: plain;">
bash$&gt; jruby chat_com_jsparrow.rb Outro_nome
</pre></p>
<p>Escreva as mensagens e veja o resultado.</p>
<p>O JSparrow tem mais características interessante e avançadas, como por exemplo colocar critérios na seleção de mensagens no tópico ou em filas, então não deixe de acompanhar o projeto no github.</p>
<p>O código deste post pode ser encontrado no <a href="http://gist.github.com/317717" target="_blank">aqui</a>, deixei o exemplo com seleção de mensagens.</p>
<p>Por hoje é só pessoal! Não esqueça de deixar seu comentário.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/219/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/219/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/219/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=219&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/02/28/jms-e-jruby-e-com-o-jsparrow/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>
	</item>
		<item>
		<title>EJB 3.0 no Weblogic e JRuby, será que rola?</title>
		<link>http://papodecorredor.wordpress.com/2010/02/24/ejb-3-0-no-weblogic-e-jruby-sera-que-rola/</link>
		<comments>http://papodecorredor.wordpress.com/2010/02/24/ejb-3-0-no-weblogic-e-jruby-sera-que-rola/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 07:57:30 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[engenharia de software]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[motivacional]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[weblogic]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=207</guid>
		<description><![CDATA[Não sei se todos aqui vem aqui no blog sabem, mas atualmente trabalho como Arquiteto de Sistemas da CVC Turismo, como não é o foco do post deixarei para falar sobre minhas atividades diarias outro dia ! Bem, entre o dia 23 e 24 de fevereiro (ontem e hoje considerando o dia que escrevi esse [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=207&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Não sei se todos aqui vem aqui no blog sabem, mas atualmente trabalho como <a href="http://en.wikipedia.org/wiki/Systems_architect" target="_blank">Arquiteto de Sistemas</a> da <a href="http://www.cvc.com.br/" target="_blank">CVC Turismo</a>, como não é o foco do post deixarei para falar sobre minhas atividades diarias outro dia <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  !</p>
<p>Bem, entre o dia 23 e 24 de fevereiro (ontem e hoje considerando o dia que escrevi esse post) fiquei ajudando em um deploy e uma preparação de uma aplicação para uma apresentação. Entre um build, um deploy, uma leitura de um log, fiquei &#8220;rascunhando uns códigos&#8221;.</p>
<p>O que eu queria era fazer lookup de <a href="http://java.sun.com/products/ejb/" target="_blank">EJB</a> de uma aplicação centralizadora de serviços de negócio que temos lá, com <a href="http://jruby.org/" target="_blank">JRuby</a>!<br />
Considerando que quando migramos de <a href="http://www.oracle.com/technology/tech/java/oc4j/index.html" target="_blank">OC4J</a> para <a href="http://www.oracle.com/appserver/weblogic/standard-edition.html" target="_blank">Weblogic</a> (essa migração ainda está rolando) tivemos muito problemas com EJB&#8217;s, achei que eu não ia conseguir fazer esse tal <a href="http://www.java2s.com/Tutorial/Java/0415__EJB3/UseInitialContextToLookupEJB.htm" target="_blank">lookup</a> em 1 ou 2 horas, então fiquei nos código apenas para passar o tempo.<br />
Acabei encontrando um <a href="http://javahowto.blogspot.com/2007/12/calling-weblogic-ejb-3-from-jruby-and.html" target="_blank">post</a> que me ajudou na brincadeira. E o resultado disso eu vou mostrar a seguir:</p>
<p>Primeiro o código Java para a gente entender o que foi feito:</p>
<p><pre class="brush: java;">
import javax.ejb.*;
import javax.naming.*;
import br.com.cvc.systur.app.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import br.com.cvc.systur.domain.pessoa.*;
import br.com.cvc.systur.app.pessoa.*;
import br.com.cvc.systur.domain.pessoa.documento.*;

public class Client {
    public static void main(String[] args) throws Exception {
         Context ic = new InitialContext();
         Object obj = ic.lookup(ServiceCatalog.CONSULTA_PESSOA.getName());

         ConsultaPessoaService cps =(ConsultaPessoaService) obj;

          for(TipoDocumento tp : cps.consultarDocumentos()){
               System.out.println(tp.getDescricao());
          }
    }
}
</pre></p>
<p>Aqui já temos as &#8220;particularidades&#8221; do Weblogic aparecendo, como podem nós temos um catálogo com todos os serviços, não entrarei em detalhes, mas ele serve, além de outras coisas, para obtermos o nome do <em>bidding</em> do objeto na arvore <a href="http://java.sun.com/products/jndi/" target="_blank">JNDI</a>, entenderemos melhor no código JRuby.</p>
<p>Este código obtém o EJB que representa um serviço de consulta de pessoas e utilizamos a operação consultarDocumentos para obter todos os tipos de documentos que trabalhamos, simples, muito simples!</p>
<p>Agora vamos ao JRuby</p>
<p><pre class="brush: ruby;">
require 'java'
include_class 'javax.naming.InitialContext'

ic = InitialContext.new
teste = ic.lookup('systur-domainsystur-domain-ejb_jarConsultaPessoaServiceBean_ConsultaPessoaService')

tipo_docs = teste.consultarDocumentos

tipo_docs.each { |tipo_doc| puts tipo_doc.descricao }
</pre></p>
<p>Olhe o lookup, veja o nome de ligação padrão no Weblogic, sei que não é o foco do post, mas entendeu porque temos o nosso &#8220;Catalogo&#8221;, isso porque nem vou entrar nos detalhes de como fazemos versionamento dos nosso serviços!</p>
<p>Esse código em JRuby, mas exatamente a mesma coisa que o código em Java, obtém o EJB e utilizamos um método e imprimimos a descrições dos tipos de documento.</p>
<p>Terminada toda a diversão, o trabalho da madrugada foi feito e eu estou aqui agora, cheio de idéias, entre elas melhorar nossa base de testes (que é um debito técnico nosso!) e deixa-los mais expressivos com JRuby, ou mesmo validar a saúde de nossa aplicação em produção rodando um simples script e executar testes de em produção (audacioso)!</p>
<p>É isso, mais uma barreira do Weblogic quebrada e mais uns 100 pontos na balança do Ruby e do JRuby!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/207/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=207&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/02/24/ejb-3-0-no-weblogic-e-jruby-sera-que-rola/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>
	</item>
		<item>
		<title>Primeiro projeto Rails com MongoDB</title>
		<link>http://papodecorredor.wordpress.com/2010/02/20/primeiro-projeto-rails-com-mongodb/</link>
		<comments>http://papodecorredor.wordpress.com/2010/02/20/primeiro-projeto-rails-com-mongodb/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 04:15:12 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[engenharia de software]]></category>
		<category><![CDATA[motivacional]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[pragmatismo]]></category>
		<category><![CDATA[teste]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=160</guid>
		<description><![CDATA[Você que leu o post 10 minutos com Ruby e MongoDB, provavelmente ficou pensando: &#8220;Como incluo o MongoDB no meu projeto Rails?&#8221;, bem, este post vem com intuito de ajudá-lo nesta sua dúvida cruel! Nós poderíamos criar um projeto Rails com e ir ajustando-o, mas tem um jeito mais fácil para esta tarefa, eu encontrei [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=160&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Você que leu o post <a href="http://papodecorredor.wordpress.com/2010/02/19/10-minutos-de-ruby-e-mongodb/" target="_blank">10 minutos com Ruby e MongoDB</a>, provavelmente ficou pensando: &#8220;Como incluo o MongoDB no meu projeto Rails?&#8221;, bem, este post vem com intuito de ajudá-lo nesta sua dúvida cruel!</p>
<p>Nós poderíamos criar um projeto Rails com e ir ajustando-o, mas tem um jeito mais fácil para esta tarefa, eu encontrei <a href="http://www.mongodb.org/display/DOCS/Rails+-+Getting+Started" target="_self">esses</a> <a href="http://gist.github.com/181842" target="_self">templates</a> e ajustei um pouco para escrever esse post.</p>
<p>Na pratica eu retirei alguns pontos e inclui outros para simplifica-lo, mas nada que altere o objetivo principal, criar um projeto Rails com MongoDB!</p>
<h3>O Template passo a passo</h3>
<p>Abaixo será apresentado o template usado para criar novas aplicações Rails com MongoDB, você também poderá ver o template aqui: <a href="http://gist.github.com/307386" target="_self">http://gist.github.com/307386</a>.</p>
<p>Removendo arquivos desnecessários</p>
<p><pre class="brush: ruby;">
run &quot;rm public/index.html&quot;
run &quot;rm public/images/rails.png&quot;
</pre></p>
<p>Colocando o nome do seu banco no MongoDB e editando o arquivo database.yml com os dados do banco</p>
<p><pre class="brush: ruby;">
db_name = ask('Qual será o nome do seu banco no mongodb? ')

# Editando o arquivo database.yml
# Com os dados do banco
file 'config/database.yml', &lt;&lt;-CODE
base: &amp;base
  adapter: mongodb
  # em tempo de execucao vamos adicionar o &quot;-\#{Rails.env}&quot; ao nomo do banco
  database: &quot;#{db_name}&quot;
# Se estiver rodando o mongodb em outro host,
#vc deveria autenticar-se
  #host: host.mongodb.com
  #username: your-username
  #password: your-password

# use as proximas linhas para colocar algo especifico a cada ambiente
development:
  &lt;&lt;: *base

test:
  &lt;&lt;: *base

production:
  &lt;&lt;: *base
CODE
</pre></p>
<p>Colocando um arquivo na inicialização do rails. Este arquivo será encarregado de conectar no banco</p>
<p><pre class="brush: ruby;">
initializer 'database.rb', &lt;&lt;-CODE
include MongoMapper

db_config = YAML::load(File.read(File.join(Rails.root, &quot;/config/database.yml&quot;)))

if db_config[Rails.env] &amp;&amp; db_config[Rails.env]['adapter'] == 'mongodb'
  mongo = db_config[Rails.env]
  MongoMapper.connection = Mongo::Connection.new(mongo['host'] || 'localhost',
                                                 mongo['port'] || 27017,
                                                :logger =&gt; Rails.logger)
  MongoMapper.database = &quot;\#{mongo['database']}-\#{Rails.env}&quot;

  if mongo['username'] &amp;&amp; mongo['password']
    MongoMapper.database.authenticate(mongo['username'], mongo['password'])
  end
end

ActionController::Base.rescue_responses['MongoMapper::DocumentNotFound'] = :not_found
CODE
</pre></p>
<p>Não precisamos do Active Record.</p>
<p><pre class="brush: ruby;">
environment 'config.frameworks -= [:active_record]'
</pre></p>
<p>Adicionando a gem do MongoMapper</p>
<p><pre class="brush: ruby;">
gem 'mongo_mapper'
</pre></p>
<p>Adicionando um Testing Helper, que adicionará o método teardown (executado no fim do teste) para todas as classes que herdam ActiveSupport::TestCase</p>
<p><pre class="brush: ruby;">
file 'test/test_helper.rb', &lt;&lt;-CODE
ENV['RAILS_ENV'] = 'test'
require File.expand_path(File.dirname(__FILE__) + '/../config/environment')
require 'test_help'

class ActiveSupport::TestCase
  # Apagando todas colecoes depois de cada test case
  def teardown
    MongoMapper.database.collections.each do |coll|
      coll.remove
    end
  end

# adicionando o metodo teardown em todos test cases
  def inherited(base)
    base.define_method teardown do
      super
    end
  end
end
CODE
</pre></p>
<p>Finalizando o gerenciamento das gems</p>
<p><pre class="brush: ruby;">
rake 'gems:install'
rake 'gems:unpack'
rake 'rails:freeze:gems'
</pre></p>
<p>Ignorando alguns arquivos no controle de versão e comitando no <a href="http://git-scm.com/" target="_blank">git</a></p>
<p><pre class="brush: ruby;">
file '.gitignore', &lt;&lt;-FILES
.DS_Store
**/.DS_Store
log/*
tmp/*
tmp/**/*
FILES

# comitando os fontes
git :init
git :add =&gt; '.'
msg_git = ask('Escreva seu comentario no commit do git')
git :commit =&gt; &quot;-a -m \&quot;#{msg_git}\&quot;&quot;
</pre></p>
<h3>Gerando sua aplicação Rails</h3>
<p><pre class="brush: plain;">
rails nome_da_aplicacao -m &quot;http://gist.github.com/307386.txt&quot;
ou
rails nome_da_aplicacao -m &quot;caminho_do_template&quot;
</pre></p>
<h3>Usando o generate</h3>
<p>Na raiz do seu projeto recém criado rode:<br />
<pre class="brush: plain;">
ruby script/generate scaffold user
</pre><br />
Aqui tem um ponto de atenção! O model não foi criado, isto porque não temos o ActiveRecord, mas calma será tudo muito simples, não desista agora!</p>
<h3>Criando o Model</h3>
<p>Seremos simples para não complicar! Um simples modelo de usuário (user.rb) a seguir:</p>
<p><pre class="brush: ruby;">
# Diferente do ActiveRecord com o MongoMapper usamos inclusão ao invés de herança
class User
  include MongoMapper::Document

  # cada atributo deve ter o nome (como um Symbol) e seu tipo
  key :nome, String
  key :email, String
  key :nickname, String

  # para utilizar os Helper do ActionView é importante sobrescrever o método &quot;to_s&quot;
  def to_s
    self._id
  end
end
</pre></p>
<p>E as <a href="http://guides.rubyonrails.org/migrations.html" target="_blank">migrations</a>??? É aqui não tem migrations, nós não precisamos nem criar o banco no MongoDB, a primeira vez que rodar a aplicação e utilizar o Model, voilá! Lá estarão as coleções!</p>
<h3>Ajustando a view do CRUD</h3>
<p>Aqui vamos chover um pouco no molhado, mas informação nunca é demais!</p>
<p><strong>index.html.erb</strong><br />
Como eu disse acima, na construção do Model, o helper &#8220;link_to&#8221; usa o método &#8220;to_s&#8221; para construir os links no CRUD, nosso index ficará assim:</p>
<p><pre class="brush: xml;">
&lt;h1&gt;Listando Usuários&lt;/h1&gt;

&lt;table&gt;
  &lt;tr&gt;
	&lt;th&gt;Nome&lt;/th&gt;
	&lt;th&gt;Email&lt;/th&gt;
	&lt;th&gt;Nickname&lt;/th&gt;
  &lt;/tr&gt;

&lt;% @users.each do |user| %&gt;
  &lt;tr&gt;
	&lt;td&gt;&lt;%= user.nome%&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= user.email%&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= user.nickname%&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Show', user %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Edit', edit_user_path(user) %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Destroy', user, :confirm =&gt; 'Are you sure?', :method =&gt; :delete %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;

&lt;br /&gt;

&lt;%= link_to 'New user', new_user_path %&gt;
</pre></p>
<p><strong>show.html.erb</strong><br />
Vale a dica do &#8220;link_to&#8221; mostrada no index</p>
<p><pre class="brush: xml;">
&lt;b&gt;Nome&lt;/b&gt;: &lt;%= @user.nome %&gt;&lt;br /&gt;
&lt;b&gt;E-mail/&lt;b&gt;: &lt;%= @user.email %&gt;&lt;br /&gt;
&lt;b&gt;Nickname&lt;/b&gt;: &lt;%= @user.nickname %&gt;&lt;br /&gt;
&lt;%= link_to 'Edit', edit_user_path(@user) %&gt; |
&lt;%= link_to 'Back', users_path %&gt;
</pre></p>
<p><strong>new.html.erb</strong><br />
Nada de novo!</p>
<p><pre class="brush: xml;">
&lt;h1&gt;Novo Usuário&lt;/h1&gt;

&lt;% form_for(@user) do |f| %&gt;
  &lt;%= f.error_messages %&gt;

&lt;table&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;%= f.label :nome %&gt;:&lt;/td&gt;
		&lt;td&gt;&lt;%= f.text_field :nome, :size =&gt; 40 %&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;%= f.label :email, 'E-mail' %&gt;&lt;/td&gt;
		&lt;td&gt;&lt;%= f.text_field :email %&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;%= f.label :nickname, 'Nickname' %&gt;&lt;/td&gt;
		&lt;td&gt;&lt;%= f.text_field :nickname %&gt;&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;

  &lt;p&gt;
    &lt;%= f.submit 'Create' %&gt;
  &lt;/p&gt;
&lt;% end %&gt;

&lt;%= link_to 'Back', users_path %&gt;
</pre></p>
<p><strong>edit.html.erb</strong><br />
Aqui também nada de novo.</p>
<p><pre class="brush: xml;">
&lt;h1&gt;Editando usuário&lt;/h1&gt;

&lt;% form_for(@user) do |f| %&gt;
  &lt;%= f.error_messages %&gt;

&lt;table&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;%= f.label :nome %&gt;:&lt;/td&gt;
		&lt;td&gt;&lt;%= f.text_field :nome, :size =&gt; 40 %&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;%= f.label :email, 'E-mail' %&gt;&lt;/td&gt;
		&lt;td&gt;&lt;%= f.text_field :email %&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;%= f.label :nickname, 'Nickname' %&gt;&lt;/td&gt;
		&lt;td&gt;&lt;%= f.text_field :nickname %&gt;&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;

  &lt;p&gt;
    &lt;%= f.submit 'Update' %&gt;
  &lt;/p&gt;
&lt;% end %&gt;

&lt;%= link_to 'Show', @user %&gt; |
&lt;%= link_to 'Back', users_path %&gt;
</pre></p>
<h3>Adicionando validações</h3>
<p><pre class="brush: ruby;">
class User

  # obrigatoriedade +++++++++++++++++++++++++++++++++++++
  validates_presence_of :nome
  validates_presence_of :nickname

  # validando o formato +++++++++++++++++++++++++++++++++
  # nao use essa REGEX em seus projetos, é mto simples!!!
  REGEX_EMAIL = /[a-zA-Z0-9_.]+@([a-z0-9_]+\.)+[a-z]{2,5}\z/
  validates_format_of :email, :with =&gt; REGEX_EMAIL, allow_blank =&gt; false
end
</pre></p>
<h3>Rodando nossa aplicação</h3>
<p>Suba o MongoDB</p>
<p><pre class="brush: plain;">
[MONGODB_HOME]/bin/mongod &amp;
</pre></p>
<p>Agora sua aplicação</p>
<p><pre class="brush: plain;">
ruby [app_name_dir]/script/server &amp;
</pre></p>
<p>Em um browser entre: <a href="http://localhost:3000/users" target="_blank">http://localhost:3000/users</a> e divirta-se! Teste o MongoDB&#8230;</p>
<h3>Testando</h3>
<p>Com o MongoMapper é muito facil escrever testes, mas por favor, não escreva só testes tão obvios e nem faça tanta duplicação do código como neste exemplo!!!<br />
Essa classe como é filha de <strong>ActiveSupport::TestCase</strong> terá o método <em>tearDown</em> adicionado, que será encarregado de remover os dados do banco no final do teste, já que no MongoDB os testes não serão envolvidos em uma transação do banco.</p>
<p><pre class="brush: ruby;">
require 'test_helper'

class UserTest &lt; ActiveSupport::TestCase

  test &quot;validar a presença do nome&quot; do
    user = User.new
    user.save
    assert_equal &quot;can't be empty&quot;, user.errors.on(:nome)
  end

  test &quot;validar a presença do email&quot; do
    user = User.new
    user.save
    assert_equal &quot;is invalid&quot;, user.errors.on(:email)
  end

  test &quot;ter o e-mail com letrar minusculas&quot; do
    user = User.new
    user.save
    user.email = &quot;ALAN@EMAIL.COM&quot;
    assert_equal &quot;is invalid&quot;, user.errors.on(:email)
  end

  test &quot;ter um email valido&quot; do
    user = User.new
    user.save
    user.email = &quot;123alan@email&quot;
    assert_equal &quot;is invalid&quot;, user.errors.on(:email)
  end

  test &quot;gravar o usuario quando estiver corretamente preenchido&quot; do
    user = User.new
    user.email = &quot;alan@email.com&quot;
    user.nickname = &quot;alan&quot;
    user.nome = &quot;Alan&quot;
    user.save
    assert_equal true, user.errors.empty?
  end
end
</pre></p>
<p>Então é isso, acho que agora você esta mais encorajado a escrever usa primeira aplicação com Rails e MongoDB! Os fontes usados neste post podem ser encontrados no git: <a href="http://github.com/alanrrb/Primeiro-projeto-Rails-com-MongoDB" target="_blank">http://github.com/alanrrb/Primeiro-projeto-Rails-com-MongoDB</a></p>
<p>Ah! Não se esqueça de deixar seu comentário!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/160/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/160/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=160&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/02/20/primeiro-projeto-rails-com-mongodb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>
	</item>
		<item>
		<title>10 minutos de Ruby e MongoDB</title>
		<link>http://papodecorredor.wordpress.com/2010/02/19/10-minutos-de-ruby-e-mongodb/</link>
		<comments>http://papodecorredor.wordpress.com/2010/02/19/10-minutos-de-ruby-e-mongodb/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 05:50:56 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=142</guid>
		<description><![CDATA[Continuando os meus estudos no movimento NoSQL, minha nova diversão é o MongoDB, mais um banco baseado em documentos. Agora você vai me perguntar: &#8220;Mas é o CouchDB que você estava estudando a um tempo atrás?&#8221;, calma caro leitor, é sempre bom ter varias ferramentas na caixa! Vamos a uma breve descrição do MongoDB: MongoDB [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=142&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Continuando os meus estudos no movimento <a href="http://en.wikipedia.org/wiki/NoSQL" target="_blank">NoSQL</a>, minha nova diversão é o <strong><a href="http://www.mongodb.org/display/DOCS/Home" target="_blank">MongoDB</a></strong>, mais um banco baseado em documentos. Agora você vai me perguntar: &#8220;Mas é o <a href="http://couchdb.apache.org/" target="_blank">CouchDB</a> que você estava estudando a um tempo atrás?&#8221;, calma caro leitor, é sempre bom ter varias ferramentas na caixa!<br />
Vamos a uma breve descrição do <strong>MongoDB:</strong></p>
<ul>
<li><strong>MongoDB</strong> tem coleções de dados, mas não tabelas como conhecemos. Diferente do CouchDB, que também é um banco orientado a documentos, o MongoDB tem namespaces para dados, estes são &#8220;schema-less&#8221;, assim os dados poderiam estar organizados por namespaces. Você pode ter seus dados em cada coleção, semelhante ao <a href="http://ar.rubyonrails.org/" target="_blank">ActiveRecord</a> com <a href="http://www.mysql.com" target="_blank">Mysql</a> ou qualquer <a href="http://pt.wikipedia.org/wiki/Sistema_de_gerenciamento_de_banco_de_dados" target="_blank">SGDB</a>.</li>
</ul>
<ul>
<li><strong>MongoDB</strong> tem indexes. Mesmo que que em cada coleção não tenha um &#8220;schema&#8221;, podemos ainda assim criar indexes e deixar as consultas ainda mais rápidas.</li>
</ul>
<ul>
<li><strong>MongoDB</strong> tem uma linguagem de consulta. Embora você possa usar o JavaScript para pesquisa através de uma coleção, como CouchDB, você também terá acesso a uma rica linguagem de consulta que pode filtrar com base nos campos, como o SQL, e filtrar com base no conteúdo dos documentos incorporados. Em vez de um complexo JOIN, você pode consultar todos os documentos da coleção de Posts que tiveram um comentário ou mais comentários no último mês de forma simples.</li>
</ul>
<p>Bem vamos ao que interessa, <em>a diversão</em>!!!</p>
<p>Começaremos instalando o <strong>MongoDB</strong>, para não ser repetitivo, você encontrará mais informações no <a href="http://www.mongodb.org/display/DOCS/Quickstart" target="_blank">site oficial</a>.</p>
<blockquote><p>Galera do MacOS, prefiram seguir as instruções ao invés de usar o macports, eu tive problemas instalando o mongodb por ele(na verdade com as dependências), as instruções no site do <strong>MongoDB</strong> são muito mais simples.</p></blockquote>
<p>Bem com tudo instalado vamos ao Ruby. Primeiro instale as gems:</p>
<p><pre class="brush: ruby;">
gem install gemcutter
</pre></p>
<p>Depois as gems dos drivers do <strong>MongoDB</strong>.</p>
<p><pre class="brush: ruby;">
gem install mongo
gem install mongo_ext
</pre></p>
<h3>Só mais 8 minutos&#8230;</h3>
<p>Em um terminal IRB rode.</p>
<p><pre class="brush: ruby;">
require 'rubygems'
require 'mongo'
</pre></p>
<p>Conectando no banco:</p>
<p><pre class="brush: ruby;">
conn = Mongo::Connection.new
db = conn.db(&quot;meu_bd&quot;)
</pre></p>
<p>Definindo uma coleção</p>
<p><pre class="brush: ruby;">
coll_usuarios = db.collection(&quot;usuarios&quot;)
</pre></p>
<p>Inserindo documentos em uma coleção</p>
<p><pre class="brush: ruby;">
coll_usuarios.insert({:nome =&gt; &quot;Alan&quot;,
:email =&gt; &quot;alanrrb@gmail.com&quot;,
:nickname =&gt; &quot;alanrrb&quot;})

coll_usuarios.insert({:nome =&gt; &quot;Jose&quot;,
:email =&gt; &quot;jose12332@gmail.com&quot;,
:nickname =&gt; &quot;jose123321&quot;})

coll_usuarios.insert({:nome =&gt; &quot;Tom&quot;,
:email =&gt; &quot;tom321123@gmail.com&quot;,
:nickname =&gt; &quot;tom321123&quot;})
</pre></p>
<p>Consultando um registro</p>
<p><pre class="brush: ruby;">
usuario = coll_usuarios.find_one()
p usuario
</pre></p>
<p><pre class="brush: ruby;">
{&quot;_id&quot;=&gt;4b7e23b01919ba0353000001, &quot;nome&quot;=&gt;&quot;Alan&quot;, &quot;email&quot;=&gt;&quot;alanrrb@gmail.com&quot;, &quot;nickname&quot;=&gt;&quot;alanrrb&quot;}
</pre></p>
<p>Buscando todos documentos com o nome &#8220;Tom&#8221;</p>
<p><pre class="brush: ruby;">
coll_usuarios.find(:nome =&gt; &quot;Tom&quot;).each do |doc|
p doc
end
</pre></p>
<p><pre class="brush: ruby;">
{&quot;_id&quot;=&gt;4b7e23b01919ba0353000003, &quot;nome&quot;=&gt;&quot;Tom&quot;, &quot;email&quot;=&gt;&quot;tom321123@gmail.com&quot;, &quot;nickname&quot;=&gt;&quot;tom321123&quot;}
</pre></p>
<h3>Mais 5 minutos&#8230;</h3>
<p>E lá vem você com mais uma pergunta: &#8220;E aí, como incluir <strong>MongoDB</strong> em meus projetos Ruby e/ou Rails?&#8221;<br />
E eu novamente lhe trago uma resposta&#8230; Existem alguns <a href="http://www.mongodb.org/display/DOCS/Object+Mappers+for+Ruby+and+MongoDB" target="_blank">projetos interessantes</a> de Object Mapper para <strong>MongoDB</strong>, destes o qual eu mais me interessei foi este <a href="http://github.com/jnunemaker/mongomapper" target="_blank">MongoMapper</a>, por parecer mais maduro e estar pronto para coloca-lo em produção sem grandes receios.</p>
<p>Mapeando Documentos</p>
<p><pre class="brush: ruby;">
require 'mongo_mapper'

MongoMapper.database = &quot;meu_bd&quot;

class Usuario
include MongoMapper::Document

key :nome, String
key :email, String
key :nickname, String
end
</pre></p>
<p>Criando documentos e salvando:</p>
<p><pre class="brush: ruby;">
marcia = Usuario.new
marcia.nome = &quot;Marcia&quot;
marcia.email = &quot;email_marcia@gmail.com&quot;
marcia.nickname = &quot;nick_marcia&quot;

marcia.save
</pre></p>
<p>Complicando um pouco mais, vamos adicionar relacionamentos</p>
<p><pre class="brush: ruby;">
class Usuario
include MongoMapper::Document

many :pagamentos
end

class Pagamento
include MongoMapper::Document

key :valor, Float

belongs_to :usuario
end

marcia.pagamentos &lt;&lt; Pagamento.new(:valor =&gt; 1.15)
marcia.save
</pre></p>
<p>Semelhante a um framework que conhecemos, o MongoMapper gera automaticamente alguns métodos, então é possível fazer isso:</p>
<p><pre class="brush: ruby;">
alan = Usuario.find_by_nome(&quot;Alan&quot;)
p alan
</pre></p>
<p><pre class="brush: ruby;">
#&lt;Usuario nickname: &quot;alanrrb&quot;, nome: &quot;Alan&quot;, _id: 4b7e23b01919ba0353000001, email: &quot;alanrrb@gmail.com&quot;&gt;
</pre></p>
<p>Criando um documento e persistindo.</p>
<p><pre class="brush: ruby;">
david = Usuario.create(:nome =&gt; &quot;David&quot;, :email =&gt; &quot;david321123@gmail.com&quot;, :nickname =&gt; &quot;david&quot;)
p david
</pre></p>
<p><pre class="brush: ruby;">
#&lt;Usuario nickname: &quot;david&quot;, nome: &quot;David&quot;, _id: 4b7e23b11919ba0353000006, email: &quot;david321123@gmail.com&quot;&gt;
</pre></p>
<p>Se você conhece o <a href="http://ar.rubyonrails.org/" target="_blank">ActiveRecord</a>, com certeza viu algumas semelhanças e já esta com algumas ideias para incluir <strong><a href="http://www.mongodb.org/display/DOCS/Home" target="_blank">MongoDB</a></strong> nos seus próximos projetos, mas isso será assunto para a próximo post.</p>
<p>Os códigos usados neste post estão publicados <a href="http://gist.github.com/308473" target="_blank">aqui</a>.</p>
<p>Por enquanto é só, não esqueçam de deixar seus comentários!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/142/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/142/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/142/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/142/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/142/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/142/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/142/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/142/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/142/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/142/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/142/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/142/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/142/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/142/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=142&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/02/19/10-minutos-de-ruby-e-mongodb/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>
	</item>
		<item>
		<title>Mais um pouco de CouchDB e CouchRest</title>
		<link>http://papodecorredor.wordpress.com/2010/01/29/mais-um-pouco-de-couchdb-e-couchrest/</link>
		<comments>http://papodecorredor.wordpress.com/2010/01/29/mais-um-pouco-de-couchdb-e-couchrest/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 03:48:40 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[couchdb]]></category>
		<category><![CDATA[couchrest]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=129</guid>
		<description><![CDATA[Se você já leu meu post anterior CouchDB &#8211; Resolvendo Problemas Reais saiba que esse é um post complementar, ou seja, se não leu pode le-lo agora! No post anterior mostrei duas formas de modelar algo comum nos cenarios de softwares corporativo atuais. Tá mais e ai, como utilizar as propostas? E possivel implementa-las? Eu [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=129&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Se você já leu meu post anterior <a href="http://papodecorredor.wordpress.com/2010/01/27/couchdb-resolvendo-problemas-reais/" target="_blank">CouchDB &#8211; Resolvendo Problemas Reais</a> saiba que esse é um post complementar, ou seja, se não leu pode le-lo agora!<br />
No post anterior mostrei duas formas de modelar algo comum nos cenarios de softwares corporativo atuais.<br />
Tá mais e ai, como utilizar as propostas? E possivel implementa-las?<br />
Eu respondo, sim, é possivel! E para mostrar como eu vou usar o CouchRest uma gem do Ruby extremamente instalar e usar.<br />
Não serei repetitivo, se quiser saber como usa-la utilize <a href="http://leandrosilva.com.br/2009/08/02/5-minutos-de-couchdb-e-couchrest/" target="_blank">5 minutos para isso</a> ou um <a href="http://blog.improveit.com.br/articles/2009/09/14/ruby-on-rails-com-couchdb-usando-couchrest" target="_blank">pouco mais que isso se preferir</a>.<br />
Chega de papo e vamos para o código!<br />
Para ter nosso documento Cliente contendo seus Pedidos o modelo ficaria assim:</p>
<p><pre class="brush: ruby;">
require 'rubygems'
require 'couchrest'

SERVER = CouchRest.new
SERVER.default_database = 'comercio2'
DB = SERVER.default_database

class Cliente &lt; CouchRest::ExtendedDocument
  use_database DB

  property :nome
  property :email
  property :telefone
  property :pedidos, :cast_as =&gt; ['Pedido'], :default =&gt; []

  timestamps!
end

class Pedido &lt; CouchRest::ExtendedDocument
  use_database DB

  property :numero
  property :valor
  property :data
end
</pre></p>
<p>Agora utilizando o modelo:</p>
<p><pre class="brush: ruby;">
cliente = Cliente.new :nome =&gt; &quot;Alan Rafael&quot;, :email =&gt; &quot;alanbatista@gmail.com&quot;, :telefone =&gt; &quot;9999-9999&quot;
cliente.pedidos &lt;&lt; Pedido.new(:numero =&gt; 1, :valor =&gt; 10, :data =&gt; Time.new)
cliente.pedidos &lt;&lt; Pedido.new(:numero =&gt; 2, :valor =&gt; 105, :data =&gt; Time.new)
cliente.pedidos &lt;&lt; Pedido.new(:numero =&gt; 3, :valor =&gt; 140, :data =&gt; Time.new)
cliente.save

puts cliente.id

#obtendo o cliente
clienteReloaded = Cliente.get cliente.id

puts &quot;Pedidos do cliente #{clienteReloaded.nome}, são: &quot;
clienteReloaded.pedidos.each do |pedido|
  p pedido
end
</pre></p>
<p>Saida do console:</p>
<p><pre class="brush: jscript;">
Identificador do Cliente: 43d78f21600a60bd3371e02455aff980
Pedidos do cliente Alan Rafael, são:
{&quot;data&quot;=&gt;&quot;2010/01/29 01:42:24 +0000&quot;, &quot;valor&quot;=&gt;10, &quot;couchrest-type&quot;=&gt;&quot;Pedido&quot;, &quot;numero&quot;=&gt;1}
{&quot;data&quot;=&gt;&quot;2010/01/29 01:42:24 +0000&quot;, &quot;valor&quot;=&gt;105, &quot;couchrest-type&quot;=&gt;&quot;Pedido&quot;, &quot;numero&quot;=&gt;2}
{&quot;data&quot;=&gt;&quot;2010/01/29 01:42:24 +0000&quot;, &quot;valor&quot;=&gt;140, &quot;couchrest-type&quot;=&gt;&quot;Pedido&quot;, &quot;numero&quot;=&gt;3}
</pre></p>
<p>Vejam que o Cliente possui uma coleção de Pedidos, então agora vamos ver como o CouchDB armazena isso:<br />
<pre class="brush: jscript;">
{
   &quot;_id&quot;: &quot;43d78f21600a60bd3371e02455aff980&quot;,
   &quot;_rev&quot;: &quot;1-97794fcd383ba246fc68ee0908621cc2&quot;,
   &quot;created_at&quot;: &quot;2010/01/29 01:42:24 +0000&quot;,
   &quot;telefone&quot;: &quot;9999-9999&quot;,
   &quot;updated_at&quot;: &quot;2010/01/29 01:42:24 +0000&quot;,
   &quot;nome&quot;: &quot;Alan Rafael&quot;,
   &quot;pedidos&quot;: [
       {
           &quot;data&quot;: &quot;2010/01/29 01:42:24 +0000&quot;,
           &quot;valor&quot;: 10,
           &quot;couchrest-type&quot;: &quot;Pedido&quot;,
           &quot;numero&quot;: 1
       },
       {
           &quot;data&quot;: &quot;2010/01/29 01:42:24 +0000&quot;,
           &quot;valor&quot;: 105,
           &quot;couchrest-type&quot;: &quot;Pedido&quot;,
           &quot;numero&quot;: 2
       },
       {
           &quot;data&quot;: &quot;2010/01/29 01:42:24 +0000&quot;,
           &quot;valor&quot;: 140,
           &quot;couchrest-type&quot;: &quot;Pedido&quot;,
           &quot;numero&quot;: 3
       }
   ],
   &quot;couchrest-type&quot;: &quot;Cliente&quot;,
   &quot;email&quot;: &quot;alanbatista@gmail.com&quot;
}
</pre></p>
<p>Simples né, um documento cliente contém os seus pedidos!</p>
<p>Bem agora vamos para o outro exemplo, um documento de Cliente com um ou mais documentos de Pedido.<br />
<pre class="brush: ruby;">
require 'rubygems'
require 'couchrest'

SERVER = CouchRest.new
DB = SERVER.database('comercio')

class Cliente &lt; CouchRest::ExtendedDocument
  use_database DB

  property :nome
  property :email
  property :telefone

  timestamps!

  def pedidos
    Pedido.by_cliente_id :key =&gt; id
  end
end

class Pedido &lt; CouchRest::ExtendedDocument
  use_database DB

  property :numero
  property :valor
  property :data

  view_by :cliente_id

  def cliente= cliente
    self['cliente_id'] = cliente.id
  end
  def cliente
    Cliente.get(self['cliente_id']) if self['cliente_id']
  end
end
</pre></p>
<p>Vamos as novidades, não sei se contei, mas todo o CouchRest::ExtendedDocument é um Hash, então nessa parte:<br />
<pre class="brush: ruby;">
  def cliente= cliente
    self['cliente_id'] = cliente.id
  end
  def cliente
    Cliente.get(self['cliente_id']) if self['cliente_id']
  end
end
</pre><br />
Eu estou adicionando o atributo cliente_id ao documento pedido, assim podemos relacionar o documento Cliente ao documento Pedido.</p>
<p>Vamos usar esse modelo:<br />
<pre class="brush: ruby;">
cliente = Cliente.new(:nome =&gt; &quot;Alan Rafael&quot;, :email =&gt; &quot;alanrrb@gmail.com&quot;, :telefone =&gt; &quot;9999-9999&quot;)
cliente.save

pedido = Pedido.new
pedido.numero= 1
pedido.valor= 20000
pedido.data = Time.new
pedido.cliente= cliente
pedido.save

pedido = Pedido.new
pedido.numero= 2
pedido.valor= 1000
pedido.data = Time.new
pedido.cliente= cliente
pedido.save

puts &quot;Identificador do Cliente #{cliente.nome}, id: #{cliente.id}&quot;

puts &quot;Pedidos do cliente #{cliente.nome}&quot;
cliente.pedidos.each do |pedido|
  pedido.each do |chave, valor|
    puts &quot;#{chave}: #{valor}&quot;
  end
  puts
end
</pre></p>
<p>Saída do console:<br />
<pre class="brush: plain;">
Identificador do Cliente Alan Rafael, id: 019d581b142bfc059b7810694fcda012
Pedidos do cliente Alan Rafael
data: 2010/01/29 02:47:11 +0000
_rev: 1-af7e81f30c7fb4a379a053b929bd9cc8
_id: 0ea8803ebfb714d3ec47f93e0d33bac7
cliente_id: 019d581b142bfc059b7810694fcda012
valor: 1000
couchrest-type: Pedido
numero: 2

data: 2010/01/29 02:47:11 +0000
_rev: 1-bc1cbce13bbf65bfaeaaf193ef33cf28
_id: fa8ad3dd1f962a567ccf7e7c50f135c3
cliente_id: 019d581b142bfc059b7810694fcda012
valor: 20000
couchrest-type: Pedido
numero: 1
</pre></p>
<p>Voltando ao CouchDB vamos ver como ele salvou essa brincadeira:<br />
<pre class="brush: jscript;">
Cliente:
{
   &quot;_id&quot;: &quot;019d581b142bfc059b7810694fcda012&quot;,
   &quot;_rev&quot;: &quot;1-5bb47e58256553b6fa2accca4f8475ba&quot;,
   &quot;created_at&quot;: &quot;2010/01/29 02:47:10 +0000&quot;,
   &quot;telefone&quot;: &quot;9999-9999&quot;,
   &quot;updated_at&quot;: &quot;2010/01/29 02:47:10 +0000&quot;,
   &quot;nome&quot;: &quot;Alan Rafael&quot;,
   &quot;couchrest-type&quot;: &quot;Cliente&quot;,
   &quot;email&quot;: &quot;alanrrb@gmail.com&quot;
}
Pedidos:
{
   &quot;_id&quot;: &quot;0ea8803ebfb714d3ec47f93e0d33bac7&quot;,
   &quot;_rev&quot;: &quot;1-af7e81f30c7fb4a379a053b929bd9cc8&quot;,
   &quot;data&quot;: &quot;2010/01/29 02:47:11 +0000&quot;,
   &quot;cliente_id&quot;: &quot;019d581b142bfc059b7810694fcda012&quot;,
   &quot;valor&quot;: 1000,
   &quot;couchrest-type&quot;: &quot;Pedido&quot;,
   &quot;numero&quot;: 2
}

{
   &quot;_id&quot;: &quot;fa8ad3dd1f962a567ccf7e7c50f135c3&quot;,
   &quot;_rev&quot;: &quot;1-bc1cbce13bbf65bfaeaaf193ef33cf28&quot;,
   &quot;data&quot;: &quot;2010/01/29 02:47:11 +0000&quot;,
   &quot;cliente_id&quot;: &quot;019d581b142bfc059b7810694fcda012&quot;,
   &quot;valor&quot;: 20000,
   &quot;couchrest-type&quot;: &quot;Pedido&quot;,
   &quot;numero&quot;: 1
}
</pre></p>
<p>Como eu mostrei no post anterior, nesse forma de modelo, temos que ter um tipo em cada documento e o CouchRest &#8220;tipou&#8221; cada documento com o atributo &#8220;couchrest-type&#8221;, ficando assim muito simples obter cada registro e seu relacionamento.</p>
<p>Para finalizar, valor total de pedidos por cliente:<br />
<pre class="brush: ruby;">
class Pedido
view_by :valor_total_pedidos,
              :map =&gt;
                &quot;function(doc) {
                    if(doc['couchrest-type'] == \&quot;Pedido\&quot;)
                       emit(doc['cliente_id'], doc['valor']);
                 }&quot;,
              :reduce =&gt;
                &quot;function(keys, values, rereduce) {
                    return sum(values);
                 }&quot;
end

total =  Pedido.by_valor_total_pedidos :key =&gt; cliente.id, :reduce =&gt; true
p &quot;Valor total de pedidos para cliente: #{cliente.nome}, Total: #{total['rows'][0]['value']}&quot;
</pre></p>
<p>Saída do console:<br />
<pre class="brush: plain;">
&quot;Valor total de pedidos para cliente: Alan Rafael, Total: 21000&quot;
</pre></p>
<p>O CouchRest nos dá muita flexibilidade e simplicidade para trabalhar com Ruby e CouchDB, espero te-los motivado para experimentar os dois.</p>
<p>Não se esqueçam de deixar seus comentários!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/129/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=129&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/01/29/mais-um-pouco-de-couchdb-e-couchrest/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>
	</item>
		<item>
		<title>CouchDB &#8211; Resolvendo problemas reais</title>
		<link>http://papodecorredor.wordpress.com/2010/01/27/couchdb-resolvendo-problemas-reais/</link>
		<comments>http://papodecorredor.wordpress.com/2010/01/27/couchdb-resolvendo-problemas-reais/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 23:40:17 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[couchdb]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=105</guid>
		<description><![CDATA[Há alguns meses me interessei pelo CouchDB, mas estava sem tempo para dedicar alguns minutos para conhece-lo mais. Pois bem, nos 3 últimos dias abri mão de algum tempo e me dediquei a conhecer esse tal! Mas como eu pensei, uma coisa leva a outra e então acabei encontrando aqui o CouchRest e acabei caindo [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=105&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Há alguns meses me interessei pelo <a href="http://couchdb.apache.org/" target="_blank">CouchDB</a>, mas estava sem tempo para dedicar alguns minutos para conhece-lo mais.<br />
Pois bem, nos 3 últimos dias abri mão de algum tempo e me dediquei a conhecer esse tal!<br />
Mas como eu pensei, uma coisa leva a outra e então acabei encontrando aqui o <a href="http://github.com/jchris/couchrest" target="_blank">CouchRest</a> e acabei caindo mais <a href="http://www.rubyinside.com.br/couchrest-couchdb-sem-frescuras-2099" target="_blank">aqui</a> e <a href="http://blog.improveit.com.br/articles/2009/09/14/ruby-on-rails-com-couchdb-usando-couchrest" target="_blank">aqui</a>.</p>
<p>Amigos, o assunto é tão interessante que eu não consegui ficar com apenas os 5 minutos que o <a href="http://leandrosilva.com.br/2009/08/02/5-minutos-de-couchdb-e-couchrest/" target="_blank">Leandro Silva</a> sugeriu, acabei indo além e li quase inteiro o livro <a href="http://www.amazon.com/Beginning-CouchDB-Joe-Lennon/dp/1430272376" target="_blank">Beginning CouchDB</a> em apenas 3 dias! (<span style="text-decoration:line-through;">pra quem estava sem tempo, foi um recorde</span>).</p>
<p>Fonte para conhecimento eu  já indiquei nos links de posts acima, então vamos partir para um problema real.</p>
<p>Por ser baseado em documentos, supondo que você escolhesse o CouchDB para seu próximo projeto e neste tivesse o seguinte cenário:</p>
<p>Um sistema de vendas on-line no qual o cliente poderá executar vários pedidos. Bem simples e comum.</p>
<p>Em um banco de dados relacional você teria duas tabelas ligadas por uma &#8220;foreign key&#8221; e as consultaria através de um &#8220;join&#8221;, mas e no caso de um banco de dados &#8220;schema-free&#8221; e baseado em documentos? Provavelmente faríamos assim:</p>
<p><pre class="brush: jscript;">{
{&quot;nome&quot;: &quot;Alan Rafael Rodrigo Batista&quot;,
&quot;e-mail&quot;: &quot;alanrrb@gmail.com&quot;,
&quot;telefone&quot;: &quot;9999-9999&quot;,
&quot;pedidos&quot;: [
{
&quot;codigo&quot;:1,
&quot;data&quot;:&quot;2010/01/27 16:56:52 +0000&quot;,
&quot;valor&quot;:2000
},
{
&quot;codigo&quot;:1,
&quot;data&quot;:&quot;2010/01/27 16:56:52 +0000&quot;,
&quot;valor&quot;:2000
},
{
&quot;codigo&quot;:1,
&quot;data&quot;:&quot;2010/01/27 16:56:52 +0000&quot;,
&quot;valor&quot;:2000
}
]
}
</pre></p>
<p>No próprio documento do cliente estaria a coleção de pedidos.</p>
<p>No CouchDB os documentos são salvos na formato JSON, então e muito fácil ter um relacionamento muitos para um.<br />
Essa forma funcionaria sem problemas, até que num dado momento um processo tentar incluir um pedido, enquanto outro tenta alterar o cliente. O que acontecerá, um deles receberá erro &#8220;<strong>409 conflict</strong>&#8220;, além de sempre que quiser incluir um novo pedido, terá que obter todo o documento do cliente. (não que isso seja um problema)</p>
<p><strong>E aí, qual outra opção?</strong></p>
<p>Podemos também modelar um documento de cliente para um ou mais documentos de pedido. Para isso temos que criar um campo tipo em cada documento para que possamos identifica-los depois.<br />
Ficaria assim:</p>
<p><pre class="brush: jscript;">
{
&quot;cliente_id&quot;: 1
&quot;nome&quot;: &quot;Alan Rafael Rodrigo Batista&quot;,
&quot;e-mail&quot;: &quot;alanrrb@gmail.com&quot;,
&quot;telefone&quot;: &quot;9999-9999&quot;
&quot;tipo&quot;: &quot;Cliente&quot;
}

{
&quot;codigo&quot;:1,
&quot;data&quot;:&quot;2010/01/27 16:56:52 +0000&quot;,
&quot;valor&quot;:2000,
&quot;tipo&quot; : &quot;Pedido&quot;
&quot;cliente_id&quot;: 1
}

{
&quot;codigo&quot;:2,
&quot;data&quot;:&quot;2010/01/27 16:56:52 +0000&quot;,
&quot;valor&quot;:6300,
&quot;tipo&quot; : &quot;Pedido&quot;
&quot;cliente_id&quot;: 1
}

{
&quot;codigo&quot;:3,
&quot;data&quot;:&quot;2010/01/27 16:56:52 +0000&quot;,
&quot;valor&quot;:200,
&quot;tipo&quot; : &quot;Pedido&quot;
&quot;cliente_id&quot;: 1
}
</pre></p>
<p>Essa forma também funcionará sem problemas, mas sob o custo de ter mais requisições HTTP para manter os dados, já que o cliente e seus pedidos estão em documentos separados.</p>
<p>E como consultamos essas informações?</p>
<p>Valor total de pedidos por Cliente:</p>
<p><pre class="brush: jscript;">
map: function(doc) {
   if(doc['tipo'] == &quot;Pedido&quot;)
      emit(doc['cliente_id'], doc['valor']);
   }
reduce: function(keys, values, rereduce) {
   return sum(values);
}

Resultado:
{&quot;rows&quot;:
[{
&quot;key&quot;:&quot;1&quot;,
&quot;value&quot;:8500
}
]}
</pre></p>
<p>Podemos também obter um resultado da união dos dois documentos com um recurso de linguagem.</p>
<p><pre class="brush: jscript;">
map: function(doc) {
   if(doc['tipo'] == &quot;Pedido&quot;)
      emit([doc['cliente_id'],1], doc);
   } elseif(doc['tipo'] == &quot;Cliente&quot;) {
      emit([doc['cliente_id'],0], doc);
   }
}
</pre></p>
<p>Assim você teria um documento que contém linhas com o codigo do cliente o próprio documento de cliente e outras com o código do cliente e o documento de pedido relacionado, simples né!</p>
<p>E qual das soluções é melhor? Não temos uma melhor ou pior e sim uma mais adequada ao seu projeto e isso que é belo no CouchDB, a liberdade que ele nós dá!</p>
<p>Bem acho que já é assunto suficiente para esse post, no próximo post vou demonstrar como escrever os dois exemplos em Ruby com o CouchRest.</p>
<p>Gostou do assunto? Comente! Não gostou? Comente também!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/105/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=105&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2010/01/27/couchdb-resolvendo-problemas-reais/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>
	</item>
		<item>
		<title>As aventuras de programador em busca do Ruby &#8211; Parte 1</title>
		<link>http://papodecorredor.wordpress.com/2009/02/13/as-aventuras-de-programador-em-busca-do-ruby-parte-1/</link>
		<comments>http://papodecorredor.wordpress.com/2009/02/13/as-aventuras-de-programador-em-busca-do-ruby-parte-1/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 01:58:34 +0000</pubDate>
		<dc:creator>Alan Rafael R. Batista</dc:creator>
				<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[livro]]></category>
		<category><![CDATA[matz]]></category>

		<guid isPermaLink="false">http://papodecorredor.wordpress.com/?p=38</guid>
		<description><![CDATA[Já faz um tempo que não posto nada, aproveitei o tempo vago nos últimos dias para aprender um nova linguagem de programação &#8211;algo que me dá uma grande satisfação&#8211;. Baixei vários livros de diversas linguagens, mas os papos de corredor me levaram a escolher Ruby. Apesar de programar em PHP por alguns anos, já estava [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=38&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Já faz um tempo que não posto nada, aproveitei o tempo vago nos últimos dias para aprender um nova linguagem de programação &#8211;algo que me dá uma grande satisfação&#8211;.</p>
<p>Baixei vários livros de diversas linguagens, mas os papos de corredor me levaram a escolher Ruby.</p>
<p>Apesar de programar em <a href="http://www.php.net/">PHP</a> por alguns anos, já estava desacostumado com linguagens <a href="http://en.wikipedia.org/wiki/Type_system#Dynamic_typing">Dinamicamente Tipadas</a>, gosto muito de Java, estou até devendo escrever algo aqui no blog, mas com certeza ele me acostumou <del datetime="00">muito</del> mal!!!</p>
<p>Pois bem, vamos parar de história e começar a diversão!</p>
<h1>A escolha do livro <a href="http://papodecorredor.files.wordpress.com/2009/02/cap2.png"><img class="alignleft" style="border:0 none;margin:0;" title="cap2" src="http://papodecorredor.files.wordpress.com/2009/02/cap2.png?w=223&#038;h=295" alt="O Ruby" width="223" height="295" /></a></h1>
<p>Essa parte foi bem difícil, porém, não menos interessante&#8230; Iniciei a leitura com o livro indicado por um <a href="http://leandrosilva.com.br/">amigo de trabalho</a> o bem recomendado <a href="http://www.amazon.com/Ruby-Way-Second-Addison-Wesley-Professional/dp/0672328844/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1233791523&amp;sr=8-1">The Ruby Way</a>, porém achei a leitura um tanto <del>densa</del> e longa (888 páginas assustam), então parti para um livro mais barato e menor, porém, não menos completo e interessante <a href="http://www.amazon.com/gp/product/0596516177/">The Ruby Programming Language</a>. O livro é ótimo e um dos seus autores é nada mais nada menos que o criador do Ruby <a href="http://en.wikipedia.org/wiki/Yukihiro_Matsumoto">Yukihiro Matsumoto &#8211; Matz</a> &#8211;acho que o cara manja um pouquinho!&#8211;.<br />
A leitura deste livro é bem tranqüila e eu estou gostando muito, recomendo, e enquanto for lendo vou compartilhar os ensinamentos adquiridos aqui no site, assim eu fixo o aprendizado e compartilho com a comunidade!<br />
Vou deixar bem claro que não se trata de uma tradução, poderia talvez chamar isto de um &#8220;resumo público&#8221;, mas ainda assim, recomendo que comprem e leiam o livro.<br />
Vou dividir a estrutura igual ao livro, porém vou iniciar a série de posts a partir do capitulo 2. Motivo? Quero que você tenha a mesma surpresa que eu tive quando ler o capitulo 1!</p>
<h1>Estrutura e Execução de Programa Ruby</h1>
<h3>Estrutura Léxica</h3>
<h4>Comentários</h4>
<p><pre class="brush: ruby;"># isto é um comentário de uma linha inteira
puts &quot;Alan&quot; # isto é um comentário
regex = /#[A-Za-z0-9] isto eh um expressão regular/ # isto é outro comentário</pre></p>
<p>Comentários de múltiplas linhas deve ser feito assim:</p>
<p><pre class="brush: ruby;">
#
# Desta forma é possível fazer um comentário de várias linhas
# No Ruby não há uma forma de comentar semelhante a essa no Java /* */
#</pre></p>
<h4>Documentos Embutidos</h4>
<p>No Ruby há outra forma de inserir comentários multi linhas. Basta iniciar o bloco comentado por <code>=begin</code> e termina-lo com <code>=end</code>. Tudo que estiver entre <code>=begin</code> e <code>=end</code> será ignorado pelo interpretador, mas lembre-se, deve ter no minimo um espaço em branco após o =begin.</p>
<p><pre class="brush: ruby;">=begin isto é um comentário multi linha
tudo que esta aqui será ignorado pelo o interpretador.
=end</pre></p>
<h4>Literais</h4>
<p>No Ruby há valores literais, aqueles que são inseridos diretamente no código, podem ser uma String, um número inteiro, ponto flutuante, expressão regular, etc., como o exemplo a seguir:</p>
<p><pre class="brush: ruby;">
1         # inteiro
1.0       # ponto flutuante
&quot;texto&quot;   # string
/regex/   # expressão pessoal
</pre></p>
<h4>Operadores</h4>
<p>Há vários operadores no Ruby, porém vou falar mais sobre eles mais na frente (estão no capitulo 4 do <a href="http://www.amazon.com/gp/product/0596516177/">livro</a> rsrs), tem várias informações interessantes para falar sobre eles depois.</p>
<h4>Identificadores</h4>
<p>Identificadores são simplesmente um nome no Ruby e são usados para representar nomes de variáveis, métodos, Módulos, Classes e outros. Podem ser escritos por letras, números e <em>underscore</em>, porém eles não podem iniciar com um número.</p>
<p>Identificadores não podem iniciar por operadores exceto +, &#8211; ,|| e outros que serão descritos.</p>
<p>Os identificadores que iniciarem com uma letra maiúscula serão considerados constantes (passível que gerar um alerta, caso houver tentativa de alteração de seu valor). Classes e Módulos devem iniciar por uma letra maiúscula.</p>
<p>Ex:</p>
<p><pre class="brush: ruby;">
a
a2
a_2
a2b
_var
PI                   # constante
class Pessoa # define a classe pessoa
end
</pre></p>
<p>O ruby é uma linguagem case sensitive, o identificador NOME é diferente de nome ou NoMe, lembre-se disso.</p>
<h4>Outros usos de identificadores</h4>
<p>No Ruby alguns identificadores tem um valor especial e são usados no inicio e no fim dos identificadores, vou mostrar essa parte com exemplos:</p>
<p><pre class="brush: ruby;">
$var_global         # como no Perl, o Ruby define variáveis globais com $
@var_instance       # atributos de objeto são definidos com @ na frente do identificador
@@var_class         # atributos de escopo de classe recebem @@ na frente
obj.respond_to?     # métodos que retorno um boolean por convenção recebem um ? no final do identificador
&quot;nome&quot;.upcase!      # métodos que devem ser usados com cuidado recebem um ! nome final
pessoa.nome=&quot;josé&quot;  # métodos de atribuição deveria receber = no final... vamos falar mais disso depois
</pre></p>
<h4>Palavras Chave</h4>
<p>As seguintes palavras são chaves e tem um significado especial para Ruby.</p>
<p><pre class="brush: ruby;">
__LINE__      case         ensure       not          then
__ENCODING__  class        false        or           true
__FILE__      def          for          redo         undef
BEGIN         defined?     if           rescue       unless
END           do           in           retry        until
alias         else         module       return       when
and           elsif        next         self         while
begin         end          nil          super        yield
break
</pre></p>
<p>E mais essas 3 que quando aparecem no inicio da linha tem um significado especial para o parser.</p>
<p><pre class="brush: ruby;">
=begin   =end   __END__
</pre></p>
<p>Apesar de serem palavras chave, se estas palavras forem precedidas de <strong>@</strong>, <strong>@@</strong>, <strong>$</strong> ou se usadas em nomes de métodos o código será interpretado sem erro (isto se deve a flexibilidade do interpretador do Ruby) porém o uso dessas palavras irá gerar um código de difícil interpretação, não acha?</p>
<p>Alguns comportamentos e características do Ruby estão ligados aos métodos de Kernel, Object, Module e Class. Como boa prática seria interessante tratar seus métodos como palavras reservadas.</p>
<p><pre class="brush: ruby;">
# Estes métodos parecem palavras chaves ou reservadas
at_exit        catch          private        require
attr           include        proc           throw
attr_accessor  lambda         protected
attr_reader    load           public
attr_writer    loop           raise

# Estes são normalmente usados como funções globais
Array          chomp!         gsub!          select
Float          chop           iterator?      sleep
Integer        chop!          load           split
String         eval           open           sprintf
URI            exec           p              srand
abort          exit           print          sub
autoload       exit!          printf         sub!
autoload?      fail           putc           syscall
binding        fork           puts           system
block_given?   format         rand           test
callcc         getc           readline       trap
caller         gets           readlines      warn
chomp          gsub           scan

# E estes são usado  como métodos de Object
allocate       freeze         kind_of?       superclass
clone          frozen?        method         taint
display        hash           methods        tainted?
dup            id             new            to_a
enum_for       inherited      nil?           to_enum
eql?           inspect        object_id      to_s
equal?         instance_of?   respond_to?    untaint
extend         is_a?          send
</pre></p>
<h4>Espaços em branco</h4>
<p>A sintaxe do código Ruby é bem flexível, porém devemos ter alguns cuidados com isso. O uso de espaços em branco pode mudar a interpretação do código e causar resultados inesperados.<br />
Ex:</p>
<p><pre class="brush: ruby;">
avalia(3+1)+1 # executa o método avalia e adiciona 1
 </pre></p>
<p>Outro exemplo:</p>
<p><pre class="brush: ruby;">
# O Interpretador assume que o &quot;(&quot; (parenteses) foi omitido e intepreta (3+1)+1 e
# passa o resultado como argumento para o método avalia.
avalia (3+1)+1
 </pre></p>
<p>Existem outras situação que serão mostradas nos post seguintes.</p>
<h3>Estrutura Sintática</h3>
<p>Neste capitulo do livro é introduzido temas relacionados a simples expressões a até complexos módulos.<br />
No Ruby a unidade básica  é a expressão, desde um valor literal que é uma expressão primária ou expressões mais complexas que usam palavras chaves como <code>nil, self, true, false</code>.</p>
<p><pre class="brush: ruby;">
[:a,:b,:c]                                   # array de símbolos
[&quot;nome&quot; =&gt; &quot;José&quot;, &quot;endereco&quot; =&gt; &quot;Rua Amazonas&quot;]  # declaração literal de um hash
5                  # expressão primária
x = x+1    # atribuição
</pre></p>
<p>Assim como em outras linguagens de programação, no Ruby composições de declarações formam declarações (statement) conforme a seguir:</p>
<p><pre class="brush: ruby;">
if x &gt; 1
   puts &quot;#{x} é maior que 1&quot;
else
   puts &quot;#{x} é menor ou igual a 1&quot;
end
</pre></p>
<h4>Blocos</h4>
<p>Há duas maneiras de criar blocos no Ruby, e esta forma de construção é extremamente prático.</p>
<p><pre class="brush: ruby;">
10.times { puts &quot;Olá mundo 10 vezes, só para confirmar!&quot; }
</pre></p>
<p><pre class="brush: ruby;">
1.upto 10 do |n| puts &quot;o número atual é #{n}&quot; end
</pre></p>
<p>Mais informações sobre os blocos serão mostradas nos próximos posts.</p>
<p>Bem então é isso, a aventura não acabou, muito pelo contrário, ela está apenas iniciando.</p>
<h4>Primeiras impressões</h4>
<p>As primeiras impressões com o Ruby foram as melhores possíveis, acho que de todas as linguagens que aprendi essa foi a me mais me identifiquei até hoje, superou até o <a href="http://www.python.org">Python</a> o qual eu não brinco já há algum tempo (tenho um colega que discordará dessa frase).<br />
Pois bem, só posso concluir esse post dizendo, você deveria experimentar o ruby agora!!!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/papodecorredor.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/papodecorredor.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/papodecorredor.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/papodecorredor.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/papodecorredor.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/papodecorredor.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/papodecorredor.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/papodecorredor.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/papodecorredor.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/papodecorredor.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/papodecorredor.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/papodecorredor.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/papodecorredor.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/papodecorredor.wordpress.com/38/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=papodecorredor.wordpress.com&amp;blog=5143998&amp;post=38&amp;subd=papodecorredor&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://papodecorredor.wordpress.com/2009/02/13/as-aventuras-de-programador-em-busca-do-ruby-parte-1/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e913c5a08e2ba99fdc2ccfb592751fa?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alan</media:title>
		</media:content>

		<media:content url="http://papodecorredor.files.wordpress.com/2009/02/cap2.png" medium="image">
			<media:title type="html">cap2</media:title>
		</media:content>
	</item>
	</channel>
</rss>
