<?xml version="1.0" encoding="utf-8"?>
    <feed xmlns="http://www.w3.org/2005/Atom">
      <link href="https://www.lucascaton.com/pt-BR/feed.xml" rel="self" type="application/atom+xml" />
      <link href="https://www.lucascaton.com" rel="alternate" type="text/html" />
      <updated>2026-04-03T05:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/feed.xml</id>
      <title type="html">Lucas Caton</title>
      <subtitle>Engenheiro de software full-stack com experiência em Ruby, Rails, React e CSS. Entusiasta de open-source, eterno aprendiz e movido por desafios.</subtitle>
      <author><name>Lucas Caton</name></author>

      
    <entry>
      <title><![CDATA[I stopped writing code, and I'm not sure that's a good thing]]></title>
      <summary><![CDATA[The work I used to love is now being done by AI]]></summary>
      <link href="https://www.lucascaton.com/2026/02/15/i-stopped-writing-code-and-im-not-sure-thats-a-good-thing?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2026-02-15T03:30:00.000Z</published>
      <updated>2026-02-15T03:30:00.000Z</updated>
      <id>https://www.lucascaton.com/2026/02/15/i-stopped-writing-code-and-im-not-sure-thats-a-good-thing</id>
      <content type="html" xml:base="https://www.lucascaton.com/2026/02/15/i-stopped-writing-code-and-im-not-sure-thats-a-good-thing">
        <![CDATA[<div xml:lang="en"><p><aside>This post is also available in <a href="https://www.lucascaton.com/pt-BR/2026/02/15/eu-parei-de-escrever-codigo-e-nao-sei-se-isso-e-bom">Portuguese</a>.</aside></p>
<p><img src="/images/posts/2026/02/i-stopped-writing-code-and-im-not-sure-if-thats-a-good-thing.png" alt="I stopped writing code - and I&#x27;m not sure if that&#x27;s a good thing"></p>
<p>I learnt to code around 2004 and started programming professionally in 2007. I never stopped.
Even between 2022 and 2024, when I worked as an Engineering Manager, I kept coding in my spare time, listening to podcasts, watching YouTube videos, and keeping up with an ecosystem I've always been passionate about.</p>
<p>I love programming. Explaining to the computer what to do and how to do it is a joy that only
those who do it can truly understand.
It has its challenges, but it's rewarding, both professionally and financially.</p>
<p>Then AI arrived, and programming became one of the fields most affected by it.</p>
<p><aside>When I say AI in this post, I'm mainly referring to LLMs (Large Language Models) - such as Claude, GPT, Gemini and the like.</aside></p>
<h2>Programming became reviewing diffs</h2>
<p>At first, I used AI sporadically. As the tools evolved, I started using them more and more.</p>
<p>I've used editors like Vim, VS Code, and Cursor.
Today, interestingly, my main tools are no longer terminal + editor/IDE, but terminal + a Git GUI
app, which I used to open only occasionally and now use more than the editor itself.</p>
<p>In the terminal, tools like Claude Code, Gemini CLI, and similar ones are the stars of the moment.
I've reached a point where it's rare for me to open the editor to change anything. Even for simple changes, I prefer to ask Claude Code and then review what was done via <code>git diff</code>.</p>
<h2>Git has never been so important</h2>
<p>I've always used Git. But when AI is creating or updating code, Git becomes even more essential.
When something I'm working on isn't trivial, I ask the AI to make changes step by step and, after each interaction, I stage the modified files to review what changed.
I only make a commit when a self-contained change is ready.</p>
<p>Git has become my layer of control over the AI.</p>
<p><aside>Even the AI configurations themselves - prompts, agents, skills, Claude or Cursor settings - are versioned in a separate private repository.</aside></p>
<h2>I started using AI for everything. Productivity skyrocketed, but my satisfaction not so much</h2>
<p>For most of last year, everything seemed great. I even laughed at this <a href="https://x.com/trashh_dev/status/1990459879308591275">meme</a>:</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2026/02/me-watching-the-llm-do-the-job-i-used-to-love.png" alt="Me watching the LLM do the job I used to love" width="751" height="700" /><figcaption>Me watching the LLM do the job I used to love</figcaption></figure></p>
<p>I laughed and agreed, but I didn't imagine it would hit me later.</p>
<p>Today I'm clearly more productive with AI. I deliver more.
The code quality also tends to be better, though of course I still review everything the AI does.
Clients and companies are more satisfied, after all we're delivering more in less time.</p>
<p>Even the famous <a href="https://en.wikipedia.org/wiki/Project_management_triangle">project management triangle</a> seems affected.
Scope, time and cost have all improved simultaneously, without affecting quality - something we've always been taught is impossible.
Of course, quality still depends on how the AI is used and reviewed, but the gains are undeniable.</p>
<p>The so-called <em>vibe coding</em> hasn't yet reached the point of leaving everything 100% in the AI's hands without supervision, but the trend is heading that way.</p>
<p>And yet, something bothers me.</p>
<h2>We're outsourcing our brains to LLMs</h2>
<p>I feel less challenged. Before, when a dependency was updated, I would:</p>
<ul>
<li>Read the <code>Changelog</code></li>
<li>Identify breaking changes</li>
<li>Analyse the impact on the project</li>
<li>Adjust the code manually</li>
</ul>
<p>Today, it's far more practical to ask the AI to do it.
It'll probably do it better and in a fraction of the time.
So why would I do it manually? That's the bit that gets me.</p>
<p>Using AI or not is no longer a personal choice.
Not using AI means falling behind, becoming outdated.</p>
<p><aside>The thumbnail for this post was generated by AI. The content was reviewed by AI. We're not going back to the way things were before.</aside></p>
<h2>The new role of the programmer</h2>
<p>In practice, my job today is:</p>
<ul>
<li>Understand the problem or requirement</li>
<li>Discuss with the team until we align on a solution (high-level, not necessarily how the implementation will look)</li>
<li>Think about UI and UX</li>
<li>Plan integrations with existing systems</li>
<li>Write a Jira card</li>
</ul>
<p>After that, I send all the context to Claude Code and use Agents, Skills, MCPs and the like to execute.
Even tasks involving multiple repositories - something common where I work - are handled quite competently by AI.</p>
<p>Even commit messages, PR titles and descriptions, and Jira cards often go through AI.
I know it'll usually write them better than I would.</p>
<p>Day to day, what I do is review, simplify, and adjust what was generated.
Sometimes I fix details in the code or documentation. But the hard part has already been done.</p>
<p>And I increasingly feel less desire to do it manually. Some days, I can't even be bothered.
This leaves me with the feeling that I might be getting dumber, since the challenges are much smaller.</p>
<h2>Loss of skill - or evolution?</h2>
<p>For a while, I was hesitant to admit that I use AI for everything.
When I don't use it, I feel unproductive. Talking to other people, I realised I'm not alone.</p>
<p>I'm not doing anything wrong. I'm pursuing productivity. Right?</p>
<p>Even so, the doubt arises: will I lose my programming skills?
At least in the form they existed until now?</p>
<p>Perhaps.</p>
<p>But so what? AI will keep evolving.
I'm still needed to review, contextualise and ensure the result makes sense.
I'm not worried about losing my job - that's another discussion worth having (let me know in the comments how you feel).</p>
<p>My concern is different: <strong>my professional satisfaction</strong>.</p>
<p>Programming has always been something I loved. And now that's changing.
Not necessarily for the worse. But it's changing.</p>
<h2>AI made me 10x more productive... and 2x more insecure</h2>
<p>Sometimes I catch myself wondering if we're heading towards something like
<a href="https://www.imdb.com/title/tt0387808/">Idiocracy</a> - an exaggerated film, but with a grain of truth.</p>
<p>I'm not afraid of machines taking over everything and/or replacing us.
I still feel useful. What worries me is the transformation of the joy of programming.
Everything changed so fast. Think about what it was like 2-3 years ago.</p>
<p>It'll never be the same again.</p>
<p>Maybe I sound like an old man yelling at clouds, but the speed of change is staggering.
And it'll continue, because there's too much money and interest involved.</p>
<p>I'm not against AI - quite the opposite. I use it extensively. I advocate for it. I recommend it.
But I'm also trying to make an honest analysis of what's happening.</p>
<p>And, to be completely honest, I'm worried.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="programming" /><category term="ai" />
    </entry>

    <entry>
      <title><![CDATA[Eu parei de escrever código, e não sei se isso é bom]]></title>
      <summary><![CDATA[O trabalho que eu amava agora está sendo feito por IA]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2026/02/15/eu-parei-de-escrever-codigo-e-nao-sei-se-isso-e-bom?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2026-02-15T03:30:00.000Z</published>
      <updated>2026-02-15T03:30:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2026/02/15/eu-parei-de-escrever-codigo-e-nao-sei-se-isso-e-bom</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2026/02/15/eu-parei-de-escrever-codigo-e-nao-sei-se-isso-e-bom">
        <![CDATA[<div xml:lang="pt-BR"><p><aside>Este post também está disponível em <a href="https://www.lucascaton.com/2026/02/15/i-stopped-writing-code-and-im-not-sure-thats-a-good-thing">Inglês</a>.</aside></p>
<p><img src="/images/posts/2026/02/eu-parei-de-escrever-codigo-e-nao-sei-se-isso-e-bom.png" alt="Eu parei de escrever código (e não sei se isso é bom)"></p>
<p>Eu aprendi a programar por volta de 2004 e comecei a programar profissionalmente em 2007. Nunca parei.
Mesmo entre 2022 e 2024, <a href="https://www.youtube.com/watch?v=j8Bhjq8mjVQ">quando trabalhei como Engineering Manager</a>, continuei codando no tempo livre, ouvindo podcasts, assistindo a vídeos no YouTube e acompanhando um ecossistema que sempre me interessou.</p>
<p>Eu amo programar. Explicar para o computador o que fazer e como fazer é um prazer que só quem faz
consegue entender.
Tem desafios, mas é recompensador, tanto profissionalmente quanto financeiramente.</p>
<p>Então as IAs chegaram, e a programação foi uma das áreas mais impactadas.</p>
<p><aside>Quando eu falo IA neste post, estou me referindo principalmente a LLMs (Large Language Models) - como Claude, GPT, Gemini e similares.</aside></p>
<h2>Programar virou revisar diffs</h2>
<p>No início eu usava IA de forma esporádica. Conforme as ferramentas evoluíram, passei a usar cada vez mais.</p>
<p>Já usei editores como Vim, VS Code e Cursor.
Hoje, curiosamente, minhas ferramentas principais não são mais terminal + editor/IDE, mas
terminal + um Git GUI, que antes eu abria de vez em quando e agora uso mais do que o próprio
editor.</p>
<p>No terminal, ferramentas como Claude Code, Gemini CLI e similares são o destaque da vez.
Cheguei a um ponto em que é raro eu abrir o editor para alterar qualquer coisa. Mesmo mudanças simples, prefiro pedir ao Claude Code e depois revisar o que foi feito via <code>git diff</code>.</p>
<h2>Git nunca foi tão importante</h2>
<p>Eu sempre usei Git. Mas, quando uso IA para criar ou atualizar código, o Git se tornou ainda mais
essencial.
Quando algo que estou trabalhando não é trivial, peço para a IA fazer mudanças passo a passo e, após cada interação, movo os arquivos modificados para a <em>staging area</em> para revisar o que mudou.
Só faço o commit quando uma mudança auto-contida está pronta.</p>
<p>O Git virou minha camada de controle sobre a IA.</p>
<p><aside>Inclusive, as próprias configurações de IA - prompts, agents, skills, configurações do Claude ou Cursor - ficam versionadas em outro repositório privado.</aside></p>
<h2>Passei a usar IA para tudo. A produtividade explodiu, mas minha satisfação nem tanto</h2>
<p>Durante boa parte do último ano, tudo parecia ótimo. Eu até ri desse <a href="https://x.com/trashh_dev/status/1990459879308591275">meme</a>:</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2026/02/me-watching-the-llm-do-the-job-i-used-to-love.png" alt="Eu vendo a LLM fazer o trabalho que eu amava" width="751" height="700" /><figcaption>Eu vendo a LLM fazer o trabalho que eu amava</figcaption></figure></p>
<p>Ri e concordei, mas não imaginei que aquilo fosse me atingir depois.</p>
<p>Hoje eu sou claramente mais produtivo com IA. Entrego mais.
A qualidade do código também tende a sair melhor, embora eu ainda revise tudo o que a IA faz.
Clientes e empresas ficam mais satisfeitos, afinal estamos entregando mais em menos tempo.</p>
<p>Até o famoso <a href="https://en.wikipedia.org/wiki/Project_management_triangle">project management triangle</a>
parece afetado.
Escopo, tempo e custo melhoraram ao mesmo tempo, sem afetar a qualidade - algo que sempre aprendemos ser impossível.
Claro, a qualidade ainda depende de como a IA é usada e revisada, mas o ganho é inegável.</p>
<p>O tal do <em>vibe coding</em> ainda não chegou ao ponto de deixar tudo 100% na mão da IA sem supervisão, mas a tendência é evoluir.</p>
<p>E mesmo assim, algo me incomoda.</p>
<h2>Estamos terceirizando nosso cérebro para LLMs</h2>
<p>Sinto que estou menos desafiado. Antes, quando uma dependência era atualizada, eu:</p>
<ul>
<li>Lia o <code>Changelog</code></li>
<li>Identificava breaking changes</li>
<li>Analisava o impacto no projeto</li>
<li>Ajustava o código manualmente</li>
</ul>
<p>Hoje, é muito mais prático pedir para a IA fazer isso.
Ela provavelmente fará melhor e em uma fração do tempo.
Então por que eu faria manualmente? Esse é o ponto que me pega.</p>
<p>Usar IA ou não deixou de ser uma escolha pessoal.
Não usar IA significa ficar para trás, ficar desatualizado.</p>
<p><aside>A thumbnail desse post foi gerada por IA. O conteúdo foi revisado por IA. Não vamos voltar ao que era antes.</aside></p>
<h2>O novo papel do programador</h2>
<p>Na prática, meu trabalho hoje é:</p>
<ul>
<li>Entender o problema ou demanda</li>
<li>Discutir com o time até alinharmos uma solução (de alto nível, não necessariamente como será a implementação)</li>
<li>Pensar em UI e UX</li>
<li>Planejar integrações com sistemas existentes</li>
<li>Escrever um card no Jira</li>
</ul>
<p>Depois disso, envio todo o contexto para o Claude Code e uso Agents, Skills, MCPs e afins para executar.
Mesmo tarefas que envolvem múltiplos repositórios - algo comum onde trabalho - são feitas com bastante competência pelas IAs.</p>
<p>Até mensagens de commit, títulos e descrições de PR e cards do Jira muitas vezes passam pela IA.
Eu sei que, na maioria das vezes, ela vai escrever melhor do que eu.</p>
<p>No dia a dia, o que faço é revisar, simplificar e ajustar o que foi gerado.
Às vezes corrijo detalhes no código ou na documentação. Mas a parte mais difícil já foi feita.</p>
<p>E cada vez tenho menos vontade de fazer isso manualmente. Às vezes, dá até preguiça.
Isso me deixa com a sensação de que posso estar ficando mais burro, já que os desafios são bem menores.</p>
<h2>Perda de habilidade - ou evolução?</h2>
<p>Por um tempo, fiquei receoso de admitir que uso IA para tudo.
Quando não uso, me sinto improdutivo. Conversando com outras pessoas, percebi que não estou sozinho.</p>
<p>Não estou fazendo nada errado. Estou buscando produtividade. Certo?</p>
<p>Mesmo assim, surge a dúvida: vou perder minhas habilidades de programação?
Pelo menos no formato em que elas existiam até agora?</p>
<p>Talvez sim.</p>
<p>Mas e daí? As IAs vão continuar evoluindo.
Ainda sou necessário para revisar, contextualizar e garantir que o resultado faz sentido.
Não estou preocupado com perder emprego - essa é outra questão que vale discutir (me conte nos comentários como você se sente).</p>
<p>Minha preocupação é outra: <strong>minha satisfação profissional</strong>.</p>
<p>Programar sempre foi algo que eu amei. E agora isso está mudando.
Não necessariamente para pior. Mas está mudando.</p>
<h2>A IA me deixou 10x mais produtivo... e 2x mais inseguro</h2>
<p>Às vezes me pego pensando se estamos caminhando para algo no estilo
<a href="https://www.imdb.com/title/tt0387808/">Idiocracy</a> - que é um filme exagerado, mas com um fundo de verdade.</p>
<p>Não estou com medo das máquinas dominarem tudo e/ou nos substituírem.
Ainda me sinto útil. O que me preocupa é a transformação do prazer de programar.
Tudo mudou muito rápido. Pense em como era 2-3 anos atrás.</p>
<p>Nunca mais será como antes.</p>
<p>Talvez eu soe como um velho reclamando, mas a velocidade da mudança impressiona.
E vai continuar, porque há muito dinheiro e interesse envolvidos.</p>
<p>Não sou contra IAs - muito pelo contrário. Uso intensamente. Defendo. Recomendo.
Mas também estou tentando fazer uma análise honesta do que está acontecendo.</p>
<p>E, sendo bem sincero, estou preocupado.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="programacao" /><category term="ia" />
    </entry>

    <entry>
      <title><![CDATA[Meu curso de React agora está gratuito]]></title>
      <summary><![CDATA[O curso React: Direto ao Ponto foi liberado de graça]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2025/08/02/meu-curso-de-react-agora-esta-gratuito?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2025-08-01T22:30:00.000Z</published>
      <updated>2025-08-01T22:30:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2025/08/02/meu-curso-de-react-agora-esta-gratuito</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2025/08/02/meu-curso-de-react-agora-esta-gratuito">
        <![CDATA[<div xml:lang="pt-BR"><p>Olá, meus caros! Tenho o prazer de anunciar que o meu curso <strong>React: Direto ao Ponto</strong> agora
está disponível gratuitamente para todo mundo! 🚀 O curso era pago, e as inscrições foram
encerradas em agosto de 2023. Como não tenho planos de abrir novas turmas, decidi liberar o
conteúdo completo de graça 😃</p>
<p><a href="https://www.lucascaton.com/pt-BR/cursos/rdp" target="_blank" rel="noopener noreferrer">ACESSAR O CURSO</a></p>
<p>Recomendo assistir pelo menos à 1ª e à 2ª aula para ver tudo o que você vai aprender. Embora o
curso não seja novo, cerca de 95% do conteúdo continua atual!</p>
<h2>Por que React?</h2>
<p>React é atualmente uma das tecnologias mais demandadas no mercado de desenvolvimento front-end. Com ele, você pode:</p>
<ul>
<li>Criar interfaces de usuário interativas e modernas</li>
<li>Desenvolver aplicações web escaláveis</li>
<li>Trabalhar com uma das tecnologias mais utilizadas por grandes empresas</li>
<li>Ter acesso a um ecossistema rico de ferramentas e bibliotecas</li>
</ul>
<h2>Para quem é este curso?</h2>
<p>Este curso é ideal para:</p>
<ul>
<li>Desenvolvedores que já conhecem JavaScript básico</li>
<li>Profissionais que querem migrar para o desenvolvimento front-end moderno</li>
<li>Estudantes que querem aprender uma tecnologia em alta demanda</li>
<li>Qualquer pessoa interessada em criar aplicações web interativas</li>
</ul>
<h2>Metodologia</h2>
<p>Como sempre, minha abordagem é <strong>direto ao ponto</strong>. Nada de enrolação, teoria em excesso ou
conteúdo desnecessário. A ideia é focar no que realmente importa para você sair do curso criando
aplicações React do mundo real.</p>
<p>Cada aula foi pensada para maximizar seu aprendizado em menos tempo, com exemplos práticos e
exercícios que simulam situações reais do mercado de trabalho.</p>
<p><a href="https://www.lucascaton.com/pt-BR/cursos/rdp" target="_blank" rel="noopener noreferrer">ACESSAR O CURSO</a></p>
<h2>O que você vai aprender? (lista de vídeos)</h2>
<ul>
<li>Introdução ao curso</li>
<li>Introdução à <strong>React</strong></li>
<li>Instalação do <strong>Node.js</strong> &#x26; do <strong>Yarn</strong></li>
<li><strong>VS Code</strong> (editor) e algumas extensões</li>
<li><strong>React Developer Tools</strong> (extensão para navegadores)</li>
<li>Ferramentas</li>
<li>Primeiro projeto e <strong>JSX</strong></li>
<li><code>Fragment</code></li>
<li>Limpando o projeto</li>
<li>Criando componentes</li>
<li>Importando CSS e imagens</li>
<li>Reusabilidade - <strong>Props</strong> (propriedades) &#x26; <strong>Children</strong></li>
<li><code>useState</code>: o React Hook para gerenciar estados</li>
<li>Evento <code>onClick</code></li>
<li>Evento <code>onChange</code></li>
<li><strong>Desestruturação</strong></li>
<li>Repetições com <code>map</code></li>
<li>Atributo especial <code>key</code></li>
<li>Criando o projeto <em>RGB</em> (e como usar a extensão <strong>React Developer Tools</strong>)</li>
<li>Componente para prever a cor</li>
<li><strong>Spread operator</strong> e <strong>Imutabilidade</strong></li>
<li>Passando funções como <code>props</code></li>
<li><strong>Desabilitando</strong> elementos</li>
<li><strong>Renderização condicional</strong></li>
<li>Gerando dados aleatórios</li>
<li>Criando o projeto <em>Gerador de Senhas</em></li>
<li><strong>Estilizando</strong> a aplicação</li>
<li><code>useEffect</code> - o React Hook que executa efeitos colaterais</li>
<li><em>Gerando a senha</em> - parte 1</li>
<li><em>Gerando a senha</em> - parte 2</li>
<li><em>Gerando a senha</em> - parte 3</li>
<li>Criando um componente para exibir a senha</li>
<li><strong>Expressões regulares</strong> para classificar e colorir a senha</li>
<li>Copiando a senha para a <strong>área de transferência</strong></li>
<li>Introdução à <strong>Context API</strong></li>
<li>Criando o projeto <em>Theme Switcher</em></li>
<li><code>createContext</code>, <code>Provider</code> e <code>useContext</code></li>
<li><code>localStorage</code></li>
<li>Criando o projeto <em>Timers</em></li>
<li>CSS Modules</li>
<li><code>onSubmit</code> e <code>FormData</code></li>
<li>Atualizações Funcionais</li>
<li><strong>Spread Properties</strong></li>
<li>Fonte personalizada</li>
<li><code>setInterval</code> e <code>clearInterval</code></li>
<li>Componente com <strong>SVG</strong></li>
<li>Removendo timers</li>
<li>Limpando recursos ao desmontar componentes</li>
<li><strong>Memoization</strong></li>
<li><code>React.memo</code></li>
<li><code>useCallback</code> e <strong>Shallow comparison</strong></li>
<li><code>useMemo</code></li>
<li>Usando <code>useRef</code> para focar em um elemento</li>
<li>Usando <code>useRef</code> com o ID do setInterval</li>
<li>Função <code>reduce</code></li>
<li>Introdução à <code>useReducer</code></li>
<li>Criando um <em>formulário de login</em></li>
<li>Implementando com <code>useState</code></li>
<li>Refatorando com <code>useReducer</code></li>
<li>Buscando usuários na <strong>API do GitHub</strong></li>
<li>Consumindo lista de repositórios da <strong>API do GitHub</strong></li>
<li>Introdução ao <strong>Next.js</strong></li>
<li>Criando o projeto <em>Pizzaton</em></li>
<li><code>Next/Link</code></li>
<li>Lendo dados de <strong>arquivos JSON</strong></li>
<li><code>Next/Image</code></li>
<li>Rotas dinâmicas (parte 1)</li>
<li>Rotas dinâmicas (parte 2)</li>
<li><strong>Redirecionamentos</strong></li>
<li><strong>Deployment</strong> (colocando seu projeto no ar)</li>
<li>Conclusão do curso</li>
</ul>
<p><a href="https://www.lucascaton.com/pt-BR/cursos/rdp" target="_blank" rel="noopener noreferrer">ACESSAR O CURSO</a></p>
<p><aside>Veja outros cursos que liberei gratuitamente <a href="https://www.lucascaton.com/pt-BR/cursos">nessa página</a>! 🙂</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="curso" /><category term="react" /><category term="javascript" />
    </entry>

    <entry>
      <title><![CDATA[Why Ruby class methods aren't always private, and how to fix that]]></title>
      <summary><![CDATA[It's surprisingly easy to expose class methods as public inside `class << self`]]></summary>
      <link href="https://www.lucascaton.com/2025/01/25/why-ruby-class-methods-arent-always-private-and-how-to-fix-that?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2025-01-25T01:30:00.000Z</published>
      <updated>2025-01-25T01:30:00.000Z</updated>
      <id>https://www.lucascaton.com/2025/01/25/why-ruby-class-methods-arent-always-private-and-how-to-fix-that</id>
      <content type="html" xml:base="https://www.lucascaton.com/2025/01/25/why-ruby-class-methods-arent-always-private-and-how-to-fix-that">
        <![CDATA[<div xml:lang="en"><p>Ruby provides multiple ways to define class methods, and one common approach is to use the
<code>class &#x3C;&#x3C; self</code> block. However, this syntax has a subtle gotcha: methods defined inside the block
are <strong>public by default</strong>, even if the block is nested inside a <code>private</code> section.</p>
<p>This behaviour can unintentionally expose class methods that should remain private, making your code
harder to maintain.</p>
<p>Here's an example:</p>
<pre><code class="language-ruby">class MyClass
  private
  class &#x3C;&#x3C; self
    def my_method # ← this is a public method 😱
      # ...
    end
  end
end
</code></pre>
<h3>Why does this happen?</h3>
<p>When you use <code>class &#x3C;&#x3C; self</code>, Ruby opens the singleton class of the object (in this case, your class). While methods defined in a normal <code>class</code> body respect the current visibility context (<code>private</code>, <code>protected</code>, or <code>public</code>), <code>class &#x3C;&#x3C; self</code> resets the default visibility to <code>public</code>. As a result, any method defined there will be public unless explicitly declared otherwise.</p>
<h3>Option #1 to fix it: declare <code>private</code> explicitly</h3>
<p>Within the <code>class &#x3C;&#x3C; self</code> block, explicitly set the visibility to <code>private</code>:</p>
<pre><code class="language-ruby">class MyClass
  private
  class &#x3C;&#x3C; self
    private # ← you have to declare `private` again
    def my_method # ← now this method is actually private!
      # ...
    end
  end
end
</code></pre>
<p>By the way, all subsequent methods defined in the block will also be private!</p>
<h3>Option #2: use <code>private_class_method</code></h3>
<p>Although I personally don't like this approach, an alternative is to define the class method and then use <code>private_class_method</code> to set its visibility:</p>
<pre><code class="language-ruby">class MyClass
  class &#x3C;&#x3C; self
    def my_method
      # ...
    end
  end
  private_class_method :my_method
end
</code></pre>
<p>Keep this in mind and you'll avoid a subtle visibility bug in your Ruby code.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[Estou de volta ao YouTube]]></title>
      <summary><![CDATA[Já são mais de 13 vídeos novos!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2024/08/11/voltei-ao-youtube?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2024-08-10T23:00:00.000Z</published>
      <updated>2024-08-10T23:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2024/08/11/voltei-ao-youtube</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2024/08/11/voltei-ao-youtube">
        <![CDATA[<div xml:lang="pt-BR"><p>Olá, meus caros!</p>
<p>Meu canal no YouTube finalmente está de volta, e voltou com tudo! Tenho publicado conteúdos novos
sobre vários temas que espero que te interessem. Se você ainda não está inscrito, não perde tempo:
tem muita coisa boa vindo por aí.</p>
<p>👉 <strong><a href="https://www.youtube.com/lucascaton?sub_confirmation=1">youtube.com/lucascaton</a></strong></p>
<p>Além do YouTube, minhas outras redes sociais também estão ativas. Se você quiser acompanhar mais de
perto e ver conteúdos sobre programação, carreira, trabalho fora do Brasil, bastidores e muito
mais:</p>
<p></p>
<p>Fica ligado, e até o próximo vídeo! 👋</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="youtube" />
    </entry>

    <entry>
      <title><![CDATA[How to automatically run tests and code analyzers via Git hooks]]></title>
      <summary><![CDATA[Run the same checks locally that you'd normally rely on in CI]]></summary>
      <link href="https://www.lucascaton.com/2024/05/22/how-to-automatically-run-tests-and-code-analyzers-via-git-hooks?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2024-05-21T23:00:00.000Z</published>
      <updated>2024-05-21T23:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2024/05/22/how-to-automatically-run-tests-and-code-analyzers-via-git-hooks</id>
      <content type="html" xml:base="https://www.lucascaton.com/2024/05/22/how-to-automatically-run-tests-and-code-analyzers-via-git-hooks">
        <![CDATA[<div xml:lang="en"><p>I like being able to run locally the same tools I'd use on a
<a href="https://en.wikipedia.org/wiki/Continuous_integration">CI server</a> so I can catch issues early.
There are various tools you might want to run:</p>
<ul>
<li>Automated tests</li>
<li>Code analyzers, such as linters and security vulnerability scanners</li>
<li>Anything else you'd run on your CI server</li>
</ul>
<p>However, you may face the following issues:</p>
<ul>
<li>👎 Running all these tools can sometimes take too long</li>
<li>👎 You might not want to run everything before pushing your changes to your code hosting platform, like GitHub</li>
<li>👎 You may forget what to run, especially if you need to run many different tools</li>
<li>👎 What you run, and how you run it, might differ from how a colleague on the same project does it</li>
</ul>
<h2>What I tried before (and didn't work as well as I expected)</h2>
<p>In 2015 (9 years ago!), I created a Ruby gem called <a href="https://github.com/lucascaton/massa">massa</a> to help solve this problem. I'm no longer using or maintaining this project, but the idea was to create <a href="https://github.com/lucascaton/massa/blob/master/config/default_tools.yml">a YAML file</a> where you could specify what you'd like to run and even define which tools are required. This way, optional tools wouldn't cause the process to fail if they encountered issues/offenses.</p>
<p>Eventually, I stopped using that and began relying on my ZSH history, ZSH autosuggestions, and <a href="https://github.com/junegunn/fzf">fzf</a> to remind me of everything I need to run. The only reason this isn't a (very) bad idea is that I was running everything in one single command. Here's an example for a Rails app:</p>
<pre><code class="language-sh">bundle exec rubocop &#x26;&#x26; bundle exec rspec &#x26;&#x26; bundle exec brakeman --run-all-checks --exit-on-warn --exit-on-error --rails7 --no-pager
</code></pre>
<p>As you can probably tell, commands can get lost in the history, and this solution doesn't address some of the issues described at the beginning of this post.</p>
<h2>New approach</h2>
<p>I'm now trying something that seems to be a better overall approach: <strong>Git hooks</strong>. I've been using
Git hooks for ages, but I had never spent time creating a formal process across the open-source
projects I maintain and my side projects.</p>
<p>The first thing I did was <a href="https://github.com/lucascaton/dotfiles/commit/e6ee880">create a default git pre-commit hook</a>.
With that and the <code>[init] templatedir</code> setting in my <code>~/.gitconfig</code> (which you can also see in the
linked commit), every time I clone a repo or create a new one with <code>git init</code>, it automatically
gets a copy of that hook saved in <code>.git/hooks/pre-commit</code>.</p>
<p><aside>You can also manually create these files and give them execution permission by running <code>chmod +x .git/hooks/pre-commit</code>.</aside></p>
<p>This is what my <code>pre-commit</code> hook script looks like at the moment:</p>
<pre><code class="language-sh">#! /bin/bash
set -euxo pipefail
# >>> For Node.js/React/React Native projects:
# yarn lint
# yarn test
# yarn test:all
# >>> For Ruby/Rails projects:
# bundle exec rubocop
# bundle exec rspec
# bundle exec brakeman --run-all-checks --exit-on-warn --exit-on-error --rails7 --no-pager --quiet
# bundle exec rails_best_practices . -c config/rails_best_practices.yml
# TODO: uncomment the above lines and remove the below line
echo "⚠️ Edit or remove the .git/hooks/pre-commit file"
</code></pre>
<p>For each project, I uncomment the lines that I want to run and remove the <code>echo</code> with the warning at the end of the script. When necessary, I add extra project-specific tools as well.</p>
<p>Now, every time you attempt to commit something, that script will run. If it fails, the commit will not be completed, and you'll see what's failing. I also like to keep the <code>x</code> flag in the <code>set</code> command to see what command is running. If all tools pass, i.e., if all commands <a href="https://en.wikipedia.org/wiki/Exit_status">finish their execution with status 0</a>, the commit will be completed.</p>
<h2>What if it takes too long?</h2>
<p>In these cases, I like to have two hooks:</p>
<ul>
<li><code>pre-commit</code>: runs quick things, usually linters and fast automated tests</li>
<li><code>pre-push</code>: runs everything, only when running <code>git push</code></li>
</ul>
<p><aside>You can always use the <code>--no-verify</code> flag to skip Git hooks. For example: <code>git commit --no-verify -m "commit message"</code></aside></p>
<h2>Aliases, because I'm lazy</h2>
<p>I'm an <a href="https://github.com/lucascaton/dotfiles/blob/63edafb/files/zshrc#L123-L206">alias addict</a>.
For different reasons, I may want to run the <code>pre-commit</code> hook before I'm actually ready to commit
the changes, so I've set the following <a href="https://github.com/lucascaton/dotfiles/blob/63edafb/files/zshrc#L145-L146">aliases</a>:</p>
<pre><code class="language-sh">alias ch=".git/hooks/pre-commit" # ch = (pre-)Commit Hook
alias ph=".git/hooks/pre-push" # ph = (pre-)Push Hook
</code></pre>
<p>Let me know in the comments how you solve this problem, and whether you use a different or better
approach 🙂</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="git" /><category term="ci" />
    </entry>

    <entry>
      <title><![CDATA[Como instalar o PostgreSQL no Windows (WSL), no Linux e no macOS]]></title>
      <summary><![CDATA[Um guia passo a passo]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2023/12/07/como-instalar-o-postgresql-no-windows-wsl-no-linux-e-no-macos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2023-12-06T21:00:00.000Z</published>
      <updated>2023-12-06T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2023/12/07/como-instalar-o-postgresql-no-windows-wsl-no-linux-e-no-macos</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2023/12/07/como-instalar-o-postgresql-no-windows-wsl-no-linux-e-no-macos">
        <![CDATA[<div xml:lang="pt-BR"><p>Olá, meus caros!</p>
<p>As aulas que você está prestes a assistir faziam parte de um curso pago. As
inscrições foram encerradas em agosto de 2023. Como não tenho planos de abrir
novas turmas, decidi disponibilizar parte do conteúdo gratuitamente 🙂</p>
<p>Espero que goste. Sucesso em sua jornada! 👊</p>
<p><a href="https://www.youtube.com/watch?v=R_tpnjR1s1U"><img src="https://i.ytimg.com/vi_webp/R_tpnjR1s1U/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="curso" /><category term="postgresql" />
    </entry>

    <entry>
      <title><![CDATA[Introdução à OO (Orientação a Objetos) usando Ruby]]></title>
      <summary><![CDATA[Fundamentos e prática]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2023/12/05/introducao-a-orientacao-a-objetos-com-ruby?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2023-12-05T06:00:00.000Z</published>
      <updated>2023-12-05T06:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2023/12/05/introducao-a-orientacao-a-objetos-com-ruby</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2023/12/05/introducao-a-orientacao-a-objetos-com-ruby">
        <![CDATA[<div xml:lang="pt-BR"><p>Olá, meus caros!</p>
<p>As aulas que você está prestes a assistir faziam parte de um curso pago. As
inscrições foram encerradas em agosto de 2023. Como não tenho planos de abrir
novas turmas, decidi disponibilizar parte do conteúdo gratuitamente 🙂</p>
<p>Espero que goste. Sucesso em sua jornada! 👊</p>
<p><a href="https://www.youtube.com/watch?v=R_tpnjR1s1U"><img src="https://i.ytimg.com/vi_webp/R_tpnjR1s1U/maxresdefault.webp" alt="YouTube video" /></a></p>
<h3>Códigos usados no vídeo:</h3>
<h4><code>metodos.rb</code></h4>
<pre><code class="language-ruby">def numeros_impares(min = 0, max)
  (min..max).each do |numero|
    puts "O número #{numero} é ímpar" if numero.odd?
  end
end
def media(elementos)
  elementos.sum / elementos.size
end
def rolar_dado(faces)
  return 'número de faces precisa ser maior que 1' if faces &#x3C;= 1
  rand(faces) + 1
end
numeros_impares(80, 90)
puts '---'
numeros_impares(12)
# puts media([9, 1, 2])
# puts media([10, 20])
# puts rolar_dado(1)
# puts rolar_dado(6)
</code></pre>
<h4><code>classes.rb</code></h4>
<pre><code class="language-ruby"># 1ª demonstração
class Cachorro
  def latir
    puts "au au"
  end
end
class Gato
  def miar
    puts "miau"
  end
end
cachorro = Cachorro.new
cachorro.latir
Gato.new.miar
#################################################
# 2ª demonstração
class Conta
end
class Banco
  def criar_nova_conta
    Conta.new
  end
end
banco = Banco.new
conta = banco.criar_nova_conta
</code></pre>
<h4><code>escopo_de_variaveis.rb</code></h4>
<pre><code class="language-ruby">class Pessoa
  def definir_nome(novo_nome)
    puts "O novo nome é #{novo_nome}"
    @nome = novo_nome
  end
  def exibir_informacoes
    puts "Nome: #{@nome}"
  end
end
pessoa = Pessoa.new
pessoa.definir_nome('Lucas')
pessoa.exibir_informacoes
pessoa2 = Pessoa.new
pessoa2.definir_nome("Daniel")
pessoa2.exibir_informacoes
</code></pre>
<h4><code>metodo_construtor.rb</code></h4>
<pre><code class="language-ruby">class Pessoa
  def initialize(nome, idade)
    @nome = nome
    @idade = idade
  end
  def exibir_informacoes
    puts "#{@nome} tem #{@idade} anos."
  end
end
pessoa = Pessoa.new('Joana', 45)
pessoa.exibir_informacoes
</code></pre>
<h4><code>setters_and_getters.rb</code></h4>
<pre><code class="language-ruby">class Produto
  attr_reader :fabricante      # somente leitura
  attr_writer :preco           # somente escrita
  attr_accessor :nome, :codigo # ambos leitura e escrita
  def initialize
    @fabricante = 'Apple'
    @codigo = 1234
  end
end
celular = Produto.new
# celular.fabricante = 'LG' # tentando chamar o setter (x)
# puts celular.fabricante   # tentando chamar o getter (✓)
# celular.preco = 1000 # tentando chamar o setter (✓)
# puts celular.preco   # tentando chamar o getter (x)
# celular.nome = 'iPhone' # tentando chamar o setter (✓)
# puts celular.nome       # tentando chamar o getter (✓)
# celular.codigo = 6789 # tentando chamar o setter (✓)
# puts celular.codigo   # tentando chamar o getter (✓)
</code></pre>
<h4><code>metodo_privado.rb</code></h4>
<pre><code class="language-ruby">class Sorteio
  def initialize(participantes)
    @participantes = participantes
  end
  def sortear
    return if @participantes.empty?
    sorteado = @participantes.sample
    puts "O participante sorteado foi: #{sorteado}!"
    remover_participante(sorteado)
  end
  private
  def remover_participante(participante)
    @participantes.delete(participante)
  end
end
participantes = ['Bruno', 'Gabriela', 'Leandro', 'Marcia']
sorteio = Sorteio.new(participantes)
sorteio.sortear
sorteio.sortear
sorteio.sortear
sorteio.sortear
sorteio.sortear
# Não é possível chamar o método privado abaixo:
# sorteio.remover_participante('qualquer coisa')
</code></pre>
<h4><code>metodo_de_classe.rb</code></h4>
<pre><code class="language-ruby">class Tempo
  def self.agora
    Time.now
  end
  # Podemos misturar métodos de classe e métodos de instância
  # na mesma classe, sem problemas:
  def alguma_coisa
    puts "funciona!"
  end
end
puts Tempo.agora
# tempo = Tempo.new
# tempo.alguma_coisa
# # ou...
Tempo.new.alguma_coisa
</code></pre>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="curso" /><category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[Introdução à programação (usando a linguagem Ruby)]]></title>
      <summary><![CDATA[100% gratuito]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2023/12/04/introducao-a-programacao-com-ruby?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2023-12-03T22:00:00.000Z</published>
      <updated>2023-12-03T22:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2023/12/04/introducao-a-programacao-com-ruby</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2023/12/04/introducao-a-programacao-com-ruby">
        <![CDATA[<div xml:lang="pt-BR"><p>Olá, meus caros!</p>
<p>As aulas que você está prestes a assistir faziam parte de um curso pago. As
inscrições foram encerradas em agosto de 2023. Como não tenho planos de abrir
novas turmas, decidi disponibilizar parte do conteúdo gratuitamente 🙂</p>
<p>Espero que goste. Sucesso em sua jornada! 👊</p>
<p><a href="https://www.youtube.com/watch?v=F_cQSB3l0W0"><img src="https://i.ytimg.com/vi_webp/F_cQSB3l0W0/maxresdefault.webp" alt="YouTube video" /></a></p>
<h3>Instalando ferramentas de desenvolvimento (comandos executados):</h3>
<pre><code class="language-bash"># Somente no Windows:
wsl --install
wsl --set-default-version 1 # Pode não ser necessário
wsl --set-default-version 2 # Pode não ser necessário
</code></pre>
<pre><code class="language-bash"># Windows e Linux:
sudo apt update &#x26;&#x26; sudo apt upgrade
sudo apt install build-essential git automake autoconf libreadline-dev libncurses-dev libssl-dev libyaml-dev libxslt-dev libffi-dev libtool unixodbc-dev unzip curl zlib1g-dev sqlite3 libsqlite3-dev
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch vX.X.X
echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
asdf --version
</code></pre>
<pre><code class="language-bash"># Somente no Windows:
\\wsl$
</code></pre>
<pre><code class="language-bash"># Somente no macOS:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install asdf
echo -e "\n. $(brew --prefix asdf)/libexec/asdf.sh" >> ~/.zshrc
asdf --version
</code></pre>
<pre><code class="language-bash"># Todos os sistemas:
asdf plugin-add ruby
asdf install ruby X.X.X
asdf global ruby X.X.X
ruby -v
</code></pre>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="curso" /><category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[A Decade in Australia: a home away from home]]></title>
      <summary><![CDATA[🇦🇺 My 10th Austranniversary]]></summary>
      <link href="https://www.lucascaton.com/2023/08/16/a-decade-in-australia-home-away-from-home?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2023-08-15T22:50:00.000Z</published>
      <updated>2023-08-15T22:50:00.000Z</updated>
      <id>https://www.lucascaton.com/2023/08/16/a-decade-in-australia-home-away-from-home</id>
      <content type="html" xml:base="https://www.lucascaton.com/2023/08/16/a-decade-in-australia-home-away-from-home">
        <![CDATA[<div xml:lang="en"><p><figure><img src="https://www.lucascaton.com/images/posts/2023/08/a-decade-in-australia-map.jpg" alt="A Decade in Australia" width="1280" height="720" /><figcaption>A Decade in Australia</figcaption></figure></p>
<p>A little over ten years ago, I was looking for a job that held the potential to sponsor my work visa
in Australia. At the time, I wasn't quite sure if I had what it took to secure one. It took a while
but on April 15, 2013, the course of my life took a remarkable turn. That morning, I woke up to find
a life-changing email in my inbox with the subject "Offer of Employment". It was from
<a href="https://www.linkedin.com/in/bruces/">Bruce Stronge</a>, who I'll forever be grateful for offering me
an opportunity that would lead me to a life I could never have imagined.</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2023/08/a-decade-in-australia-email.png" alt="The most impactful email of my life" width="1168" height="354" /><figcaption>The most impactful email of my life</figcaption></figure></p>
<p>On August 16, 2013, exactly 10 years ago, my wife Aline (Lily) and I embarked on a journey that
would redefine our lives. Leaving our home in Brazil, we arrived in Australia with dreams and hopes
for a fresh start. The anticipation and uncertainty marked the beginning of an adventure that would
shape us in unimaginable ways. Today we're celebrating 10 Years in Australia! 🇦🇺</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2023/08/a-decade-in-australia-lucas-and-aline.jpg" alt="Aline (Lily) and
I in our early days living in Brisbane" width="1333" height="1000" /><figcaption>Aline (Lily) and
I in our early days living in Brisbane</figcaption></figure></p>
<p>Beyond learning to love Vegemite and Tim Tam, the contrasts in language, habits, food, and even
driving side have enriched my perspective and broadened my horizons.</p>
<p>Over the past decade, I've had the privilege of meeting remarkable people who have become part of my
life. From colleagues at the three different jobs I've held to the camaraderie of my Taekwondo club
and the shared joy of board game days, each connection has added vibrancy to my Aussie experience.</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2023/08/a-decade-in-australia-friends.jpg" alt="Some of the first friends I made in Australia" width="960" height="620" /><figcaption>Some of the first friends I made in Australia</figcaption></figure></p>
<p>From the Australian breathtaking landscapes to its vibrant culture, I've found <strong>a home away from
home</strong> that resonates with my soul in this amazing country.</p>
<p>Australia isn't just a place though; it's where our family grew. Our two beloved children, Harry and
Noah, were born here, adding immeasurable joy and purpose to our lives. The memories we've created
have intensified our connection to this land.</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2023/08/a-decade-in-australia-glass-house-mountains.jpg" alt="Glass House Mountains, QLD" width="960" height="720" /><figcaption>Glass House Mountains, QLD</figcaption></figure></p>
<p>While the journey has been incredible, it hasn't been without its challenges. Being far away from
family and friends in Brazil has been the toughest part. However, the strength of the bonds we've
forged here and the connections we've made have provided comfort and support to us.</p>
<p>I want to take this moment to express my heartfelt gratitude to those who have made this journey
extraordinary. Bruce Stronge, for the opportunity I mentioned in the beginning; you might not
realise how important you were to me and my family and I can't thank you enough. Ricardo Bernardeli
and Raissa Mantovani, your referral to NetEngine, support, friendship, and warm welcome to Australia
will always hold a special place in my heart. To Thiago Aléssio (aka. Xis) and Vitor Pellegrino,
your courage to pursue new horizons inspired my own leap of faith.</p>
<p>As I celebrate this milestone, I eagerly look forward to the future. The prospect of more years in
Australia with new experiences, friendships, and growth excites me. With a heart full of gratitude,
I embrace the journey that continues to unfold! 🦘🐨💚</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2023/08/a-decade-in-australia-brisbane.jpg" alt="Brisbane, QLD" width="1078" height="720" /><figcaption>Brisbane, QLD</figcaption></figure></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" />
    </entry>

    <entry>
      <title><![CDATA[My Favorite Rails Upgrade Strategy]]></title>
      <summary><![CDATA[Ditch the rake task and try this method instead]]></summary>
      <link href="https://www.lucascaton.com/2023/01/11/my-favorite-rails-upgrade-strategy?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2023-01-11T00:15:00.000Z</published>
      <updated>2023-01-11T00:15:00.000Z</updated>
      <id>https://www.lucascaton.com/2023/01/11/my-favorite-rails-upgrade-strategy</id>
      <content type="html" xml:base="https://www.lucascaton.com/2023/01/11/my-favorite-rails-upgrade-strategy">
        <![CDATA[<div xml:lang="en"><p>Upgrading a Ruby on Rails app can be a daunting task, but I've found a strategy
that works well, particularly for small to medium size projects.</p>
<p>Instead of using the <code>rails app:update</code> rake task, which is the
<a href="https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#the-update-task">approach recommended in the official Rails Guides</a>,
I prefer to generate a new app, for example with the following command:</p>
<pre><code class="language-bash">rails new --database postgresql --skip-test /tmp/my-app
# Use any other flag to make it as close as possible to the original app
</code></pre>
<p>Then, I replace all the files in the current repository with the new ones,
except for the <code>.git</code> directory. After that, I compare the changes in each file
and decide whether to keep or remove them based on whether they make sense for
my project running on the new version of Rails.</p>
<p>One of the benefits of this approach is that it addresses all the necessary
changes at once, rather than only updating the strictly required files like the
rake task does.</p>
<p>The rake task will always create a
<code>config/initializers/new_framework_defaults_[old-version].rb</code> file, which is
frequently overlooked and left unmodified (until it causes problems or during
the next upgrade), resulting in the app running on the new Rails version with
some of the old version's defaults.</p>
<p>The strategy I use can be a bit more time-consuming (after all, you're ripping
the whole upgrade steps off like a Band-Aid), but in my experience, it has
resulted in fewer issues.</p>
<p>For example, I recently upgraded an app and realised that with the rake task
approach, it didn't upgrade the <code>app/models/application_record.rb</code> file at all,
while this method would have replaced:</p>
<pre><code class="language-diff"> class ApplicationRecord &#x3C; ActiveRecord::Base
-  self.abstract_class = true
+  primary_abstract_class
 end
</code></pre>
<p>It's not a big deal but I'd like to have my app fully upgraded, almost like it
was created using the <code>rails new</code> command from the latest Rails.</p>
<p>Overall, while both approaches can get the job done, I find that generating a
new app and carefully comparing the changes is a more reliable strategy for
upgrading a Rails app.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" />
    </entry>

    <entry>
      <title><![CDATA[ChatGPT vai mudar sua vida para sempre]]></title>
      <summary><![CDATA[Você não vai acreditar no que essa IA pode fazer]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2022/12/11/chat-gpt-vai-mudar-sua-vida-para-sempre?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2022-12-10T16:43:00.000Z</published>
      <updated>2022-12-16T07:18:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2022/12/11/chat-gpt-vai-mudar-sua-vida-para-sempre</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2022/12/11/chat-gpt-vai-mudar-sua-vida-para-sempre">
        <![CDATA[<div xml:lang="pt-BR"><p>O <strong>ChatGPT</strong> é um modelo de linguagem de grande porte treinado pela OpenAI com habilidades em
conversar e responder perguntas de maneira natural e humana.</p>
<p>Fiquei impressionado com a capacidade do ChatGPT em gerar respostas precisas e coerentes e estou
animado para compartilhar esse conteúdo com vocês.</p>
<p>Espero que vocês gostem e se divirtam assistindo ao vídeo tanto quanto eu me diverti produzindo:</p>
<p><a href="https://www.youtube.com/watch?v=7vltUSlYPo4"><img src="https://i.ytimg.com/vi_webp/7vltUSlYPo4/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="chatgpt" /><category term="ia" />
    </entry>

    <entry>
      <title><![CDATA[RubyConf+ Brasil 2022: desconto de 25%]]></title>
      <summary><![CDATA[Presencial e online]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2022/08/11/ruby-conf-brasil-2022-desconto-de-25?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2022-08-10T21:00:00.000Z</published>
      <updated>2022-08-10T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2022/08/11/ruby-conf-brasil-2022-desconto-de-25</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2022/08/11/ruby-conf-brasil-2022-desconto-de-25">
        <![CDATA[<div xml:lang="pt-BR"><p>Depois de tanto tempo sem eventos presenciais, eu gostaria de compartilhar com vocês que a
<strong>RubyConf+ 2022</strong> será presencial e online!</p>
<p>Confesso que eu sinto muita falta desse tipo de evento. Sempre curti muito rever os amigos, assistir
as apresentações, almoçar com a galera, conhecer gente nova (networking!) e claro, ir para o
<em>happy hour</em> depois! 🍻😄</p>
<p><img src="/images/posts/2022/08/ruby-conf-brasil-2022.jpg" alt="RubyConf+ Brasil 2022"></p>
<p>Por ser um "DEV Parceiro" do evento, tenho um cupom de desconto para vocês, que é válido tanto para
o evento presencial, quanto online. É só usar o cupom <code>LUCASCATON_25</code> para ganhar 25% de desconto ou
clicar em um dos links abaixo:</p>
<ul>
<li><a href="https://www.sympla.com.br/rubyconf-2022-presencial__1575172?d=LUCASCATON_25">Desconto para o evento presencial 🛣🍔🥤</a></li>
<li><a href="https://www.sympla.com.br/rubyconf-2022-online__1575188?d=LUCASCATON_25">Desconto para o evento online 👨‍💻📺👩‍💻</a></li>
</ul>
<h2>Outra novidade!</h2>
<p>Vou aproveitar para compartilhar uma decisão que tomei depois de conversar muito com o meu sócio
Mauricio. Há uns meses, nós decidimos que era hora de parar de vender o
<a href="https://www.lucascaton.com/cursos/cplc">curso de Ruby/Rails</a>
e se focar nos outros cursos, principalmente no de
<a href="https://www.lucascaton.com/cursos/rdp">React</a>.</p>
<p>O principal motivo é que o curso não foi gravado usando a última versão do Rails e apesar de pouca
coisa ter mudado na prática, não fazia mais sentido continuar vendendo um curso o qual não usa a
última versão. Porém aconteceu algo que a gente não esperava: a procura não só não parou como
aumentou! 😅</p>
<p>Através de conversas com interessados, ficamos sabendo que muitas empresas ainda têm vários projetos
(a maioria, eu diria!) usando Rails 6 ou versões mais antigas, então reconsideramos já que tanta
gente poderia se beneficiar com todo o conteúdo do curso (eu inclusive ao vender mais, hehe).</p>
<p>Isso significa que vamos reabrir as inscrições ainda essa semana, para ajudar quem quer chegar na
RubyConf já com uma boa base!
Cadastre seu email na <a href="https://www.lucascaton.com/cursos/cplc">lista de espera</a> para não perder! 😉</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rubyconf" />
    </entry>

    <entry>
      <title><![CDATA[Tutorial: Criando um blog com Next.js]]></title>
      <summary><![CDATA[Usaremos React, Tailwind CSS e posts em Markdown]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2021/12/07/criando-um-blog-com-nextjs?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2021-12-07T10:34:00.000Z</published>
      <updated>2021-12-07T10:34:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2021/12/07/criando-um-blog-com-nextjs</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2021/12/07/criando-um-blog-com-nextjs">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://nextjs.org/">Next.js</a> é tão sensacional que meio que virou meu <em>framework</em> padrão para
novos projetos. Além disso, eu também migrei vários outros projetos, include esse site/blog que você
está lendo nesse exato momento, conforme
<a href="https://www.lucascaton.com/2021/07/18/migrei-meu-site-para-nextjs">documentei aqui</a>.</p>
<p>Nesse tutorial, vamos desenvolver um blog com <a href="https://nextjs.org/"><strong>Next.js</strong></a>,
<a href="https://reactjs.org/"><strong>React</strong></a> e <a href="https://tailwindcss.com/"><strong>Tailwind CSS</strong></a>.
Os posts serão escritos em <strong>Markdown</strong> e convertidos para <strong>HTML</strong> no final.</p>
<p>E aí, bora codar? 😉</p>
<h2>Criando e configurando o projeto</h2>
<p>Antes de continuar, você precisa ter o
<a href="https://www.lucascaton.com/tags/nodejs">Node.js e o Yarn instalados</a>.</p>
<p>Abra o terminal e rode o seguinte comando para criar o projeto:</p>
<pre><code class="language-bash">yarn create next-app -e with-tailwindcss blog
</code></pre>
<p>Agora, acesse o diretório do projeto e adicione as bibliotecas que vamos precisar:</p>
<pre><code class="language-bash">cd blog
yarn add react-markdown gray-matter @tailwindcss/typography
</code></pre>
<p>Essas bibliotecas servem para:</p>
<ul>
<li><strong>React Markdown</strong>: converter Markdown para HTML.</li>
<li><strong>Gray Matter</strong>: interpretar <em>front matters</em> (veremos mais sobre isso a seguir).</li>
<li><strong>Plugin "typography" do Tailwind CSS</strong>: estilização básica decente para artigos/posts.</li>
</ul>
<h2>Escrevendo o post inicial</h2>
<p>Crie um diretório <code>posts</code> na raiz do projeto e dentro, crie um arquivo chamado <code>hello-world.md</code> com
o conteúdo que você desejar:</p>
<pre><code class="language-markdown">---
title: "Hello World"
date: "07/12/2021"
---
Olá mundo!
**Texto em negrito** e _texto em itálico_.
- Lista
- com
- vários
- items
</code></pre>
<h2>O que é "Front Matter"?</h2>
<p>O bloco no começo de arquivos markdowns, entre os traços (<code>---</code>) é o que chamamos de
<em>"Front Matter"</em> e é onde geralmente definimos metadados do post. Esse bloco precisa necessariamente
estar no começo do arquivo e precisa usar uma sintaxe YAML válida.</p>
<pre><code class="language-yml">title: "Hello World"
date: "07/12/2021"
</code></pre>
<h2>Preparando a página inicial</h2>
<p>Vamos mover o componente <code>&#x3C;Head></code> do arquivo <code>pages/index.js</code> para <code>pages/_app.js</code> e renomear o
conteúdo da tag <code>&#x3C;title></code>:</p>
<h3><code>pages/_app.js</code></h3>
<pre><code class="language-jsx">import Head from "next/head";
import "tailwindcss/tailwind.css";
function MyApp({ Component, pageProps }) {
  return (
    &#x3C;>
      &#x3C;Head>
        &#x3C;title>Meu blog&#x3C;/title>
        &#x3C;link rel="icon" href="https://www.lucascaton.com/favicon.ico" />
      &#x3C;/Head>
      &#x3C;Component {...pageProps} />
    &#x3C;/>
  );
}
export default MyApp;
</code></pre>
<p>Depois vamos deixar apenas um título <code>Posts</code> na página inicial:</p>
<h3><code>pages/index.js</code></h3>
<pre><code class="language-jsx">const Blog = () => {
  return &#x3C;h1>Posts&#x3C;/h1>;
};
export default Blog;
</code></pre>
<h2>Conferindo se está tudo bem até aqui</h2>
<p>Vamos rodar o servidor para ver se está tudo certo até agora. No terminal, rode:</p>
<pre><code class="language-bash">yarn dev
</code></pre>
<p>Abra o navegador e acesse <a href="http://localhost:3000/">localhost:3000</a>. Você deve ver algo assim:</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2021/12/blog1.png" alt="Versão inicial do blog" width="1200" height="814" /><figcaption>Versão inicial do blog</figcaption></figure></p>
<h2>Criando e estilizando o cabeçalho</h2>
<p>Vamos adicionar as tags <code>&#x3C;header></code> e <code>&#x3C;main></code> ao arquivo <code>pages/_app.js</code> com algumas classes do
Tailwind CSS:</p>
<pre><code class="language-diff"> import Head from "next/head";
+import Link from "next/link";
+
 import "tailwindcss/tailwind.css";
 function MyApp({ Component, pageProps }) {
@@ -9,7 +11,17 @@ function MyApp({ Component, pageProps }) {
         &#x3C;link rel="icon" href="https://www.lucascaton.com/favicon.ico" />
       &#x3C;/Head>
-      &#x3C;Component {...pageProps} />
+      &#x3C;header className="py-10 bg-gradient-to-r from-green-400 to-blue-500 text-center">
+        &#x3C;Link href="/">
+          &#x3C;a>
+            &#x3C;h2 className="text-5xl font-bold text-white">Meu blog&#x3C;/h2>
+          &#x3C;/a>
+        &#x3C;/Link>
+      &#x3C;/header>
+
+      &#x3C;main className="my-6 mx-auto p-6 bg-white sm:shadow-lg rounded prose lg:prose-xl">
+        &#x3C;Component {...pageProps} />
+      &#x3C;/main>
     &#x3C;/>
   );
 }
</code></pre>
<h2>Personalizando a tipografia do Tailwind CSS</h2>
<p>Vamos extender alguns comportamentos padrões de tipografia do Tailwind CSS e carregar o plugin
oficial <code>@tailwindcss/typography</code>.</p>
<p>Para isso, abra o arquivo <code>tailwind.config.js</code> e adicione isso:</p>
<pre><code class="language-diff">   darkMode: false, // or 'media' or 'class'
   theme: {
-    extend: {},
+    extend: {
+      typography: {
+        DEFAULT: {
+          css: {
+            a: {
+              color: "#3182ce",
+              "&#x26;:hover": {
+                color: "#2c5282",
+              },
+            },
+          },
+        },
+      },
+    },
   },
   variants: {
     extend: {},
   },
-  plugins: [],
+  plugins: [require("@tailwindcss/typography")],
 };
</code></pre>
<h2>Adicionando classes CSS na tag <code>&#x3C;body></code></h2>
<p>Para fazer isso, precisamos criar um arquivo <code>pages/_document.js</code> com o seguinte conteúdo:</p>
<pre><code class="language-jsx">import Document, { Html, Head, Main, NextScript } from "next/document";
class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }
  render() {
    return (
      &#x3C;Html>
        &#x3C;Head />
        &#x3C;body className="bg-white sm:bg-gray-50">
          &#x3C;Main />
          &#x3C;NextScript />
        &#x3C;/body>
      &#x3C;/Html>
    );
  }
}
export default MyDocument;
</code></pre>
<p>Repare que eu adicionei as classes <code>bg-white</code> e <code>sm:bg-gray-50</code> na tag <code>&#x3C;body></code>.</p>
<p><aside>Veja mais detalhes sobre <code>pages/_document.js</code> na <a href="https://nextjs.org/docs/advanced-features/custom-document">documentação oficial</a>.</aside></p>
<h2>Lendo o conteúdo dos posts</h2>
<p>Crie um arquivo <code>lib/posts.js</code> que será responsável por ler os arquivos Markdown e retornar uma
lista de posts:</p>
<pre><code class="language-js">import { promises as fs } from "fs";
import path from "path";
import matter from "gray-matter";
const getPosts = async () => {
  const postsDirectory = path.join(process.cwd(), "posts");
  const filenames = await fs.readdir(postsDirectory);
  return await Promise.all(
    filenames.map(async (filename) => {
      const filePath = path.join(postsDirectory, filename);
      const fileContents = await fs.readFile(filePath, "utf8");
      const document = matter(fileContents);
      return {
        slug: filename.replace(/\.md$/, ""),
        title: document.data.title,
        date: document.data.date,
        markdown: document.content,
      };
    })
  );
};
export default getPosts;
</code></pre>
<p>Cada post é representado por um objeto com as seguintes chaves:</p>
<ul>
<li><strong>slug</strong>: Representação do post que pode ser usada na URL. Para isso, vamos usar o nome do arquivo
sem sua extensão (<code>.md</code>).</li>
<li><strong>title</strong>: Metadado definido no <em>front matter</em></li>
<li><strong>date</strong>: Metadado definido no <em>front matter</em></li>
<li><strong>markdown</strong>: Conteúdo principal do arquivo Markdown</li>
</ul>
<p>Repare que estamos usando a biblioteca <code>gray-matter</code> para ler os metadados definidos no
<em>front matter</em> de cada post.</p>
<h2>Adicionando os posts à página inicial</h2>
<p>Vamos importar a função <code>getPosts</code> do arquivo que acabamos de criar na página inicial, ou seja, no
arquivo <code>pages/index.js</code> e fazer um <em>loop</em> para exibir links e títulos de cada um dos posts:</p>
<pre><code class="language-jsx">import Link from "next/link";
import getPosts from "../lib/posts";
const Blog = ({ posts }) => {
  return (
    &#x3C;>
      &#x3C;h1>Posts&#x3C;/h1>
      &#x3C;ul>
        {posts.map(({ slug, title }) => (
          &#x3C;li key={slug}>
            &#x3C;Link href={`/${slug}`}>
              &#x3C;a>{title}&#x3C;/a>
            &#x3C;/Link>
          &#x3C;/li>
        ))}
      &#x3C;/ul>
    &#x3C;/>
  );
};
export async function getStaticProps() {
  return {
    props: {
      posts: await getPosts(),
    },
  };
}
export default Blog;
</code></pre>
<p>Vamos ver no navegador como nosso blog está ficando:</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2021/12/blog2.png" alt="Lista de posts" width="1300" height="875" /><figcaption>Lista de posts</figcaption></figure></p>
<p>Massa!</p>
<h2>Criando as páginas dos posts com rotas dinâmicas</h2>
<p>Ao tentar clicar no link do post <em>Hello World</em> que vemos da página acima, um erro 404 (página não
encontrada) será mostrada. Isso é esperado, afinal, ainda não criamos essa página 🙃</p>
<p>Bora criá-la, então. Como queremos um mesmo <em>template</em> para os posts, mas com <strong>rotas dinâmicas</strong>
(baseadas no nome de seus arquivos), vamos criar e nomear o arquivo dos posts com colchetes:
<code>pages/[slug].js</code>.</p>
<p>Seu conteúdo pode ser algo mais ou menos assim:</p>
<pre><code class="language-jsx">import getPosts from "../lib/posts";
const Post = ({ title, date, markdown }) => (
  &#x3C;article>
    &#x3C;h1>{title}&#x3C;/h1>
    &#x3C;time className="font-extralight tracking-wider text-gray-500">{date}&#x3C;/time>
    {markdown}
  &#x3C;/article>
);
export const getStaticPaths = async () => {
  const posts = await getPosts();
  return {
    paths: posts.map((post) => `/${post.slug}`),
    fallback: false,
  };
};
export const getStaticProps = async ({ params: { slug } }) => {
  const posts = await getPosts();
  const post = posts.find((post) => post.slug === slug);
  return { props: post };
};
export default Post;
</code></pre>
<p>Agora vamos verificar como ficou no navegador...</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2021/12/blog3.png" alt="Página do post" width="1300" height="886" /><figcaption>Página do post</figcaption></figure></p>
<p>Ok, está ficando legal, mas ainda falta converter o Markdown.</p>
<h2>Convertendo o Markdown para HTML</h2>
<p>Vamos usar a bilioteca <code>ReactMarkdown</code> para fazer isso. Atualize o arquivo <code>pages/[slug].js</code> para:</p>
<pre><code class="language-diff">+import ReactMarkdown from "react-markdown";
+
 import getPosts from "../lib/posts";
 const Post = ({ title, date, markdown }) => (
   &#x3C;article>
     &#x3C;h1>{title}&#x3C;/h1>
     &#x3C;time className="font-extralight tracking-wider text-gray-500">{date}&#x3C;/time>
-    {markdown}
+    &#x3C;ReactMarkdown>{markdown}&#x3C;/ReactMarkdown>
   &#x3C;/article>
 );
</code></pre>
<p>Vamos testar novamente:</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2021/12/blog4.png" alt="Página do post com Markdown convertido" width="1300" height="1176" /><figcaption>Página do post com Markdown convertido</figcaption></figure></p>
<p>Ah, bem melhor!</p>
<h2>Adicionando um favicon</h2>
<p>Para finalizar, substitua o <em>favicon</em> da pasta <code>public/</code>.</p>
<p>Se você não tiver um, pode usar esse:</p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2021/12/favicon.ico" alt="undefined" width="48" height="48" /><figcaption></figcaption></figure></p>
<p>Fique a vontade também para remover o arquivo <code>public/vercel.svg</code>, que atualmente não tem utilidade nenhuma.</p>
<h2>Resultado final 🎉</h2>
<p><figure><img src="https://www.lucascaton.com/images/posts/2021/12/blog-com-nextjs.jpg" alt="Blog - versão final" width="1920" height="1080" /><figcaption>Blog - versão final</figcaption></figure></p>
<p><aside>Se quiser aprender tudo sobre React e Next.js, dê uma olhada no meu <a href="https://www.lucascaton.com/cursos/rdp">curso de React</a> 😉</aside></p>
<hr>
<h2>Vídeo que originou esse post</h2>
<p><a href="https://www.youtube.com/watch?v=PiWvZX9eLw8"><img src="https://i.ytimg.com/vi_webp/PiWvZX9eLw8/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Repositório no GitHub</h2>
<p>O código do blog desenvolvido nesse tutorial está
<a href="https://github.com/lucascaton/blog-em-1-minuto">publicado integralmente no GitHub</a>, caso você
precise por qualquer motivo! 😉</p>
<h2>O que achou?</h2>
<p>Me conte nos comentários abaixo!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="tutoriais" /><category term="react" /><category term="nextjs" />
    </entry>

    <entry>
      <title><![CDATA[RubyConf Brasil 2021 (online) com desconto de 25%]]></title>
      <summary><![CDATA[Desconto oferecido pela NewRiide.com (apoiadora do evento)]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2021/07/18/ruby-conf-brasil-online-2021-com-desconto-de-25?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2021-07-18T09:14:00.000Z</published>
      <updated>2021-07-18T09:14:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2021/07/18/ruby-conf-brasil-online-2021-com-desconto-de-25</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2021/07/18/ruby-conf-brasil-online-2021-com-desconto-de-25">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2021/07/ruby-conf-brasil-2021.jpg" alt="RubyConf Brasil 2021"></p>
<p>Nos dias 29 e 30 de julho acontecerá a
<a href="https://online.rubyconf.com.br/?utm_source=lucascaton.com/pt-BR">RubyConf Brasil 2021 - Online</a>.
Serão dois dias para você imergir no mundo da tecnologia que vai muito além da linguagem de
programação Ruby.</p>
<p>Estamos empenhados junto com a nossa parceira
<a href="https://newriide.com/?utm_source=lucascaton.com/pt-BR">NewRiide.com</a> em trazer as melhores
oportunidades para você ingressar e evoluir no mundo da tecnologia e desenvolvimento de software.</p>
<p>A <strong>NewRiide</strong> apoia o evento e negociou com a Locaweb um <strong>desconto de 25%</strong> na aquisição dos
ingressos para RubyConf, basta acessar o link abaixo para adquirir o seu ingresso já com desconto:</p>
<h3>👉 <a href="https://www.lucascaton.com/rubyconf">INGRESSO COM 25% DESCONTO</a></h3>
<p>Aproveite mais esta oportunidade para ingressar no mundo do desenvolvimento de software e ter
contato com desenvolvedores de diversas empresas renomadas que estão fazendo a diferença no mercado
de tecnologia!</p>
</div>]]>
      </content>
      <author><name>Mauricio de Amorim</name></author>
      <category term="ruby" /><category term="rubyconf" />
    </entry>

    <entry>
      <title><![CDATA[Migrei meu site para Next.js]]></title>
      <summary><![CDATA[Depois de usar WordPress, Enki e Jekyll, meu site finalmente está como eu quero e usando React!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2021/07/18/migrei-meu-site-para-nextjs?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2021-07-18T05:37:00.000Z</published>
      <updated>2021-07-18T05:37:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2021/07/18/migrei-meu-site-para-nextjs</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2021/07/18/migrei-meu-site-para-nextjs">
        <![CDATA[<div xml:lang="pt-BR"><p>Criei esse <a href="https://www.lucascaton.com/2009/07/14/primeiro-post">site/blog em 2009 usando Wordpress</a>. Depois migrei para
<a href="https://www.lucascaton.com/2011/05/19/porque-voltei-a-usar-o-wordpress">Enki mas acabei voltando para o Wordpress</a>.
Parece que foi ontem que <a href="https://www.lucascaton.com/2017/10/04/refiz-meu-blog-do-zero">refiz tudo do zero</a>, mas na
realidade foi em 2017, quando comecei a usar Jekyll para gerar um site estático pela primeira vez.</p>
<h2>Por que mudar novamente?</h2>
<p><strong>Jekyll</strong> me serviu bem, mas desde o ano passado eu notei que precisava de algo ainda mais
flexível e com melhor performance já que gerar o site (aka. processo de <em>build</em>) e também
renderizar páginas em ambiente de desenvolvimento estava deixando a desejar. Aproveitei
que estava estudando <strong>Next.js</strong> e decidi usá-lo no site novo para ganhar experiência na prática. A
migração foi bastante lenta, pois eu não tinha pressa e queria experimentar combinações de
bibliotecas e soluções diferentes, que vou detalhar mais na sessão "Stack" abaixo.</p>
<h2>Processo</h2>
<p>Em vez de reusar o mesmo repositório, criei um novinho em folha. Eis o primeiro commit, que
aconteceu há mais de um ano:</p>
<pre><code>commit 7fdcbe4
Author: Lucas Caton
Date:   Thu Jun 11 17:21:21 2020 +1000
    Initial commit from Create Next App
</code></pre>
<p>Depois de alguns meses, o site estava longe de estar finalizado, porém estava bom o suficiente.
Como eu sempre sigo a idéia de que
<a href="https://www.youtube.com/watch?v=LgejjWsu8MU">feito é melhor que perfeito</a>, decidi colocar no ar,
sem muito alarde. Só agora porém, meses depois, parei para escrever um post e contar essa história.</p>
<h2>O quanto "pronto" eu esperei para colocar no ar?</h2>
<p>Só nesse repositório novo, já foram 441 commits:</p>
<pre><code>❯ git shortlog -sn
   441  Lucas Caton
</code></pre>
<p>Mas ainda tem muitas coisas para arrumar. Você provavelmente vai encontrar algumas partes meio
feias, inacabadas ou até mesmo inexistes no site novo (não tem mais uma busca, por exemplo). Aos
poucos, eu farei melhorias incrementais para re-adicionar o que falta e/ou corrigir o que precisa.</p>
<h2>Valeu a pena?</h2>
<p>Tudo saiu melhor que o planejado e talvez eu escreva posts separados no futuro para contar os vários
motivos. De forma resumida, a flexibilidade e performance que o Next.js e o React têm, mudaram o
jogo para mim. Falando nisso, deixa eu contar quais bibliotecas e ferramentas exatamente que o site
novo está usando:</p>
<h2>Stack</h2>
<ul>
<li><strong>React.js</strong> (<a href="https://reactjs.org/">https://reactjs.org/</a>) &#x26; <strong>Next.js</strong> (<a href="https://nextjs.org/">https://nextjs.org/</a>).
<ul>
<li>Aproveite para conhecer <a href="https://www.lucascaton.com/cursos/rdp">meu curso</a>! 😉</li>
</ul>
</li>
<li><strong>Posts em Markdown</strong> - um dos pré-requisitos que eu mesmo defini é que eu não queria mudar
absolutamente nada nos arquivos dos posts. Até mesmo o
<a href="https://jekyllrb.com/docs/front-matter/"><em>front matter</em></a> eu mantive o mesmo que usava com Jekyll.
Só que agora são as bibliotecas <a href="https://github.com/remarkjs/react-markdown"><code>react-markdown</code></a> e
<a href="https://github.com/jonschlinkert/gray-matter"><code>gray-matter</code></a> que convertem tudo.</li>
<li><strong>TailwindCSS</strong> (<a href="https://tailwindcss.com/">https://tailwindcss.com/</a>) - eu tenho usado esse framework CSS na maioria dos meus
projetos e continuo achando ele sensacional. Se você não conhece, vale a pena dar uma olhada no
<a href="https://www.youtube.com/c/TailwindLabs">canal deles no YouTube</a>. Veja mais detalhes na sessão
"Layout próprio" abaixo.</li>
<li><strong>Styled components</strong> - <a href="https://styled-components.com/">https://styled-components.com/</a>.</li>
<li><strong>TypeScript</strong> (<a href="https://www.typescriptlang.org/">https://www.typescriptlang.org/</a>) &#x26;
TypeScript Coverage Report (<a href="https://github.com/alexcanessa/typescript-coverage-report">https://github.com/alexcanessa/typescript-coverage-report</a>).</li>
<li><strong>React Highlight</strong> (<a href="https://react-highlight.neostack.com/">https://react-highlight.neostack.com/</a>) - suporte para <em>syntax highlighting</em>
em aplicações React.</li>
<li><strong>Disqus</strong> (<a href="https://disqus.com/">https://disqus.com/</a>) - já usava antes e continuo usando esse serviço para permitir
comentários nos posts.</li>
<li><strong>ES Lint</strong> (<a href="https://eslint.org/">https://eslint.org/</a>) &#x26; <strong>Prettier</strong> (<a href="https://prettier.io/">https://prettier.io/</a>) - para manter os estilos
e qualidade do código.</li>
<li><strong>Jest</strong> - <a href="https://jestjs.io/">https://jestjs.io/</a>.</li>
</ul>
<h2>Mudei do GitHub Pages para a Vercel</h2>
<p>Migrei para a <a href="https://vercel.com/">Vercel</a> por 3 motivos:</p>
<ul>
<li>Melhor integração com o Next.js</li>
<li>Deploys mais simples</li>
<li>Plano gratuito bastante generoso</li>
</ul>
<h2>O que eu NÃO estou usando</h2>
<ul>
<li>Biblioteca com componentes prontos, exemplo: Bootstrap, Bulma, etc.</li>
<li>Pré-processador CSS, exemplo: SASS, SCSS, Slim, nem nenhum outro. Apenas Tailwind e CSS puro.</li>
</ul>
<h2>Layout próprio</h2>
<p>Eu criei a <em>UI</em> de todas as páginas, menus, componentes, etc. Em todas as versões anteriores, eu
usava <em>templates</em> prontos, mas resolvi eu mesmo criar um dessa vez. Ainda estou
atualizando/melhorando várias partes que precisam de um pouco mais de amor :)</p>
<p><img src="/images/posts/2021/07/site-2021.jpg" alt="Screenshot do site novo criado em 2021"></p>
<h2>Feedback</h2>
<p>Para concluir, eu adoraria saber o que você achou do site novo. Me conte nos comentários abaixo! 😉</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="site" /><category term="blog" /><category term="react" /><category term="nextjs" />
    </entry>

    <entry>
      <title><![CDATA[Webinário: Por que aprender a programar?]]></title>
      <summary><![CDATA[Você provavelmente já ouviu falar que é importante, mas você sabe o motivo?]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2021/07/16/webinario-por-que-aprender-a-programar?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2021-07-16T10:00:00.000Z</published>
      <updated>2021-07-16T10:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2021/07/16/webinario-por-que-aprender-a-programar</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2021/07/16/webinario-por-que-aprender-a-programar">
        <![CDATA[<div xml:lang="pt-BR"><p>Webinário apresentado em <strong>30/01/2019</strong>.</p>
<p><a href="https://www.youtube.com/watch?v=DSfdEFZ6Fwo"><img src="https://i.ytimg.com/vi_webp/DSfdEFZ6Fwo/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<p><aside>Aproveite para se inscrever para se inscrever no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="webinarios" />
    </entry>

    <entry>
      <title><![CDATA[Webinário: 10 lições para ser um excelente desenvolvedor]]></title>
      <summary><![CDATA[Como evitar armadilhas, a relevância de projetos open-source, o que estudar sem perder tempo com o que não é necessário, entre outras coisas.]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2021/07/13/webinario-10-licoes-para-ser-um-excelente-desenvolvedor?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2021-07-13T09:00:00.000Z</published>
      <updated>2021-07-13T09:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2021/07/13/webinario-10-licoes-para-ser-um-excelente-desenvolvedor</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2021/07/13/webinario-10-licoes-para-ser-um-excelente-desenvolvedor">
        <![CDATA[<div xml:lang="pt-BR"><p>Webinário apresentado em <strong>06/07/2018</strong>.</p>
<p><a href="https://www.youtube.com/watch?v=TqIlK4pyX20"><img src="https://i.ytimg.com/vi_webp/TqIlK4pyX20/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<p><aside>Aproveite para se inscrever para se inscrever no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="webinarios" />
    </entry>

    <entry>
      <title><![CDATA[Webinário: Como trabalhar como programador no exterior]]></title>
      <summary><![CDATA[10 dicas baseadas no que acertei e no que errei para conseguir meu visto de trabalho]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2021/07/04/webinario-como-trabalhar-como-programador-no-exterior?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2021-07-04T00:00:00.000Z</published>
      <updated>2021-07-04T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2021/07/04/webinario-como-trabalhar-como-programador-no-exterior</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2021/07/04/webinario-como-trabalhar-como-programador-no-exterior">
        <![CDATA[<div xml:lang="pt-BR"><p>Webinário apresentado em <strong>20/12/2017</strong>.</p>
<p><a href="https://www.youtube.com/watch?v=xnydQGlpO9M"><img src="https://i.ytimg.com/vi_webp/xnydQGlpO9M/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<p><aside>Aproveite para se inscrever para se inscrever no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="webinarios" />
    </entry>

    <entry>
      <title><![CDATA[Podcast: entrevistando Cássio Marques]]></title>
      <summary><![CDATA[Programador, Audiófilo, Escalador e meu mentor técnico]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/04/04/podcast-entrevistando-cassio-marques?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-04-04T00:18:07.000Z</published>
      <updated>2020-04-04T00:18:07.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/04/04/podcast-entrevistando-cassio-marques</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/04/04/podcast-entrevistando-cassio-marques">
        <![CDATA[<div xml:lang="pt-BR"><p>Seguindo com a
<a href="https://www.lucascaton.com/2020/02/19/segunda-temporada-do-podcast">2ª temporada do meu podcast</a>, dessa
vez o entrevistado foi o <strong>Cássio Marques</strong>, que é programador, amante de música, mora na Inglaterra e
foi o meu mentor técnico, a pessoa que me apresentou boas práticas de programação e quem me mostrou
o "caminho das pedras" de uma carreira de sucesso na área.</p>
<p>Assista a entrevista completa no YouTube:</p>
<p><a href="https://www.youtube.com/watch?v=t7wA6Jx7ScE"><img src="https://i.ytimg.com/vi_webp/t7wA6Jx7ScE/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Você também pode escutar a entrevista através do seu player de podcast
preferido; é só buscar por <code>Lucas Caton</code> no app de podcast ou conferir o link direto
<a href="https://www.lucascaton.com/podcast/">nessa página</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="podcast" /><category term="entrevista" />
    </entry>

    <entry>
      <title><![CDATA[Podcast: entrevistando Tiago Menegaz]]></title>
      <summary><![CDATA[Rubysta, Dockeiro, estudou na Austrália e trampa para empresa gringa]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/03/19/podcast-entrevistando-tiago-menegaz?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-03-19T07:39:04.000Z</published>
      <updated>2020-03-19T07:39:04.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/03/19/podcast-entrevistando-tiago-menegaz</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/03/19/podcast-entrevistando-tiago-menegaz">
        <![CDATA[<div xml:lang="pt-BR"><p>Seguindo com a
<a href="https://www.lucascaton.com/2020/02/19/segunda-temporada-do-podcast">2ª temporada do meu podcast</a>, dessa
vez o entrevistado foi <strong>Tiago Menegaz</strong>, que é programador Ruby, curte/manja de Docker e Kubernetes,
morou e estudou na Austrália e atualmente trabalha para uma startup americana!</p>
<p>Assista a entrevista completa no YouTube:</p>
<p><a href="https://www.youtube.com/watch?v=I5MMlaEpRQU"><img src="https://i.ytimg.com/vi_webp/I5MMlaEpRQU/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Você também pode escutar a entrevista através do seu player de podcast
preferido; é só buscar por <code>Lucas Caton</code> no app de podcast ou conferir o link direto
<a href="https://www.lucascaton.com/podcast/">nessa página</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="podcast" /><category term="entrevista" />
    </entry>

    <entry>
      <title><![CDATA[Instalação do Ruby e do Node.js no macOS, usando ASDF]]></title>
      <summary><![CDATA[O passo-a-passo completo]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/02/26/instalacao-do-ruby-do-nodejs-no-macos-usando-asdf?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-02-26T12:00:00.000Z</published>
      <updated>2025-03-11T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/02/26/instalacao-do-ruby-do-nodejs-no-macos-usando-asdf</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/02/26/instalacao-do-ruby-do-nodejs-no-macos-usando-asdf">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=cXNyQDDDXbg"><img src="https://i.ytimg.com/vi_webp/cXNyQDDDXbg/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<p>Abaixo você encontra os comandos executados no vídeo:</p>
<p>Site do Homebrew: <a href="https://brew.sh/">https://brew.sh/</a></p>
<pre><code class="language-bash">/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
</code></pre>
<p>Site do ASDF: <a href="https://asdf-vm.com/">https://asdf-vm.com/</a></p>
<pre><code class="language-bash">brew install asdf
echo -e "\n. $(brew --prefix asdf)/asdf.sh" >> ~/.zshrc
source ~/.zshrc
asdf --version
</code></pre>
<p>Site do Ruby: <a href="https://www.ruby-lang.org/pt/">https://www.ruby-lang.org/pt/</a></p>
<pre><code class="language-bash">asdf plugin-add ruby
asdf install ruby 3.4.2
asdf global ruby 3.4.2
ruby -v
</code></pre>
<p>Site do Node.js: <a href="https://nodejs.org/pt-br/">https://nodejs.org/pt-br/</a></p>
<pre><code class="language-bash">asdf plugin-add nodejs
asdf install nodejs 22.14.0
asdf global nodejs 22.14.0
node -v
</code></pre>
<p>Site do Rails: <a href="https://rubyonrails.org/">https://rubyonrails.org/</a></p>
<pre><code class="language-bash">gem install rails
rails -v
</code></pre>
<p>Site do Yarn: <a href="https://yarnpkg.com/">https://yarnpkg.com/</a></p>
<pre><code class="language-bash">npm install --global yarn
yarn -v
</code></pre>
<h3>Criando um projeto Rails para garantir que tudo está funcionando:</h3>
<pre><code class="language-bash">rails new todo
cd todo
rails s
</code></pre>
<p>Abra o navegador e acesse a página <a href="http://localhost:3000">localhost:3000</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="macOS" /><category term="asdf" /><category term="ruby" /><category term="nodejs" /><category term="rails" /><category term="yarn" />
    </entry>

    <entry>
      <title><![CDATA[Podcast: entrevistando Fabio Akita]]></title>
      <summary><![CDATA[Um profissional foda que admiro muito e que dispensa apresentações]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/02/24/podcast-entrevistando-fabio-akita?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-02-23T20:25:44.000Z</published>
      <updated>2020-02-23T20:25:44.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/02/24/podcast-entrevistando-fabio-akita</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/02/24/podcast-entrevistando-fabio-akita">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2020/02/fabio-akita.jpg" alt="Fabio Akita"></p>
<p>Seguindo com a
<a href="https://www.lucascaton.com/2020/02/19/segunda-temporada-do-podcast">2ª temporada do meu podcast</a>, dessa
vez o entrevistado foi <strong>Fabio Akita</strong>, um amigo de longa data e um profissional que admiro muito.</p>
<p>Assista a entrevista completa no YouTube:</p>
<p><a href="https://www.youtube.com/watch?v=ZhrN6BDI9QQ"><img src="https://i.ytimg.com/vi_webp/ZhrN6BDI9QQ/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Você também pode escutar a entrevista através do seu player de podcast
preferido; é só buscar por <code>Lucas Caton</code> no app de podcast ou conferir o link direto
<a href="https://www.lucascaton.com/podcast/">nessa página</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="podcast" /><category term="entrevista" />
    </entry>

    <entry>
      <title><![CDATA[Segunda temporada do Podcast!]]></title>
      <summary><![CDATA[Os 5 primeiros episódios já estão no ar]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/02/19/segunda-temporada-do-podcast?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-02-18T21:10:07.000Z</published>
      <updated>2020-02-18T21:10:07.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/02/19/segunda-temporada-do-podcast</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/02/19/segunda-temporada-do-podcast">
        <![CDATA[<div xml:lang="pt-BR"><p>Fala meus caros! 👋</p>
<p>No começo desse ano (também conhecido como "mês passado"), eu estreei a 2ª temporada do
<a href="https://www.lucascaton.com/podcast/">meu podcast</a>, no qual estou entrevistando profissionais que
trabalham com tecnologia (a maioria programadores) que eu admiro.</p>
<p>Toda quinta-feira tem um episódio novo, com insights de quem está no "campo de batalha", trabalhando
na área.</p>
<p>Os 5 primeiros episódios já estão no ar e você pode escutar através do seu player de podcast
preferido; é só buscar por <code>Lucas Caton</code> no app de podcast ou conferir o link direto
<a href="https://www.lucascaton.com/podcast/">nessa página</a>.</p>
<p>Se preferir, você também pode assistir pelo YouTube:</p>
<h3>Episódio 01 - WILL ROSA</h3>
<blockquote>
<p>CURIOSO, AUTODIDATA, COMPARTILHADOR DE CONTEÚDO E LEITOR DE MANUAIS</p>
</blockquote>
<p><a href="https://www.youtube.com/watch?v=zUgCtc71hEA"><img src="https://i.ytimg.com/vi_webp/zUgCtc71hEA/maxresdefault.webp" alt="YouTube video" /></a></p>
<h3>Episódio 02 - THIAGO ALESSIO</h3>
<blockquote>
<p>PROGRAMADOR (INCLUSIVE DE ATARI), SYSADMIN E QUASE ALEMÃO</p>
</blockquote>
<p><a href="https://www.youtube.com/watch?v=7fiL8g0GKpU"><img src="https://i.ytimg.com/vi_webp/7fiL8g0GKpU/maxresdefault.webp" alt="YouTube video" /></a></p>
<h3>Episódio 03 - VAL SILVA</h3>
<blockquote>
<p>ANALISTA DE SISTEMAS, GUITARRISTA, DOUTORANDO EM COMPUTAÇÃO E HUMILDÃO</p>
</blockquote>
<p><a href="https://www.youtube.com/watch?v=0p_4PdDMmDA"><img src="https://i.ytimg.com/vi_webp/0p_4PdDMmDA/maxresdefault.webp" alt="YouTube video" /></a></p>
<h3>Episódio 04 - FERNANDO SOUSA</h3>
<blockquote>
<p>EMPREENDEDOR, RANGER E DESENVOLVEDOR DESDE OS 10 ANOS</p>
</blockquote>
<p><a href="https://www.youtube.com/watch?v=8BhTe_zAoE4"><img src="https://i.ytimg.com/vi_webp/8BhTe_zAoE4/maxresdefault.webp" alt="YouTube video" /></a></p>
<h3>Episódio 05 - MAURICIO DE AMORIM</h3>
<blockquote>
<p>ESTAGIÁRIO AOS 36, CORREDOR, EMPATIA MAN, O CARA DOS BASTIDORES</p>
</blockquote>
<p><a href="https://www.youtube.com/watch?v=nGouhyeNMTo"><img src="https://i.ytimg.com/vi_webp/nGouhyeNMTo/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>E é só o começo, toda semana tem episódio novo! 😉</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="podcast" /><category term="entrevista" />
    </entry>

    <entry>
      <title><![CDATA[Instalação do Ruby e do Node.js no Ubuntu Linux, usando ASDF]]></title>
      <summary><![CDATA[O passo-a-passo completo]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/02/17/instalacao-do-ruby-do-nodejs-no-ubuntu-linux-usando-asdf?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-02-17T10:19:24.000Z</published>
      <updated>2025-03-11T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/02/17/instalacao-do-ruby-do-nodejs-no-ubuntu-linux-usando-asdf</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/02/17/instalacao-do-ruby-do-nodejs-no-ubuntu-linux-usando-asdf">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=xGINzo4iQdE"><img src="https://i.ytimg.com/vi_webp/xGINzo4iQdE/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<p>Abaixo você encontra os comandos executados no vídeo:</p>
<pre><code class="language-bash">sudo apt update
sudo apt install build-essential git automake autoconf libreadline-dev libncurses-dev libssl-dev libyaml-dev libxslt-dev libffi-dev libtool unixodbc-dev unzip curl zlib1g-dev sqlite3 libsqlite3-dev
</code></pre>
<p>Site do ASDF: <a href="https://asdf-vm.com/">https://asdf-vm.com/</a></p>
<pre><code class="language-bash">git clone https://github.com/asdf-vm/asdf.git ~/.asdf
cd ~/.asdf
git checkout "$(git describe --abbrev=0 --tags)"
echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
source ~/.bashrc
asdf --version
</code></pre>
<p>Site do Ruby: <a href="https://www.ruby-lang.org/pt/">https://www.ruby-lang.org/pt/</a></p>
<pre><code class="language-bash">asdf plugin-add ruby
asdf install ruby 3.4.2
asdf global ruby 3.4.2
ruby -v
</code></pre>
<p>Site do Node.js: <a href="https://nodejs.org/pt-br/">https://nodejs.org/pt-br/</a></p>
<pre><code class="language-bash">asdf plugin-add nodejs
asdf install nodejs 22.14.0
asdf global nodejs 22.14.0
node -v
</code></pre>
<p>Site do Rails: <a href="https://rubyonrails.org/">https://rubyonrails.org/</a></p>
<pre><code class="language-bash">gem install rails
rails -v
</code></pre>
<p>Site do Yarn: <a href="https://yarnpkg.com/">https://yarnpkg.com/</a></p>
<pre><code class="language-bash">npm install --global yarn
yarn -v
</code></pre>
<h3>Criando um projeto Rails para garantir que tudo está funcionando:</h3>
<pre><code class="language-bash">rails new todo
cd todo
rails s
</code></pre>
<p>Abra o navegador e acesse a página <a href="http://localhost:3000">localhost:3000</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="linux" /><category term="ubuntu" /><category term="asdf" /><category term="ruby" /><category term="nodejs" /><category term="rails" /><category term="yarn" />
    </entry>

    <entry>
      <title><![CDATA[Frameworks do Rails]]></title>
      <summary><![CDATA[Entenda o que é e como funciona o Action Mailbox, Action Text, Active Job, Active Storage, Action Cable, etc.]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/02/12/frameworks-do-rails?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-02-11T21:00:00.000Z</published>
      <updated>2020-02-11T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/02/12/frameworks-do-rails</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/02/12/frameworks-do-rails">
        <![CDATA[<div xml:lang="pt-BR"><p>Nesse vídeo, eu vou destrinchar a teoria por traz dos frameworks/componentes
do Rails na prática, com exemplos e tudo mais! 😉</p>
<p>Entenda o que é e como funciona o <code>Active Record</code>, <code>Action View</code>,
<code>Action Controller</code>, <code>Active Support</code>, <code>Action Mailer</code>, <code>Action Mailbox</code>,
<code>Action Text</code>, <code>Active Job</code>, <code>Active Storage</code>, <code>Action Cable</code>, etc.</p>
<p>Com esses conceitos fica mais fácil compreender como as coisas se encaixam para
explorar novas soluções para suas aplicações.</p>
<p><a href="https://www.youtube.com/watch?v=AUTpTFp11Io"><img src="https://i.ytimg.com/vi_webp/AUTpTFp11Io/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Se curtir, não deixe de
<a href="https://www.youtube.com/lucascaton?sub_confirmation=1">se inscrever no canal</a>! 😉</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" />
    </entry>

    <entry>
      <title><![CDATA[Instalação do Ruby e do Node.js no Windows, usando WSL e ASDF]]></title>
      <summary><![CDATA[O passo-a-passo completo]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/02/03/instalacao-do-ruby-do-nodejs-no-windows-usando-wsl-e-asdf?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-02-03T09:30:28.000Z</published>
      <updated>2025-03-11T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/02/03/instalacao-do-ruby-do-nodejs-no-windows-usando-wsl-e-asdf</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/02/03/instalacao-do-ruby-do-nodejs-no-windows-usando-wsl-e-asdf">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=2zw2VkJFaN4"><img src="https://i.ytimg.com/vi_webp/2zw2VkJFaN4/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Abaixo você encontra os comandos executados no vídeo:</p>
<h3>No PowerShell:</h3>
<pre><code class="language-powershell">Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
</code></pre>
<h3>No terminal do Ubuntu (WSL):</h3>
<pre><code class="language-bash">sudo apt update
sudo apt install build-essential git automake autoconf libreadline-dev libncurses-dev libssl-dev libyaml-dev libxslt-dev libffi-dev libtool unixodbc-dev unzip curl zlib1g-dev sqlite3 libsqlite3-dev
</code></pre>
<pre><code class="language-bash">git clone https://github.com/asdf-vm/asdf.git ~/.asdf
cd ~/.asdf
git checkout "$(git describe --abbrev=0 --tags)"
echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
source ~/.bashrc
asdf --version
</code></pre>
<pre><code class="language-bash">asdf plugin-add ruby
asdf install ruby 3.4.2
asdf global ruby 3.4.2
ruby -v
</code></pre>
<pre><code class="language-bash">asdf plugin-add nodejs
asdf install nodejs 22.14.0
asdf global nodejs 22.14.0
node -v
</code></pre>
<pre><code class="language-bash">gem install rails
rails -v
</code></pre>
<pre><code class="language-bash">npm install --global yarn
yarn -v
</code></pre>
<h3>Criando um projeto Rails para garantir que tudo está funcionando:</h3>
<pre><code class="language-bash">rails new todo
cd todo
rails s
</code></pre>
<p>Abra o navegador e acesse a página <a href="http://localhost:3000">localhost:3000</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="windows" /><category term="wls" /><category term="asdf" /><category term="ruby" /><category term="nodejs" /><category term="rails" /><category term="yarn" />
    </entry>

    <entry>
      <title><![CDATA[Vale a pena aprender Ruby on Rails em 2020?]]></title>
      <summary><![CDATA[Uma análise semi-imparcial com os prós e contras]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/01/23/vale-a-pena-aprender-ruby-on-rails-em-2020?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-01-22T22:17:52.000Z</published>
      <updated>2020-01-22T22:17:52.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/01/23/vale-a-pena-aprender-ruby-on-rails-em-2020</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/01/23/vale-a-pena-aprender-ruby-on-rails-em-2020">
        <![CDATA[<div xml:lang="pt-BR"><p>Esta é uma das perguntas que mais recebo. Para criar um contexto e responder da
melhor forma, gravei e publiquei um vídeo no meu
<a href="https://www.youtube.com/lucascaton?sub_confirmation=1">canal do YouTube</a>:</p>
<p><a href="https://www.youtube.com/watch?v=4UGCkUV2zCc"><img src="https://i.ytimg.com/vi_webp/4UGCkUV2zCc/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Se curtir, não deixe de
<a href="https://www.youtube.com/lucascaton?sub_confirmation=1">se inscrever no canal</a>! 😉</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Introdução ao JavaScript (JS) em 30 minutos]]></title>
      <summary><![CDATA[Variáveis, tipos, manipulação de DOM, requisições assíncronas (AJAX) e mais]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/01/19/video-introducao-a-javascript-js-em-30-minutos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-01-19T09:35:33.000Z</published>
      <updated>2020-01-19T09:35:33.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/01/19/video-introducao-a-javascript-js-em-30-minutos</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/01/19/video-introducao-a-javascript-js-em-30-minutos">
        <![CDATA[<div xml:lang="pt-BR"><p>Aprenda o básico de JavaScript (JS) através do mais recente vídeo que publiquei no meu
<a href="https://www.youtube.com/lucascaton?sub_confirmation=1">canal do YouTube</a>:</p>
<p><a href="https://www.youtube.com/watch?v=wUA5mkosxmU"><img src="https://i.ytimg.com/vi_webp/wUA5mkosxmU/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<p>Abaixo você encontra os arquivos criados/utilizados no vídeo:</p>
<h3><code>index.html</code></h3>
<pre><code class="language-html">&#x3C;!DOCTYPE html>
&#x3C;html lang="en">
  &#x3C;head>
    &#x3C;meta charset="UTF-8">
    &#x3C;meta name="viewport" content="width=device-width, initial-scale=1.0">
    &#x3C;meta http-equiv="X-UA-Compatible" content="ie=edge">
    &#x3C;title>Introdução à JS&#x3C;/title>
    &#x3C;link rel="stylesheet" href="css/style.css">
  &#x3C;/head>
  &#x3C;body>
    &#x3C;main>
      &#x3C;nav>
        [Alterar tema](#" id="theme-toggle)
      &#x3C;/nav>
      &#x3C;article>
        &#x3C;h1>The Matrix&#x3C;/h1>
        &#x3C;h2>Cast&#x3C;/h2>
        &#x3C;ul class='cast'>&#x3C;/ul>
        &#x3C;p>
          The Matrix is a 1999 science fiction action film[3][4] written and directed by the Wachowskis.[a] It stars Keanu Reeves, Laurence Fishburne, Carrie-Anne Moss, Hugo Weaving, and Joe Pantoliano and is the first installment in the Matrix franchise. It depicts a dystopian future in which humanity is unknowingly trapped inside a simulated reality, the Matrix, created by intelligent machines to distract humans while using their bodies as an energy source.[5] When computer programmer Thomas Anderson, under the hacker alias "Neo", uncovers the truth, he "is drawn into a rebellion against the machines"[5] along with other people who have been freed from the Matrix.
        &#x3C;/p>
        &#x3C;p>
          The Matrix is an example of the cyberpunk subgenre of science fiction.[6] The Wachowskis' approach to action scenes was influenced by Japanese animation[7] and martial arts films, and the film's use of fight choreographers and wire fu techniques from Hong Kong action cinema influenced subsequent Hollywood action film productions. The film is known for popularizing a visual effect known as "bullet time", where the heightened perception of certain characters is represented by allowing the action within a shot to progress in slow-motion while the camera appears to move through the scene at normal speed, allowing the sped-up movements of certain characters to be perceived normally. While some critics have praised the film for its handling of difficult subjects, others have said the deeper themes are largely overshadowed by its action scenes.
        &#x3C;/p>
      &#x3C;/article>
    &#x3C;/main>
    &#x3C;script src="js/app.js">&#x3C;/script>
  &#x3C;/body>
&#x3C;/html>
</code></pre>
<h3><code>css/style.css</code></h3>
<pre><code class="language-css">* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  background-color: #f5f5f5;
}
main {
  max-width: 500px;
  min-height: 100vh;
  margin: auto;
  padding: 1rem 2rem;
  font-family: sans-serif;
  background-color: white;
  color: #333;
}
article h1 {
  margin: 1rem 0;
  font-size: 3rem;
}
article p {
  font-size: 1.4rem;
  margin: 2rem 0;
}
nav {
  display: flex;
  flex-direction: row-reverse;
}
#theme-toggle {
  text-decoration: none;
  padding: 0.25rem 0.5rem;
  border-radius: 5px;
  background-color: #eee;
  color: #333;
}
ul {
  margin: 1rem 0 0 3rem;
}
/* Dark theme */
body.dark {
  background-color: #222;
}
body.dark main {
  background-color: #444;
  color: #eee;
}
body.dark #theme-toggle {
  background-color: #777;
  color: #ddd;
}
</code></pre>
<h3><code>js/app.js</code></h3>
<pre><code class="language-javascript">document.querySelector('#theme-toggle').addEventListener('click', (event) => {
  event.preventDefault();
  toggleTheme();
});
function toggleTheme() {
  document.body.classList.toggle('dark');
}
</code></pre>
<pre><code class="language-javascript">const cast = [
  'Keanu Reeves',
  'Carrie-Anne Moss',
  'Laurence Fishburne',
  'Hugo Weaving'
];
const castList = document.querySelector('.cast');
cast.forEach(person => {
  const item = document.createElement("li");
  const personName = document.createTextNode(person);
  item.appendChild(personName);
  castList.appendChild(item);
  // P.S. Existem formas melhores de fazer ↑ isso,
  // usando um framework tipo React por exemplo :)
});
</code></pre>
<pre><code class="language-javascript">document.querySelector('main').innerHTML = '';
fetch('https://api.github.com/users/lucascaton/repos?per_page=100')
  .then(response => response.json())
  .then(repos => repos.forEach(repo => {
    let item = document.createElement("li");
    var repoName = document.createTextNode(repo.name);
    item.appendChild(repoName);
    document.querySelector('main').appendChild(item);
  }));
</code></pre>
<p><aside>Se curtiu o vídeo, não deixe de <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">se inscrever no canal</a>! 😉</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="javascript" /><category term="es6" />
    </entry>

    <entry>
      <title><![CDATA[Conselhos para 2020]]></title>
      <summary><![CDATA[Alguns "tapas na cara" que você pode estar precisando.]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/01/07/conselhos-para-2020?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-01-07T10:52:08.000Z</published>
      <updated>2020-01-07T10:52:08.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/01/07/conselhos-para-2020</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/01/07/conselhos-para-2020">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2020/01/conselhos-para-2020.jpg" alt="Pessoa pensativa usando um laptop"></p>
<p>Escrevi abaixo alguns conselhos para te fazer pensar em como você quer levar sua vida profissional
nesse ano que acabou de começar.
Em vários trechos, eu "linkei" artigos, vídeos ou referências relevantes.</p>
<p>Se te incomodar o tom "tapa na cara" do post, fique tranquilo, não é nada pessoal.
Mas é para te ajudar a acordar se você estiver precisando :)</p>
<h2>1. Faça o seu perfil do GitHub ficar animal</h2>
<p><strong>Crie projetos</strong> e os deixe públicos. Contribua com projetos open-source, nem que seja
<a href="https://github.com/zilverline/sequent/pull/213">só atualizando a documentação</a>.
Empresas gostam de perfis interessantes e atualmente isso conta mais que CV.
<a href="https://www.lucascaton.com/2017/10/21/por-que-voce-deveria-ter-um-blog">Escrever sobre tecnologia</a>
também ajuda!</p>
<h2>2. Defina o seu propósito maior</h2>
<p><a href="https://www.youtube.com/watch?v=-Q-Y-4a2QNo">Reflita sua motivação</a>
para quer chegar onde você planeja chegar. E não deixe de
<a href="https://www.youtube.com/watch?v=xZcwB_cVtrI">ser consistente</a>!</p>
<h2>3. Pare de jogar ou assistir coisas inúteis</h2>
<p>PS4, Netflix e Porta dos Fundos são ótimos, mas estão cagando para o seu futuro.
<strong>A única pessoa que realmente se importa contigo é você mesmo</strong>.</p>
<h2>4. Crie um projeto pessoal para ser o seu playground</h2>
<p>Não pense em ganhar dinheiro com ele. Comece com
<a href="https://www.lucascaton.com/2018/02/11/criando-sua-primeira-pagina-web-em-30-minutos-basico-sobre-html-e-css">algo básico</a>
se você for iniciante, mas saiba
<a href="https://www.lucascaton.com/2019/02/03/guia-desenvolvedor-web-2019">dar o próximo passo</a>
para não ficar parado no tempo. Teste tecnologias diferentes.
Envolva back-end e front-end. Crie uma API e um app mobile (ou uma PWA) para consumi-la.
<strong>Identifique no que você é bom e no que precisa melhorar</strong>!</p>
<h2>5. Pare de reclamar que não tem tempo</h2>
<p>O tempo é igual para todos. A diferença é a prioridade que damos para as coisas.
Manter-se ocupado não é ser produtivo.
<a href="https://pca.st/p2643nwe">Aprenda a dizer <strong>não</strong></a>!
<strong>Libere sua agenda</strong>, em vez de lotar com coisas que não são importantes.
Algo que também pode ajudar com isso é começar a
<a href="https://www.lucascaton.com/2018/03/27/os-desafios-de-trabalhar-remotamente">trabalhar remotamente</a>!</p>
<h2>6. Faça entrevistas de emprego</h2>
<p>Só assim você conseguirá o seu
<a href="https://www.youtube.com/watch?v=LwbVFhaRuXw">primeiro emprego na área de tecnologia</a>.
Corra atrás de <a href="https://www.youtube.com/watch?v=2GaDY7W0U2c">trabalhar com o que você quer</a>.
Não espere uma empresa te convidar para trabalhar lá, isso não vai acontecer do nada.
<a href="https://www.youtube.com/watch?v=JqFIqEK3G1c">Você <strong>não</strong> é iniciante demais</a>.
Você <strong>não</strong> é velho demais. Você <strong>não</strong> é diferente de ninguém. <strong>Chega de desculpas!</strong></p>
<blockquote>
<p>O melhor dia para fazer isso é um ano atrás. O segundo melhor é hoje.</p>
</blockquote>
<p>Depois que conseguir,
<a href="https://www.lucascaton.com/2018/05/17/3-atitudes-para-ser-feliz-no-trabalho">dê o seu melhor</a>!</p>
<h2>7. Saia do Facebook</h2>
<p>Não precisa deletar sua conta ou o app, só <strong>pare de abrir a cada 30 minutos</strong>,
porque quase nada que está lá vai te levar para o seu próximo nível.</p>
<p>Dica: troque o tempo gasto lá por
<a href="https://www.lucascaton.com/2015/05/02/por-que-escutar-podcasts">podcasts</a>.
Já conhece <a href="https://www.lucascaton.com/podcast/">o meu</a>?</p>
<h2>8. Aprenda algo novo</h2>
<p>Aprenda a <a href="https://www.lucascaton.com/2020/01/06/video-heroku-open-source-conheca-o-dokku">colocar um servidor e o seu projeto no ar</a>.
Aprenda <a href="https://www.lucascaton.com/2019/05/25/aprenda-css-grid-em-60-minutos">CSS Grid</a>.
Aprenda <a href="https://www.lucascaton.com/2019/11/22/video-criando-um-jogo-da-velha-com-react">React</a>.
Aprenda GraphQL. Aprenda Rust. Aprenda Flutter.</p>
<p>Mas faça de <a href="https://www.thoughtworks.com/pt/radar">forma consciente</a>,
escolha <strong>o que vai agregar ou te trazer benefícios no curto/médio prazo</strong>.
É importante <a href="https://www.lucascaton.com/2013/09/28/ha-um-mes-eu-troquei-o-ios-pelo-android">sair da sua zona de conforto</a>,
mas com os "pés no chão".</p>
<h2>9. Você é a média das 5 pessoas que mais convive</h2>
<p>Sendo assim, nada melhor que escolher bem os amigos que quer por perto.
Não tenha medo de <strong>trocar seus amigos</strong> ou de
<a href="https://www.lucascaton.com/2013/08/25/iniciando-uma-vida-completamente-nova">começar uma vida nova</a>.
Daqui a alguns anos (ou em até menos tempo) você vai me agradecer.</p>
<h2>10. Faça um projeto de graça antes de fazer seu primeiro freela</h2>
<p>Mas <strong>sem desistir</strong> no meio, hein?
<a href="https://www.lucascaton.com/2018/12/18/off-topic-feito-e-melhor-que-perfeito">Terminativa</a>
é tão importante quanto iniciativa.</p>
<h2>11. Aprenda inglês</h2>
<p>Esse talvez seja o item mais óbvio e se você não está estudando, <strong>já está ficando para trás</strong>.
Você é programador e está codando em português?
<a href="https://www.lucascaton.com/2015/05/22/8-motivos-pra-programar-em-ingles">Você está fazendo errado</a>.
Simples assim.
Tem
<a href="https://www.lucascaton.com/2018/05/05/video-sacadas-para-estudar-ingles-que-demorei-para-aprender">sacadas que a gente demora para aprender</a>,
mas é melhor tarde do que nunca!</p>
<hr>
<p>Excelente 2020 para você! 😉</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="carreira" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Heroku Open-Source? Conheça o Dokku]]></title>
      <summary><![CDATA[Aprenda a configurá-lo passo-a-passo]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2020/01/06/video-heroku-open-source-conheca-o-dokku?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2020-01-06T07:19:26.000Z</published>
      <updated>2024-10-01T21:30:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2020/01/06/video-heroku-open-source-conheca-o-dokku</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2020/01/06/video-heroku-open-source-conheca-o-dokku">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=1OUDPbvnBxs"><img src="https://i.ytimg.com/vi_webp/1OUDPbvnBxs/maxresdefault.webp" alt="YouTube video" /></a></p>
<ul>
<li><a href="http://dokku.viewdocs.io/dokku/">Documentação oficial do Dokku</a></li>
<li><a href="http://dokku.viewdocs.io/dokku/#install-curl">Dokku - Guia de instalação</a></li>
</ul>
<h3>Lista de todos os comandos utilizados no vídeo:</h3>
<pre><code class="language-bash"># Criar uma aplicação no Dokku
dokku apps:create bookaton
# Criar e "linkar" um banco de dados PostgreSQL
dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres
dokku postgres:create bookaton_production # NOTA: você pode ignorar o sufixo `_production` se quiser
dokku postgres:link bookaton_production bookaton
dokku postgres:list
# Criar e "linkar" uma instância do Redis (Não rodei esses comandos no vídeo)
# dokku plugin:install https://github.com/dokku/dokku-redis.git redis
# dokku redis:create bookaton_production
# dokku redis:link bookaton_production bookaton
# dokku redis:list
# Definiar variáveis de ambiente
# (você pode passar várias de uma vez)
dokku config:set bookaton RAILS_MASTER_KEY=123456789
# Listar variáveis de ambiente
dokku config bookaton
# Adicionar buildpacks
dokku buildpacks:add bookaton https://github.com/heroku/heroku-buildpack-ruby.git
dokku buildpacks:add bookaton https://github.com/heroku/heroku-buildpack-nodejs.git
# dokku buildpacks:add bookaton \
#   https://github.com/heroku/heroku-buildpack-activestorage-preview.git
# Ver quais buildpacks foram adicionados
dokku buildpacks:list bookaton
# Associar nossa aplicação à um domínio
dokku domains:add bookaton bookaton.lucascaton.com.br
# Remover domínio que o Dokku adiciona por padrão
dokku domains:remove bookaton bookaton.dokku
# Ver todos os domínios
dokku domains:report bookaton
</code></pre>
<hr>
<p>Na sua aplicação, não esqueça de criar os seguintes arquivos:</p>
<h3><code>Procfile</code></h3>
<pre><code class="language-bash">web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq -c 3
release: bin/rails db:migrate
</code></pre>
<h3><code>DOKKU_SCALE</code></h3>
<pre><code class="language-bash">web=1
worker=1
</code></pre>
<hr>
<p>Aí basta configurar o repositório remoto do Git (rode esse comando uma única vez):</p>
<pre><code class="language-bash">git remote add dokku dokku@200.0.0.0:bookaton
</code></pre>
<p>E toda vez que você quiser fazer deploy, rode:</p>
<pre><code class="language-bash">git push dokku
</code></pre>
<hr>
<p>No servidor, vamos instalar o Let's Encrypt e criar nosso certificado SSL:</p>
<pre><code class="language-bash">dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
dokku config:set --no-restart bookaton DOKKU_LETSENCRYPT_EMAIL=fulano@exemplo.com
dokku letsencrypt:enable bookaton
# [Não mostrei isso no vídeo]
# Criar um cronjob para renovar o certificado a cada 2 meses
dokku letsencrypt:cron-job --add
</code></pre>
<p>Para rodar o console do Rails e/ou do PostgreSQL no servidor:</p>
<pre><code class="language-bash">dokku run bookaton rails c
dokku run bookaton rails db
</code></pre>
<p>[Não mostrei isso no vídeo] Para acessar o container dentro do servidor:</p>
<pre><code class="language-bash">dokku run bookaton sh
</code></pre>
<p>Por fim, para visualizar/acompanhar os logs, basta rodar:</p>
<pre><code class="language-bash">dokku logs bookaton -t
</code></pre>
<hr>
<p>Clientes do Dokku, para rodar os comandos diretamente da sua máquina em vez de ter que acessar o servidor:</p>
<p><a href="http://dokku.viewdocs.io/dokku/community/clients/">http://dokku.viewdocs.io/dokku/community/clients/</a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="heroku" /><category term="docker" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Como usar o ASDF para gerenciar versões do Node.js, Ruby e mais]]></title>
      <summary><![CDATA[Substitua RVM, Rbenv, NVM, etc. por apenas uma ferramenta!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2019/12/09/video-como-usar-o-asdf-para-gerenciar-versoes-do-nodejs-ruby-etc?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2019-12-08T21:00:00.000Z</published>
      <updated>2019-12-08T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2019/12/09/video-como-usar-o-asdf-para-gerenciar-versoes-do-nodejs-ruby-etc</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2019/12/09/video-como-usar-o-asdf-para-gerenciar-versoes-do-nodejs-ruby-etc">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=adO0QhF8mBU"><img src="https://i.ytimg.com/vi_webp/adO0QhF8mBU/maxresdefault.webp" alt="YouTube video" /></a></p>
<ul>
<li><a href="https://asdf-vm.com/">Site oficial do ASDF</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="javascript" /><category term="nodejs" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: criando um Jogo da Velha com React]]></title>
      <summary><![CDATA[Bora criar um web app de Jogo da Velha, utilizando ⚛️ React & ⚛ React Hooks! 💚]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2019/11/22/video-criando-um-jogo-da-velha-com-react?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2019-11-21T21:02:08.000Z</published>
      <updated>2019-11-21T21:02:08.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2019/11/22/video-criando-um-jogo-da-velha-com-react</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2019/11/22/video-criando-um-jogo-da-velha-com-react">
        <![CDATA[<div xml:lang="pt-BR"><p>Há um tempo atrás eu fiz uma pesquisa no meu
<a href="https://www.lucascaton.com/telegram/">canal do Telegram</a>,
perguntando que tipo de conteúdo queríam que eu produzisse.
De longe, o que foi mais pedido foi <strong>JavaScript</strong> e específicamente <strong>React</strong>.
De lá pra cá, eu venho estudando e também usando React,
tanto em projetos pessoais como na empresa onde eu trabalho.</p>
<p>Por estes motivos, vou começar a produzir mais conteúdos sobre esse assunto!
Eis abaixo o primeiro resultado dessa mudança: eu gravei um <em>screencast</em> mostrando como criar
um jogo da velha usando <strong>React</strong> e <strong>React Hooks</strong>! 😃</p>
<p>Honestando falando, foi um dos vídeos mais divertidos que já fiz e que, ao mesmo tempo,
também contém <em>insights</em> valiosos caso você queira trabalhar com essas tecnologias!</p>
<p><a href="https://www.youtube.com/watch?v=kFXDcaUcOto"><img src="https://i.ytimg.com/vi_webp/kFXDcaUcOto/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<p>Abaixo você encontra o CSS utilizado no vídeo:</p>
<h3><code>src/TicTacToe.css</code></h3>
<pre><code class="language-css">:root {
  --O-color: #2196f3;
  --X-color: #f44336;
  --E-color: #777;
  --green: #4caf50;
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  display: grid;
  align-items: center;
  justify-content: center;
  font-family: sans-serif;
  height: 100vh;
  background-color: #eee;
}
.title {
  text-align: center;
  font-size: 3rem;
  color: #555;
  margin-bottom: 2rem;
}
.board {
  display: grid;
  grid-template-columns: repeat(3, 240px);
  grid-template-rows: repeat(3, 200px);
  gap: 1rem;
}
.board.game-over {
  opacity: 0.8;
}
.cell {
  display: grid;
  align-items: center;
  justify-content: center;
  background-color: white;
  border-radius: 5px;
  font-size: 3rem;
  font-weight: bold;
  color: #00000066;
  cursor: pointer;
}
.cell:not(.O):not(.X):hover {
  box-shadow:
    0 20px 25px -5px rgba(0, 0, 0, 0.1),
    0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.cell.O,
.cell.X,
.game-over .cell {
  cursor: not-allowed;
}
.cell.O {
  background-color: var(--O-color);
}
.cell.X {
  background-color: var(--X-color);
}
footer {
  text-align: center;
}
.winner-message {
  margin: 2rem;
}
.winner-message span.O {
  color: var(--O-color);
}
.winner-message span.X {
  color: var(--X-color);
}
.winner-message span.E {
  color: var(--E-color);
}
button {
  padding: 0.8rem 1.5rem;
  border: none;
  border-radius: 5px;
  box-shadow:
    0 1px 3px 0 rgba(0, 0, 0, 0.1),
    0 1px 2px 0 rgba(0, 0, 0, 0.06);
  background-color: var(--green);
  color: white;
  font-size: 1.2rem;
}
</code></pre>
<p>Me conte nos comentários o que achou do vídeo! 😃</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="javascript" /><category term="react" /><category term="react-hooks" />
    </entry>

    <entry>
      <title><![CDATA[Aprenda CSS Grid em 60 minutos]]></title>
      <summary><![CDATA[CSS Grid é o sistema de layouts mais poderoso disponível para CSS]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2019/05/25/aprenda-css-grid-em-60-minutos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2019-05-25T00:40:18.000Z</published>
      <updated>2019-05-25T00:40:18.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2019/05/25/aprenda-css-grid-em-60-minutos</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2019/05/25/aprenda-css-grid-em-60-minutos">
        <![CDATA[<div xml:lang="pt-BR"><p><strong>CSS Grid</strong> é o sistema de layouts mais poderoso disponível para CSS.</p>
<p>Eu apresentei uma introdução ao assunto em uma LIVE no formato de <em>tech-talk</em>:</p>
<p><a href="https://www.youtube.com/watch?v=B4GOQ0VJ36I"><img src="https://i.ytimg.com/vi_webp/B4GOQ0VJ36I/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<h2>Arquivos demonstrados no vídeo acima:</h2>
<h3><code>index.html</code></h3>
<pre><code class="language-html">&#x3C;!doctype html>
&#x3C;html lang="en">
  &#x3C;head>
    &#x3C;meta charset="UTF-8" />
    &#x3C;meta name="viewport" content="width=device-width, initial-scale=1.0" />
    &#x3C;link rel="stylesheet" href="style.css" />
  &#x3C;/head>
  &#x3C;body>
    &#x3C;main>
      &#x3C;nav>
        &#x3C;h3>Your Account&#x3C;/h3>
      &#x3C;/nav>
      &#x3C;form class="sign-in-form">
        &#x3C;h3>Sign in form&#x3C;/h3>
        &#x3C;button>Sign in&#x3C;/button>
      &#x3C;/form>
      &#x3C;article class="welcome-message">
        &#x3C;h1>Welcome to Foobar&#x3C;/h1>
        &#x3C;p>
          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt
          ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
          ullamco laboris nisi ut aliquip ex ea commodo consequat.
        &#x3C;/p>
        &#x3C;p>
          Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
          nulla pariatur.
        &#x3C;/p>
      &#x3C;/article>
      &#x3C;section class="market-sites">
        &#x3C;h3>Other products&#x3C;/h3>
      &#x3C;/section>
      &#x3C;footer>
        &#x3C;ul>
          &#x3C;li>Help Center&#x3C;/li>
          &#x3C;li>About&#x3C;/li>
          &#x3C;li>Privacy Policy&#x3C;/li>
        &#x3C;/ul>
      &#x3C;/footer>
    &#x3C;/main>
  &#x3C;/body>
&#x3C;/html>
</code></pre>
<h3><code>style.css</code></h3>
<pre><code class="language-css">* {
  margin: 0;
  padding: 1rem;
  border-radius: 5px;
}
body {
  font-family: sans-serif;
  background: whitesmoke;
  padding: 0;
}
main {
  max-width: 1000px;
  margin: 0 auto;
  padding: 0;
}
nav {
  background-color: black;
  color: white;
  grid-area: navbar;
}
.sign-in-form {
  background-color: white;
  color: #333;
  grid-area: sign-in-form;
}
.sign-in-form button {
  background-color: #85b54a;
  width: 100%;
  color: white;
  font-size: 1rem;
}
.welcome-message {
  grid-area: welcome;
}
.market-sites {
  background-color: #673ab7;
  color: white;
  grid-area: market-sites;
}
footer {
  border-top: 0.1rem solid #ccc;
  margin-top: 1rem;
  padding-top: 0;
  color: grey;
  text-align: center;
  grid-area: footer;
}
footer li {
  display: inline;
}
@media screen and (min-width: 700px) {
  main {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr auto auto 1fr;
    grid-gap: 10px;
    grid-template-areas:
      "navbar       navbar"
      "welcome      sign-in-form"
      "market-sites sign-in-form"
      "footer       footer";
  }
}
</code></pre>
<p><aside>Assista outras lives <a href="https://www.lucascaton.com/lives">aqui</a>!</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="html" /><category term="css" /><category term="css-grid" /><category term="desenvolvimento-web" />
    </entry>

    <entry>
      <title><![CDATA[Como ler um livro rendeu uma vaga na RedHat]]></title>
      <summary><![CDATA[1º episódio da série "Programe Seu Futuro"]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2019/05/13/como-ler-um-livro-rendeu-uma-vaga-na-redhat?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2019-05-13T02:11:38.000Z</published>
      <updated>2019-05-13T02:11:38.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2019/05/13/como-ler-um-livro-rendeu-uma-vaga-na-redhat</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2019/05/13/como-ler-um-livro-rendeu-uma-vaga-na-redhat">
        <![CDATA[<div xml:lang="pt-BR"><p>1º episódio da série <a href="https://www.lucascaton.com/tags/programeseufuturo/">"Programe Seu Futuro"</a>.</p>
<ul>
<li>Com <a href="https://twitter.com/thiagoalessio">Thiago Aléssio (aka. Xis)</a></li>
<li>Co-host: <a href="https://twitter.com/pothix">Willian Molinari (aka. PotHix)</a></li>
</ul>
<p><a href="https://www.youtube.com/watch?v=Q80PoxkiHuo"><img src="https://i.ytimg.com/vi_webp/Q80PoxkiHuo/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>🔊 Escute a versão em <a href="https://www.lucascaton.com/podcast">podcast</a> se preferir (episódio #22).</aside></p>
<p><aside>📘 Leia também o artigo <a href="https://www.lucascaton.com/2017/02/09/li-e-recomendo-o-livro-desconstruindo-a-web">Li e recomendo o livro Desconstruindo a Web</a>.</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="programeseufuturo" />
    </entry>

    <entry>
      <title><![CDATA[Quer me ver programando? Venha acompanhar minhas lives!]]></title>
      <summary><![CDATA[Lives todas as sextas-feiras às 20h, no YouTube]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2019/04/19/quer-me-ver-programando-venha-acompanhar-minhas-lives?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2019-04-19T02:04:11.000Z</published>
      <updated>2019-04-19T02:04:11.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2019/04/19/quer-me-ver-programando-venha-acompanhar-minhas-lives</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2019/04/19/quer-me-ver-programando-venha-acompanhar-minhas-lives">
        <![CDATA[<div xml:lang="pt-BR"><p>Há algumas semanas comecei a gravar <strong>lives de programação</strong> no meu
<a href="https://www.youtube.com/lucascaton?sub_confirmation=1">canal do YouTube</a>!</p>
<p><a href="https://www.lucascaton.com/lives"><img src="https://img.youtube.com/vi/o6DJ3Rgrcok/maxresdefault.jpg" alt="Live thumb"></a></p>
<h3>Todas as sextas-feiras às 20h</h3>
<p><aside>Você também pode assistir às <a href="https://www.lucascaton.com/lives">primeiras lives</a> <strong>por enquanto</strong>, pois em breve as lives antigas ficarão disponíveis apenas para <a href="/curso">meus alunos</a> :)</aside></p>
<p>Se inscreva no meu
<a href="https://www.youtube.com/lucascaton?sub_confirmation=1">canal do YouTube</a>
ou deixe o seu email no <a href="https://www.lucascaton.com/lives">formulário desta página</a>
para ser lembrado sobre as próximas lives!</p>
<p>Te vejo lá!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="programacao" /><category term="lives" />
    </entry>

    <entry>
      <title><![CDATA[Guia: Desenvolvedor Web 2019]]></title>
      <summary><![CDATA[Versão 2019 do guia que ficou muito popular em 2018]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2019/02/03/guia-desenvolvedor-web-2019?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2019-02-03T05:21:00.000Z</published>
      <updated>2019-02-03T05:21:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2019/02/03/guia-desenvolvedor-web-2019</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2019/02/03/guia-desenvolvedor-web-2019">
        <![CDATA[<div xml:lang="pt-BR"><p>Eu 2018, eu <a href="https://www.lucascaton.com/2018/01/18/desenvolvimento-web-em-2018">traduzi</a> um guia chamado
<a href="https://github.com/kamranahmedse/developer-roadmap">Developer Roadmap</a>.
Agora em 2019, fiz algo parecido, porém <strong>em vídeo</strong>, comentando cada um dos itens do guia:</p>
<h2>Parte 1 (Introdução)</h2>
<p><a href="https://www.youtube.com/watch?v=8zZo_H3SevA"><img src="https://i.ytimg.com/vi_webp/8zZo_H3SevA/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Parte 2 (Front-end)</h2>
<p><a href="https://www.youtube.com/watch?v=lSxMMLEcNIA"><img src="https://i.ytimg.com/vi_webp/lSxMMLEcNIA/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Parte 3 (Back-end)</h2>
<p><a href="https://www.youtube.com/watch?v=kChYaF-SweI"><img src="https://i.ytimg.com/vi_webp/kChYaF-SweI/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Parte 4 (Dev Ops)</h2>
<p><a href="https://www.youtube.com/watch?v=W0zK1b_srXU"><img src="https://i.ytimg.com/vi_webp/W0zK1b_srXU/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se inscreva no meu canal do YouTube para <strong>assistir mais vídeos como esses</strong>: <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">www.youtube.com/lucascaton</a></aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="guia" /><category term="desenvolvimento-web" /><category term="back-end" /><category term="front-end" /><category term="dev-ops" />
    </entry>

    <entry>
      <title><![CDATA[Ruby 2.6 acaba de ser lançado!]]></title>
      <summary><![CDATA[Com mais performance, JIT, ranges infinitos, método "then" e muito mais!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/12/25/ruby-2-6-acaba-de-ser-lancado?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-12-25T00:21:30.000Z</published>
      <updated>2018-12-25T00:21:30.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/12/25/ruby-2-6-acaba-de-ser-lancado</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/12/25/ruby-2-6-acaba-de-ser-lancado">
        <![CDATA[<div xml:lang="pt-BR"><p>Desde 2013, os desenvolvedores do Ruby mantém uma tradição de lançar uma nova versão da linguagem
na época do Natal e nesse ano não foi diferente.</p>
<p><img src="/images/posts/2018/12/ruby2.6.jpg" alt="Ruby 2.6"></p>
<h2>Como instalar/atualizar?</h2>
<p>Antes de mais nada: <strong>sim, já é possível instalar e usar a nova versão!</strong></p>
<p>Para instalar usando os gerenciadores mais populares:</p>
<h4><a href="https://rvm.io/">RVM</a>:</h4>
<pre><code class="language-bash"># Atualize o RVM:
$ rvm get stable
# Instale o Ruby 2.6:
$ rvm install 2.6.0
</code></pre>
<h4><a href="https://github.com/rbenv/rbenv">rbenv</a>:</h4>
<pre><code class="language-bash"># Atualize a lista de versões do Ruby:
$ cd "$(rbenv root)"/plugins/ruby-build &#x26;&#x26; git pull
# Instale o Ruby 2.6:
$ rbenv install 2.6.0
</code></pre>
<p>* * *</p>
<p>Vamos então dar uma olhada no que há de novo nessa nova versão!</p>
<h2>Melhorias de performance</h2>
<p>Essa versão tem algumas melhorias de performance, como:</p>
<ul>
<li>O método <code>Proc#call</code> está aproximadamente 1.4x mais rápido.</li>
<li><em>Hashes</em> de vida-útil curta consomem 7% menos memória.</li>
</ul>
<p>Na RubyConf de 2015, Matz (criador do Ruby) <a href="https://youtu.be/LE0g2TUsJ4U?t=3358">anunciou o <strong>Ruby 3x3</strong></a>,
que são os planos para fazer o <strong>Ruby 3.0</strong> ficar 3x mais rápido.
Essa versão provavelmente será <a href="https://www.quora.com/When-will-Ruby-3-0-release">lançada em 2020</a>.</p>
<p>Uma das estratégias que viabilizará essa grande melhoria de performance é o JIT/MJIT,
que está sendo incluída (como recurso experimental) na versão 2.6, conforme você confere na sessão abaixo:</p>
<h2>JIT (Just-in-time)</h2>
<p>Uma das funcionalidades mais notáveis da versão 2.6 do Ruby
é que ela vem com uma implementação (experimental) de um <strong>compilador JIT (Just-in-time)</strong>.</p>
<p>Segundo esse <a href="https://medium.com/tailor-tech/whats-new-in-ruby-2-6-a4774f3631c1">artigo do Guy Maliar</a>
(em uma tradução livre):</p>
<blockquote>
<p>A idéia por trás de um compilador JIT é "inspencionar" o código em tempo de execução
e tentar otimizar de forma mais inteligente o código atualmente em execução,
que é o oposto do que acontece em um compilador AOT (Ahead Of Time compiler).</p>
</blockquote>
<p>Essa é apenas a implementação inicial e ainda está um pouco instável.</p>
<p>Entretando, <em>benchmarks</em> iniciais mostram resultados muito bons.
O emulador de NES "Optcarrot" rodou ~ 77% mais rápido, se comparado com o Ruby 2.5.3:</p>
<table>
<thead>
<tr>
<th align="left">Ruby (versão)</th>
<th align="left">FPS (frames por segundo)</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">2.5.3</td>
<td align="left">48.3</td>
</tr>
<tr>
<td align="left">2.6.0</td>
<td align="left">54.5</td>
</tr>
<tr>
<td align="left">2.6.0 + JIT</td>
<td align="left">85.7</td>
</tr>
</tbody>
</table>
<p>(<a href="https://gist.github.com/k0kubun/d7f54d96f8e501bbbc78b927640f4208">Fonte</a>)
{: .text-right}</p>
<p>Outros <em>benchmarks</em> mostram resultados ainda mais significativos:</p>
<table>
<thead>
<tr>
<th align="left">Benchmark</th>
<th align="left">Quanto mais rápido?</th>
<th align="left">Código</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Mandlebrot</td>
<td align="left">1.27x</td>
<td align="left"><a href="https://github.com/benchmark-driver/mjit-benchmarks/blob/master/benchmarks/mandelbrot.yml">Ver código</a></td>
</tr>
<tr>
<td align="left">Fibonacci</td>
<td align="left">3.19x</td>
<td align="left"><a href="https://github.com/benchmark-driver/mjit-benchmarks/blob/master/benchmarks/fib.yml">Ver código</a></td>
</tr>
<tr>
<td align="left"><code>const</code>/<code>const2</code></td>
<td align="left">Quase 4x</td>
<td align="left"><a href="https://github.com/benchmark-driver/mjit-benchmarks/blob/master/benchmarks/const2.yml">Ver código</a></td>
</tr>
</tbody>
</table>
<p><aside>Leia mais sobre JIT (e MJIT) <a href="https://www.rubyguides.com/2018/11/ruby-mjit/">neste artigo</a>.</aside></p>
<h2>Bundler agora vem com o Ruby</h2>
<p><img src="/images/posts/2018/12/bundler.png" alt="Bundler"></p>
<p>Já faz um tempo que essa <a href="https://bugs.ruby-lang.org/issues/12733">discussão começou</a> e agora é oficial:
<strong>a gem <code>bundler</code> vem por padrão com o Ruby!</strong></p>
<p>Quem tiver curiosidade, <a href="https://github.com/ruby/ruby/pull/1536/files">esse é o <em>Pull Request</em></a>
com tudo que foi alterado.</p>
<p>Essa mudança é especialmente bem-vinda pelo fato de ajudar iniciantes, já que elimina um passo na instalação do Ruby
(e é com prazer que eu <del>vou ter que regravar</del> já regravei essa aula do <a href="https://www.lucascaton.com/cursos/cplc/">meu curso</a> 🙂).</p>
<p><aside>Você pode ler mais sobre essa integração no <a href="http://engineering.appfolio.com/appfolio-engineering/2018/11/26/bundler-is-built-into-ruby-260preview3">blog de engenharia da Appfolio</a>.</aside></p>
<h2>O método <code>#then</code></h2>
<p>O método <code>yield_self</code> foi adicionado no Ruby 2.5.
A novidade agora é que ele ganhou um alias: <code>then</code>.</p>
<p>Considere o seguinte exemplo de código de <em>controller</em> do <strong>Rails</strong>:</p>
<pre><code class="language-ruby">events = Event.upcoming
events = events.limit(params[:limit])          if params[:limit]
events = events.where(status: params[:status]) if params[:status]
events
</code></pre>
<p>Podemos reescrever o código acima usando <code>yield_self</code> ou <code>then</code>
(já que o segundo é apenas um <em>alias</em> do primeiro):</p>
<pre><code class="language-ruby">Event.upcoming
  .yield_self { |events| params[:limit]  ? events.limit(params[:limit])          : events }
  .yield_self { |events| params[:status] ? events.where(status: params[:status]) : events }
</code></pre>
<p>Agora com <code>then</code>, que faz o código ficar um pouco mais legível:</p>
<pre><code class="language-ruby">Event.upcoming
  .then { |events| params[:limit]  ? events.limit(params[:limit])          : events }
  .then { |events| params[:status] ? events.where(status: params[:status]) : events }
</code></pre>
<h2>Ranges infinitos</h2>
<p>Agora podemos criar <em>ranges</em> sem especificar um valor final.
Isso significa que podemos escrever códigos como:</p>
<pre><code class="language-ruby">array[1..]
# O código acima é identico à `array[1..-1]`
</code></pre>
<pre><code class="language-ruby"># Loop infinito que começa com índice 1
(1..).each { |index| ... }
</code></pre>
<pre><code class="language-ruby">array.zip(1..) { |elem, index| ... }
# O código acima é identico à `array.each.with_index(1) { }`
</code></pre>
<h2>Novo método <code>#filter</code> para arrays (<em>alias</em> para o método <code>#select</code>)</h2>
<p>Nós conhecemos bem o método <code>select</code>, mas em outras linguagens
(como JavaScript, Java e PHP), ele é mais conhecido como <code>filter</code>.
Se você, assim como eu, sempre quis que um <em>alias</em> fosse criado, esse momento chegou:</p>
<pre><code class="language-ruby">[:foo, :bar].filter { |x| x == :foo }
# => [:foo]
</code></pre>
<h2>Métodos <code>#union</code> e <code>#difference</code> para arrays</h2>
<p>Para quem lembra das <a href="https://www.todamateria.com.br/operacoes-com-conjuntos/">aulas de matemática da escola</a>
ou para quem precisa trabalhar com <strong>união e diferença entre <em>arrays</em></strong>, tenho uma boa notícia:</p>
<p>Dois métodos (<code>#union</code> e <code>#difference</code>) foram adicionados aos <em>arrays</em>.</p>
<p>Eis um exemplo:</p>
<pre><code class="language-ruby">[1, 1, 2, 2, 3, 3, 4, 5].difference([1, 2, 4])
# => [3, 3, 5]
</code></pre>
<pre><code class="language-ruby">['a', 'b', 'c'].union(['c', 'd', 'a'])
# => ['a', 'b', 'c', 'd']
</code></pre>
<pre><code class="language-ruby">['a'].union([['e', 'b'], ['a', 'c', 'b']])
# => ['a', 'e', 'b', 'c']
</code></pre>
<hr>
<p>Veja também
<a href="https://www.ruby-lang.org/en/news/2018/12/25/ruby-2-6-0-released/">post oficial</a>
sobre o lançamento da versão 2.6.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[[Off-topic] Feito é melhor que perfeito]]></title>
      <summary><![CDATA[Uma técnica relativamente simples para alcançar seus objetivos]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/12/18/off-topic-feito-e-melhor-que-perfeito?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-12-18T10:04:38.000Z</published>
      <updated>2018-12-18T10:04:38.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/12/18/off-topic-feito-e-melhor-que-perfeito</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/12/18/off-topic-feito-e-melhor-que-perfeito">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2018/12/design-desk-display-313690.jpg" alt="image_description"></p>
<p>Vou escrever sobre uma técnica relativamente simples para alcançar seus objetivos, seja conseguir
um [novo] emprego, emagrecer, terminar um curso de programação, ou qualquer outra coisa.</p>
<p>Em 2012, eu fui com a minha noiva (atualmente esposa) visitar o meu pai e levamos um grande amigo meu.
Na viagem de volta pra casa, viemos falando sobre casamento e comentamos que não tínhamos uma data
para casar ainda. Afinal, por que a pressa para casar?
Tanto eu quanto minha noiva estávamos tranquilos em relação à isso.
Não é o tipo de situação na qual existe pressão por parte de um chefe, de um cliente, da família, etc.</p>
<p>Eram muitas coisas para planejar: documentação para o cartório, agendar o dia na igreja
(além de preparar os enfeites), alugar o salão, comprar os comes e bebes da festa, fazer lista de
convidados, escolher os padrinhos, planejar a lua de mel (que tem que coincidir com férias de
trabalho) e muito mais - só que já casou sabe do que eu estou falando!</p>
<p>Sei que muitos casais enrolam justamente por isso :)</p>
<p>Nesse momento, ele nos deu um conselho caso a gente realmente quisesse casar:
escolher uma data e não mudar por motivo algum.
Essa seria a forma mais eficiente para conseguirmos preparar tudo.
Ele ainda sugeriu 6 meses a contar daquele dia.
Após um pouco de conversa, caiu a ficha de que ele tinha razão!
Mesmo sabendo que era bastante coisa para fazer, 6 meses parecida um prazo razoável.</p>
<p>Começamos a ligar para nossa família e amigos mais chegados e perguntar se eles tinham compromisso
naquela data. Depois de confirmar que todos poderiam, pedimos para que todos reservassem o dia 8 de
dezembro de 2012 em seus calendários, pois iriamos nos casar! Nesse momento, não havia como fugir:
<strong>teríamos que fazer o melhor possível durante aqueles 6 meses</strong>. No final deu tudo certo!</p>
<p>* * *</p>
<p>Venho utilizando essa técnica desde aquela época, para várias outras coisas da minha vida.</p>
<p>O mais importante é <strong>escolher uma data e mantê-la</strong>,
principalmente quando somos perfeccionistas, pois naturalmente tendemos a enrolar o máximo que der.
Isso vale para um casamento,
para <a href="https://www.lucascaton.com/2017/10/21/por-que-voce-deveria-ter-um-blog">criar um blog</a>,
para projetos pessoais, para um trabalho de conclusão de faculdade/pós-graduação, enfim, para qualquer coisa!</p>
<p>Dependendo do seu foco e da sua disciplina, é capaz de você acabar desistindo de finalizar se você
<strong>não tiver um prazo e não for avançando aos poucos</strong>.</p>
<blockquote>
<p>Não basta ter a <em>iniciativa</em> é importante ter a <em>"terminativa"</em>!</p>
</blockquote>
<p>Existe a chance, inclusive, de você criar inconscientemente uma desculpa para justificar o porquê
você não chegou lá. Digamos que você queira começar a correr, mas no primeiro dia estava chovendo e
você deixa para o dia seguinte. Aí no dia seguinte não vai porque não tinha o tênis apropriado. No
terceiro, não vai porque a perna estava doendo um pouquinho. Tem até aquele ditado:</p>
<blockquote>
<p>"Quem quer, arruma um jeito; quem não quer, arruma uma desculpa."</p>
</blockquote>
<p><strong>Inventar desculpas é uma das coisas mais eficiente que o ser humano é capaz</strong>;
somos realmente muito bons nisso.</p>
<p>* * *</p>
<p>Suponhamos que você esteja criando um aplicativo/site ou ainda esteja abrindo uma empresa.
Você obviamente vai precisar de um nome. Pode parecer uma tarefa simples, mas eu vejo pessoas
demorando vários dias e muitas vezes até desistindo somente pelo fato de não terem conseguido o
"nome ideal" (algo utópico, considerando que um nome é muito subjetivo).</p>
<p>A solução para esses casos é estabelecer um prazo e dar o melhor de si até tal prazo chegar.
Faça uma lista de opções. Talvez você não goste de nenhum, mas vá anotando todos os que surgirem.</p>
<p><strong>Quando a data chegar, escolha o melhor nome da lista e pronto!</strong></p>
<p>Lembre-se que você fez o melhor que pôde, então não postergue essa decisão,
mesmo que nenhum nome te agrade 100%. Mesmo que talvez você precise mudar no futuro,
esse é o momento de seguir em frente com o que você conseguiu até agora.</p>
<p>Se você não fizer isso, você nunca vai entender que <strong>"feito é melhor que perfeito"</strong>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="offtopic" /><category term="produtividade" />
    </entry>

    <entry>
      <title><![CDATA[Café com Caton 008: Devo estudar criação de APIs ou cliente mobile primeiro?]]></title>
      <summary><![CDATA[Dúvida enviada por Tharlles Té]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/10/11/cafe-com-caton-008-devo-estudar-criacao-de-apis-ou-cliente-mobile-primeiro?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-10-11T11:19:56.000Z</published>
      <updated>2018-10-11T11:19:56.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/10/11/cafe-com-caton-008-devo-estudar-criacao-de-apis-ou-cliente-mobile-primeiro</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/10/11/cafe-com-caton-008-devo-estudar-criacao-de-apis-ou-cliente-mobile-primeiro">
        <![CDATA[<div xml:lang="pt-BR"><p>Quando estamos nos preparando para começar a programar um novo projeto,
nem sempre é claro o que precisamos estudar primeiro.</p>
<p>É como preparar um bolo: tem que saber os ingredientes, a quantidade de cada coisa
e também a ordem de preparo, ou seja, em que momento colocar cada item.</p>
<p>É sobre isso que eu falo nesse episódio, respondendo a dúvida enviada pelo <strong>Tharlles Té</strong>:</p>
<p><a href="https://www.youtube.com/watch?v=xXNwzqRyci8"><img src="https://i.ytimg.com/vi_webp/xXNwzqRyci8/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se inscreva no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
<ul>
<li>
<p>Vídeo comentado nesse episódio: <a href="https://www.lucascaton.com/2018/01/28/como-testar-seu-site-ou-app-em-diversos-dispositivos">Como testar seu site ou app em diversos dispositivos</a>.</p>
</li>
<li>
<p>Se preferir, você também pode <strong>escutar</strong> esse episódio através do meu <a href="https://www.lucascaton.com/podcast">podcast</a>.</p>
</li>
<li>
<p>Ver outros episódios da série <a href="https://www.lucascaton.com/tags/cafe-com-caton/">Café com Caton</a>.</p>
</li>
<li>
<p>Escreva sua opinião nos comentários abaixo, a discussão fica mais interessante com mais pessoas :)</p>
</li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="cafe-com-caton" /><category term="apis" /><category term="ionic" /><category term="react" />
    </entry>

    <entry>
      <title><![CDATA[Café com Caton 007: SQL ou NoSQL?]]></title>
      <summary><![CDATA[Dúvida enviada por Ramakanta Dasa]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/10/06/cafe-com-caton-007-sql-ou-nosql?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-10-06T01:16:58.000Z</published>
      <updated>2018-10-06T01:16:58.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/10/06/cafe-com-caton-007-sql-ou-nosql</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/10/06/cafe-com-caton-007-sql-ou-nosql">
        <![CDATA[<div xml:lang="pt-BR"><p>Digamos que você esteja prestes a começar o desenvolvimento de um novo projeto.
Enquanto que banco de dados como <strong>PostgreSQL</strong> e <strong>MySQL</strong> são escolhas tradicionais,
quais são os casos que valem a pena considerar bancos <strong>NoSQL</strong>, como <strong>MongoDB</strong>?</p>
<p>É sobre isso que eu falo nesse episódio, respondendo a dúvida enviada pelo <strong>Ramakanta Dasa</strong>:</p>
<p><a href="https://www.youtube.com/watch?v=X858FxpKTSE"><img src="https://i.ytimg.com/vi_webp/X858FxpKTSE/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se preferir, você também pode <strong>escutar</strong> esse episódio através do meu podcast: <a href="https://www.lucascaton.com/podcast">podcast</a></aside></p>
<p><aside>Se inscreva no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
<p><aside>Ver outros episódios da série <a href="https://www.lucascaton.com/tags/cafe-com-caton/">Café com Caton</a></aside></p>
<p>Escreva sua opinião nos comentários abaixo, a discussão fica mais interessante com mais pessoas! 🙂</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="cafe-com-caton" /><category term="banco-de-dados" /><category term="postgresql" /><category term="nosql" />
    </entry>

    <entry>
      <title><![CDATA[Action Text: o novo framework que virá no Rails 6]]></title>
      <summary><![CDATA[Descubra o que é e como usar o novo framework]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/10/04/video-action-text-o-novo-framework-que-vira-no-rails-6?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-10-04T07:58:54.000Z</published>
      <updated>2018-10-04T07:58:54.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/10/04/video-action-text-o-novo-framework-que-vira-no-rails-6</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/10/04/video-action-text-o-novo-framework-que-vira-no-rails-6">
        <![CDATA[<div xml:lang="pt-BR"><p><strong>Action Text</strong> é o mais novo <em>framework</em> do <strong>Rails</strong> e será adicionado oficialmente na versão 6.</p>
<p>Para entender as razões que levaram o <strong>Rails Core Team</strong> (e a equipe do <strong>Basecamp</strong> também, diga-se de passagem)
a criá-lo e também aprender a utilizá-lo, assista ao vídeo abaixo:</p>
<p><a href="https://www.youtube.com/watch?v=ZlN1iPbuP-A"><img src="https://i.ytimg.com/vi_webp/ZlN1iPbuP-A/maxresdefault.webp" alt="YouTube video" /></a></p>
<ul>
<li><a href="https://github.com/rails/actiontext">Action Text</a></li>
<li><a href="https://trix-editor.org/">Trix</a> (editor de texto rico JS criado pelo <a href="https://basecamp.com">Basecamp</a>)</li>
</ul>
<p>Vídeos comentados no <em>screencast</em> acima:</p>
<ul>
<li><a href="https://www.lucascaton.com/2018/04/14/video-aprenda-active-storage-parte-1">Aprenda Active Storage</a></li>
<li><a href="https://www.lucascaton.com/2018/07/14/live-o-que-ja-sabemos-sobre-o-rails-6">Live: o que já sabemos sobre o Rails 6</a></li>
</ul>
<p><aside><strong>Atenção</strong>: não é recomendado usar versões <code>alpha</code>, <code>beta</code>, <code>rc</code>, etc. em produção.</aside></p>
<hr>
<p>Comandos executados e arquivos alterados no vídeo:</p>
<h3>Terminal</h3>
<pre><code class="language-bash">$ rails6 new action-text-demo --edge
$ cd action-text-demo
$ atom .
</code></pre>
<h3><code>Gemfile</code></h3>
<pre><code class="language-ruby">gem 'actiontext', github: 'rails/actiontext', require: 'action_text'
gem 'image_processing', '~> 1.2'
</code></pre>
<h3>Terminal</h3>
<pre><code class="language-bash">$ rails action_text:install
$ rails db:migrate
$ rails g scaffold post title
$ rails db:migrate
$ rails s
</code></pre>
<h3><code>config/routes.rb</code></h3>
<pre><code class="language-ruby">root 'posts#index'
</code></pre>
<h3><code>app/models/post.rb</code></h3>
<pre><code class="language-ruby">class Post &#x3C; ApplicationRecord
  has_rich_text :content
end
</code></pre>
<h3><code>app/views/posts/_form.html.erb</code></h3>
<pre><code class="language-erb">&#x3C;div class="field">
  &#x3C;%= form.label :content %>
  &#x3C;%= form.rich_text_area :content %>
&#x3C;/div>
</code></pre>
<h3><code>app/controllers/posts_controller.rb</code></h3>
<pre><code class="language-ruby">params.require(:post).permit(:title, :content)
</code></pre>
<h3><code>app/views/posts/show.html.erb</code></h3>
<pre><code class="language-erb">&#x3C;p>&#x3C;%= @post.content %>&#x3C;/p>
</code></pre>
<p>Coloquem nos comentários abaixo o que vocês acharam da novidade e quem está ansioso pelo <strong>Rails 6</strong>! 😁</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="actiontext" />
    </entry>

    <entry>
      <title><![CDATA[Meu podcast está no ar!]]></title>
      <summary><![CDATA[Eis o que você pode esperar nos episódios]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/10/01/meu-podcast-esta-no-ar?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-10-01T07:59:21.000Z</published>
      <updated>2018-10-01T07:59:21.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/10/01/meu-podcast-esta-no-ar</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/10/01/meu-podcast-esta-no-ar">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=BYt28WGd3JQ"><img src="https://i.ytimg.com/vi_webp/BYt28WGd3JQ/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Busque por <code>Lucas Caton</code> no seu app de podcast favorito! 🙂</p>
<p>Ou <a href="https://www.lucascaton.com/podcast">clique aqui</a> para acessar os links diretamente!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="podcasts" />
    </entry>

    <entry>
      <title><![CDATA[Café com Caton 006: Por que não desenvolver um ecommerce?]]></title>
      <summary><![CDATA[Dúvida enviada por várias pessoas]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/09/28/cafe-com-caton-006-por-que-nao-desenvolver-um-ecommerce?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-09-27T22:05:07.000Z</published>
      <updated>2018-09-27T22:05:07.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/09/28/cafe-com-caton-006-por-que-nao-desenvolver-um-ecommerce</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/09/28/cafe-com-caton-006-por-que-nao-desenvolver-um-ecommerce">
        <![CDATA[<div xml:lang="pt-BR"><p>Existem situações nas quais não valem a pena desenvolver um software e nesse episódio eu vou falar sobre uma delas:</p>
<p><a href="https://www.youtube.com/watch?v=y2LfzdC2kzQ"><img src="https://i.ytimg.com/vi_webp/y2LfzdC2kzQ/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se inscreva no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
<ul>
<li>
<p>Solução open-source (gem) de ecommerce feita em Ruby on Rails: <a href="https://github.com/spree/spree">Spree</a></p>
</li>
<li>
<p>Plataforma de ecommerce (SAAS): <a href="https://www.shopify.com/">Shopify</a></p>
</li>
<li>
<p>Artigo <a href="https://www.lucascaton.com/2018/01/18/desenvolvimento-web-em-2018">"Desenvolvimento web em 2018"</a></p>
</li>
<li>
<p>Assista o episódio anterior, no qual eu falo quais
<a href="https://www.lucascaton.com/2018/09/26/cafe-com-caton-005-podcasts-que-eu-escuto">podcasts que eu escuto</a></p>
</li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="cafe-com-caton" /><category term="ecommerce" />
    </entry>

    <entry>
      <title><![CDATA[Café com Caton 005: Podcasts que eu escuto]]></title>
      <summary><![CDATA[Dúvida enviada por várias pessoas]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/09/26/cafe-com-caton-005-podcasts-que-eu-escuto?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-09-26T07:27:03.000Z</published>
      <updated>2018-09-26T07:27:03.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/09/26/cafe-com-caton-005-podcasts-que-eu-escuto</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/09/26/cafe-com-caton-005-podcasts-que-eu-escuto">
        <![CDATA[<div xml:lang="pt-BR"><p>Aqueles que leram e gostaram do meu artigo
<a href="https://www.lucascaton.com/2015/05/02/por-que-escutar-podcasts">"Por que escutar Podcasts?"</a>,
provavelmente também curtirão esse episódio da série <strong>"Café com Caton"</strong>,
no qual eu falo rapidamente sobre todos os podcasts que escuto atualmente (nacionais e gringos):</p>
<p><a href="https://www.youtube.com/watch?v=KNFVrTYqr5U"><img src="https://i.ytimg.com/vi_webp/KNFVrTYqr5U/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Aproveite para conhecer o <a href="https://www.lucascaton.com/podcast"><strong>meu podcast</strong></a>!</aside></p>
<p>Assista o episódio anterior, no qual eu mostro
<a href="https://www.lucascaton.com/2018/09/23/cafe-com-caton-004-como-e-meu-estudio-escritorio">como é meu estúdio e meu escritório</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="cafe-com-caton" /><category term="podcasts" />
    </entry>

    <entry>
      <title><![CDATA[Café com Caton 004: Como é meu estúdio / escritório]]></title>
      <summary><![CDATA[Dúvida enviada por Aristóteles Coutinho e Pádua Lima]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/09/23/cafe-com-caton-004-como-e-meu-estudio-escritorio?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-09-22T23:29:45.000Z</published>
      <updated>2018-09-22T23:29:45.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/09/23/cafe-com-caton-004-como-e-meu-estudio-escritorio</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/09/23/cafe-com-caton-004-como-e-meu-estudio-escritorio">
        <![CDATA[<div xml:lang="pt-BR"><p>O quarto episódio da série <strong>"Café com Caton"</strong> está no ar:</p>
<p><a href="https://www.youtube.com/watch?v=yDf5ae3Zldw"><img src="https://i.ytimg.com/vi_webp/yDf5ae3Zldw/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se inscreva no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
<p>Artigo comentado no vídeo:
<a href="https://www.lucascaton.com/2018/03/27/os-desafios-de-trabalhar-remotamente">Os desafios de trabalhar remotamente</a>.</p>
<p>Assista o episódio anterior sobre
<a href="https://www.lucascaton.com/2018/09/22/cafe-com-caton-003-como-construir-uma-carreira-de-referencia">Como construir uma carreira de referência</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="cafe-com-caton" /><category term="home-office" /><category term="trabalho-remoto" /><category term="estudio" />
    </entry>

    <entry>
      <title><![CDATA[Café com Caton 003: Como construir uma carreira de referência]]></title>
      <summary><![CDATA[Dúvida enviada por Tiago Garcia]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/09/22/cafe-com-caton-003-como-construir-uma-carreira-de-referencia?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-09-21T21:04:19.000Z</published>
      <updated>2018-09-21T21:04:19.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/09/22/cafe-com-caton-003-como-construir-uma-carreira-de-referencia</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/09/22/cafe-com-caton-003-como-construir-uma-carreira-de-referencia">
        <![CDATA[<div xml:lang="pt-BR"><p>O terceiro episódio da série <strong>"Café com Caton"</strong> está no ar:</p>
<p><a href="https://www.youtube.com/watch?v=umOG4Y1j0fQ"><img src="https://i.ytimg.com/vi_webp/umOG4Y1j0fQ/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se inscreva no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
<p>Assista o episódio anterior sobre
<a href="https://www.lucascaton.com/2018/09/21/cafe-com-caton-002-como-trabalhar-com-a-linguagem-que-voce-ama">Como trabalhar com a linguagem que você ama</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="cafe-com-caton" /><category term="carreira" />
    </entry>

    <entry>
      <title><![CDATA[Café com Caton 002: Como trabalhar com a linguagem que você ama]]></title>
      <summary><![CDATA[Dúvida enviada por Alyne Gois]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/09/21/cafe-com-caton-002-como-trabalhar-com-a-linguagem-que-voce-ama?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-09-20T14:19:00.000Z</published>
      <updated>2018-09-20T14:19:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/09/21/cafe-com-caton-002-como-trabalhar-com-a-linguagem-que-voce-ama</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/09/21/cafe-com-caton-002-como-trabalhar-com-a-linguagem-que-voce-ama">
        <![CDATA[<div xml:lang="pt-BR"><p>O segundo episódio da série <strong>"Café com Caton"</strong> está no ar:</p>
<p><a href="https://www.youtube.com/watch?v=2GaDY7W0U2c"><img src="https://i.ytimg.com/vi_webp/2GaDY7W0U2c/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se inscreva no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
<p>Assista o episódio anterior sobre
<a href="https://www.lucascaton.com/2018/09/19/cafe-com-caton-001-freelancer">Freelancer</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="cafe-com-caton" /><category term="ruby" /><category term="meetups" /><category term="trabalho-remoto" />
    </entry>

    <entry>
      <title><![CDATA[Café com Caton 001: Freelancer]]></title>
      <summary><![CDATA[Dúvida enviada por Fábio de Albuquerque]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/09/19/cafe-com-caton-001-freelancer?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-09-19T11:59:00.000Z</published>
      <updated>2018-09-19T11:59:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/09/19/cafe-com-caton-001-freelancer</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/09/19/cafe-com-caton-001-freelancer">
        <![CDATA[<div xml:lang="pt-BR"><p>Olá meus caros!</p>
<p>O vídeo abaixo inaugura uma nova série chamada <strong>"Café com Caton"</strong>.
Seria impossível encontrar um nome mais clichê, eu sei! 😆</p>
<p>Espero que gostem:</p>
<p><a href="https://www.youtube.com/watch?v=LmKKaN71wX0"><img src="https://i.ytimg.com/vi_webp/LmKKaN71wX0/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se inscreva no <a href="https://www.youtube.com/lucascaton?sub_confirmation=1">meu canal no YouTube</a>!</aside></p>
<p>Artigo comentado no vídeo:
<a href="https://www.lucascaton.com/2018/03/27/os-desafios-de-trabalhar-remotamente">Os desafios de trabalhar remotamente</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="cafe-com-caton" /><category term="freelancer" /><category term="trabalho-remoto" />
    </entry>

    <entry>
      <title><![CDATA[Como editar e reordenar seus commits no Git]]></title>
      <summary><![CDATA[Redescobri uma funcionalidade antiga, mas muito poderosa!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/07/24/como-editar-e-reordenar-seus-commits-no-git?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-07-24T03:06:21.000Z</published>
      <updated>2018-07-24T03:06:21.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/07/24/como-editar-e-reordenar-seus-commits-no-git</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/07/24/como-editar-e-reordenar-seus-commits-no-git">
        <![CDATA[<div xml:lang="pt-BR"><p>Redescobri uma funcionalidade antiga, mas muito poderosa!</p>
<p><a href="https://www.youtube.com/watch?v=WvjzmBz3mFU"><img src="https://i.ytimg.com/vi_webp/WvjzmBz3mFU/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Já conhecia? Já usa? Comente abaixo :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="git" />
    </entry>

    <entry>
      <title><![CDATA[Participei de um podcast sobre refatoração]]></title>
      <summary><![CDATA[Primeiro episódio do podcast "SouforceCast"]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/07/15/participei-de-um-podcast-sobre-refatoracao?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-07-15T02:31:40.000Z</published>
      <updated>2018-07-15T02:31:40.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/07/15/participei-de-um-podcast-sobre-refatoracao</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/07/15/participei-de-um-podcast-sobre-refatoracao">
        <![CDATA[<div xml:lang="pt-BR"><p>Olá meus caros!</p>
<p>Eu fui convidado pelo <a href="https://souforce.cloud">Fernando Sousa</a> para gravar um podcast sobre <em>refactoring</em>.
Esse é o primeiro episódio do podcast <a href="https://souforce.cloud/podcast/">SouforceCast</a> e ele já confirmou que vem mais por aí.</p>
<div>
<iframe width="400px" height="102px" src="https://anchor.fm/souforcecloud/embed/episodes/Episdio-1---Refactoring-e1pd97" frameborder="0" scrolling="no"></iframe>
</div>
<hr>
<p>Escute também pelo:</p>
<ul>
<li><a href="https://itunes.apple.com/br/podcast/souforce-cloud/id1410225197?l=en">iTunes</a></li>
<li><a href="https://pca.st/HOOP">PocketCasts</a></li>
</ul>
<p><a href="https://souforce.cloud/podcast/"><img src="/images/posts/2018/07/souforce-cast.png" alt="souforce-cast-logo"></a></p>
<p><aside>Aproveite para conhecer o <a href="https://www.lucascaton.com/podcast"><strong>meu podcast</strong></a> também!</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="refatoracao" /><category term="podcasts" />
    </entry>

    <entry>
      <title><![CDATA[Live: O que já sabemos sobre o Rails 6?]]></title>
      <summary><![CDATA[Gravamos uma live analisando as alterações recentes no código-fonte com o objetivo de descobrir o que vem por aí!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/07/14/live-o-que-ja-sabemos-sobre-o-rails-6?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-07-14T05:26:55.000Z</published>
      <updated>2020-11-15T05:55:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/07/14/live-o-que-ja-sabemos-sobre-o-rails-6</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/07/14/live-o-que-ja-sabemos-sobre-o-rails-6">
        <![CDATA[<div xml:lang="pt-BR"><p>Gravamos uma <em>live</em> analisando as alterações recentes no código-fonte com o objetivo de descobrir o que vem por aí no <strong>Rails 6</strong>:</p>
<p><a href="https://www.youtube.com/watch?v=5p07TQATjjI"><img src="https://i.ytimg.com/vi_webp/5p07TQATjjI/maxresdefault.webp" alt="YouTube video" /></a></p>
<h3>Links comentados no vídeo:</h3>
<ul>
<li><a href="https://www.youtube.com/watch?v=8evXWvM4oXM">RailsConf 2018 - The Future of Rails 6</a></li>
<li><a href="https://github.com/rails/rails/milestone/63">Milestone "Rails 6"</a></li>
<li><a href="https://github.com/rails/rails/pull/33079/files">PR "Make Webpacker the default JavaScript compiler"</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="rails" /><category term="live" />
    </entry>

    <entry>
      <title><![CDATA[Eu não faço isso aqui para ganhar dinheiro... eu ganho dinheiro para fazer isso aqui!]]></title>
      <summary><![CDATA[Abri meu coração e honestamente contei todos os meus planos]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/06/24/eu-nao-faco-isso-aqui-para-ganhar-dinheiro-eu-ganho-dinheiro-para-fazer-isso-aqui?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-06-24T08:51:27.000Z</published>
      <updated>2018-06-24T08:51:27.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/06/24/eu-nao-faco-isso-aqui-para-ganhar-dinheiro-eu-ganho-dinheiro-para-fazer-isso-aqui</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/06/24/eu-nao-faco-isso-aqui-para-ganhar-dinheiro-eu-ganho-dinheiro-para-fazer-isso-aqui">
        <![CDATA[<div xml:lang="pt-BR"><p>Abri meu coração e honestamente contei todos os meus planos:</p>
<p><a href="https://www.youtube.com/watch?v=-Q-Y-4a2QNo"><img src="https://i.ytimg.com/vi_webp/-Q-Y-4a2QNo/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="curso" />
    </entry>

    <entry>
      <title><![CDATA[Mini-curso sobre Git & GitHub]]></title>
      <summary><![CDATA[Aprenda o básico em menos de 2 horas! (gratuito)]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/06/10/mini-curso-sobre-git-github?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-06-09T23:26:00.000Z</published>
      <updated>2018-06-09T23:26:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/06/10/mini-curso-sobre-git-github</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/06/10/mini-curso-sobre-git-github">
        <![CDATA[<div xml:lang="pt-BR"><p>Abaixo você encontrará um mini-curso que foi originalmente gravado para os alunos
do <a href="https://www.lucascaton.com/cursos/cplc/">meu curso</a>). O objetivo é aprender o
básico do <strong>Git</strong> (ferramenta) e do <strong>GitHub</strong> (plataforma).</p>
<h2>Parte 1</h2>
<p><a href="https://www.youtube.com/watch?v=hwDRjlCj4Po"><img src="https://i.ytimg.com/vi_webp/hwDRjlCj4Po/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Parte 2</h2>
<p><a href="https://www.youtube.com/watch?v=7hDUkR830_I"><img src="https://i.ytimg.com/vi_webp/7hDUkR830_I/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Parte 3</h2>
<p><a href="https://www.youtube.com/watch?v=7FgUQ_AKaEg"><img src="https://i.ytimg.com/vi_webp/7FgUQ_AKaEg/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Parte 4</h2>
<p><a href="https://www.youtube.com/watch?v=WxSmPnbkO8w"><img src="https://i.ytimg.com/vi_webp/WxSmPnbkO8w/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Parte 5</h2>
<p><a href="https://www.youtube.com/watch?v=kj5JMvLOdaU"><img src="https://i.ytimg.com/vi_webp/kj5JMvLOdaU/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Parte 6</h2>
<p><a href="https://www.youtube.com/watch?v=qF7hue4Ef4E"><img src="https://i.ytimg.com/vi_webp/qF7hue4Ef4E/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<h2>Como instalar o Git</h2>
<p>O processo de instalação do Git é simples, basta seguir as instruções do site oficial:</p>
<ul>
<li><strong>Windows</strong>: <a href="https://git-scm.com/download/win">git-scm.com/download/win</a></li>
<li><strong>Linux/Unix</strong>: <a href="https://git-scm.com/download/linux">git-scm.com/download/linux</a></li>
<li><strong>macOS</strong> (se você tiver <a href="https://brew.sh/">Homebrew</a> instalado): <code>$ brew install git</code></li>
<li><strong>macOS</strong> (sem usar o Homebrew): <a href="https://git-scm.com/download/mac">git-scm.com/download/mac</a></li>
</ul>
<h2>Criar uma conta no GitHub:</h2>
<p><a href="https://github.com/join">https://github.com/join</a></p>
<h2>Configurar seu nome de usuário no Git:</h2>
<p><a href="https://help.github.com/articles/setting-your-username-in-git/">https://help.github.com/articles/setting-your-username-in-git/</a></p>
<h2>Autenticar no GitHub:</h2>
<p><a href="https://help.github.com/articles/set-up-git/">https://help.github.com/articles/set-up-git/</a></p>
<h2>Comandos usados nas videoaulas:</h2>
<ul>
<li><code>git init</code></li>
<li><code>git add README.md</code></li>
<li><code>git status</code></li>
<li><code>git commit -m "Create README.md"</code></li>
<li><code>git log</code></li>
<li><code>git diff README.md</code></li>
<li><code>git revert [hash]</code></li>
<li><code>git show</code></li>
<li><code>git push</code></li>
<li><code>git checkout -b nova_funcionalidade</code></li>
<li><code>git branch</code></li>
<li><code>git branch -a</code></li>
<li><code>git checkout nova_funcionalidade</code></li>
<li><code>git checkout master</code></li>
</ul>
<h2>Artigos relacionados:</h2>
<ul>
<li><a href="https://www.lucascaton.com/2017/10/16/como-escrever-mensagens-de-commits-no-git">Como escrever mensagens de commits no Git</a></li>
<li><a href="https://www.lucascaton.com/2016/02/23/why-i-regenerated-my-ssh-key-and-maybe-you-should-too">Como eu migrei de chaves SSH para HTTPS no Git/GitHub</a> (em inglês)</li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="mini-curso" /><category term="git" /><category term="github" />
    </entry>

    <entry>
      <title><![CDATA[3 atitudes para ser feliz no trabalho]]></title>
      <summary><![CDATA[Uma compilação de atitudes que eu aprendi (e me policio para continuar tendo) para manter meu emprego atual de forma saudável.]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/05/17/3-atitudes-para-ser-feliz-no-trabalho?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-05-17T08:54:20.000Z</published>
      <updated>2018-05-17T08:54:20.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/05/17/3-atitudes-para-ser-feliz-no-trabalho</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/05/17/3-atitudes-para-ser-feliz-no-trabalho">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2018/05/3-atitudes-para-ser-feliz-no-trabalho.jpg" alt="3 colegas tomando café e usando um laptop"></p>
<p>Você provavelmente conhece alguém que não consegue trabalhar na mesma empresa por mais de um ano.
Eu conheço pessoas que, em menos tempo que isso, já estão doidas para procurar outro trabalho.</p>
<p>Comecei a trabalhar aos 16 anos, em 2004, como estagiário em uma secretaria da universidade onde eu estudava.
Nessa época eu só programava na faculdade, por hobby e eventualmente fazendo um <em>"freela"</em> (trabalho <em>freelance</em>).
Em 2007, comecei a finalmente trabalhar profissionalmente com programação, passando por várias empresas, grandes e pequenas.</p>
<p>Desde então, minha meta pessoal é não ficar menos que um ano trabalhando em uma empresa; meu tempo recorde foi 3 anos e meio.
<strong>O fato é que não existe um tempo ideal para deixar o que já é certo para se aventurar em algo novo.</strong>
São muitas variáveis em jogo e cada um sabe onde o calo aperta.</p>
<p>Se você ficar muito tempo na mesma empresa, pode ficar acomodado (a famigerada "zona de conforto"),
pode se desapegar (às vezes inconscientemente) da sua carreira, deixar de aprender coisas novas e deixar de fazer novos colegas/amigos.
Por outro lado, conquista estabilidade, autoridade, pode ser promovido e eventualmente tem um aumento de salário.</p>
<p>Já ficando pouco tempo em uma empresa, lhe dá a oportunidade de experimentar diferentes ambientes/culturas em diferentes companhias.
Esta também poderia ser uma boa hora para negociar um salário melhor, caso você julgue justo.
Mas também tem seus pontos negativos, por exemplo ganhar uma má reputação, ou mesmo não conseguir ter disciplina.</p>
<p><img src="/images/posts/2018/05/mulher-no-escritorio.jpg" alt="ser-feliz-no-trabalho"></p>
<p>Trocar de empresa, ingenuamente, apenas para resolver um determinado problema,
é <strong>negligenciar o fato de que a nova empresa terá problemas que a atual não tem.</strong></p>
<p>Na minha perspectiva, a regra de ouro é: se você tem um problema,
<strong>use bons argumentos para defender o que você acredita,
mas também saiba ser humilde e admitir quando você estiver errado.</strong></p>
<p>Mas o ponto principal desse artigo é: durante um emprego, você vai procurar dar o melhor de si
e torcer para receber o melhor da empresa, certo?
Abaixo você encontrará uma compilação de 3 atitudes que eu aprendi (e me policio para continuar tendo)
para manter meu emprego atual de forma saudável.</p>
<h2>1. Seja responsável</h2>
<p>Esteja alinhado com os objetivos da empresa.
Se você não concorda com o caminho que a empresa está seguindo, <strong>talvez fosse melhor nem ter começado lá</strong>.</p>
<p>Coisas pequenas contam: não se atrase para reuniões, mantenha pessoas atualizadas sobre problemas
que estão acontecendo, não falte a toa com desculpas esfarrapadas, etc.</p>
<h2>2. Seja amigável/respeitoso com colegas</h2>
<blockquote>
<p>“Todas as pessoas que você conhece estão enfrentando batalhas que você não sabe nada a respeito. Seja gentil. Sempre.”</p>
</blockquote>
<p>Acho sensacional a frase acima (sem autor conhecido, pelo que eu pesquisei).
Não julgue aquele colega que não está produtivo hoje,
pois você não sabe se ele perdeu um ente querido, se ele está com dor ou problema de saúde,
com problemas financeiros, ou tantas outras coisas possíveis.
<strong>Seja empático; jamais desrespeite alguém.</strong></p>
<p>Inevitavelmente, uma hora acontece algum desentendimento. Dependendo da gravidade, esfrie a cabeça,
talvez seja melhor deixar pra tentar se entender mais tarde ou até no dia seguinte.
Certos desentendimentos se resolvem simplesmente ao esperar a poeira baixar.
Pode ser que nem era algo tão grave e no calor do momento você/ele/ela acabou exagerando.</p>
<h2>3. Busque um emprego recompensador</h2>
<p>Realisticamente falando, não adianta você fazer a sua parte e não ser recompensado.
Esse provavelmente seria o cenário no qual você logo estaria procurando por outro emprego.</p>
<p>Busque um salário e uma posição justa para o momento presente de sua carreira.
Peça <em>feedback</em> caso não receba, só assim você alinha suas expectativas com as da empresa.
Seu trabalho deve ser saudável, em todos os aspectos, e nunca consumir toda sua energia física ou mental.</p>
<p><strong>Trabalhar com o que você ama, faz com que você não gaste sua vida apenas
trocando seu tempo/esforço pelo dinheiro no final do mês.</strong></p>
<p><img src="/images/posts/2018/05/ser-feliz-no-trabalho.jpg" alt="ser-feliz-no-trabalho"></p>
<h2>Tem como ser 100% feliz no seu emprego?</h2>
<p>Mesmo que você encontre o trabalho perfeito, tudo sempre vai poder mudar.
Colegas que você gosta pedem demissões, os diretores/gerentes mudam,
seu salário aumenta menos do que o esperado, um novo funcionário é contratado e você não o suporta.
Qualquer uma dessas mudanças contribuem para o desequilibro de um suposto emprego perfeito.</p>
<p><strong>Empresa perfeita é utopia. Assim como você também não é um funcionário perfeito, nem nunca será.</strong></p>
<p>Além disso, que graça teria uma vida sem desafios? 🙂</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="carreira" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: sacadas para estudar inglês que demorei para aprender]]></title>
      <summary><![CDATA[Queria que alguém tivesse me ensinado isso 10 anos atrás]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/05/05/video-sacadas-para-estudar-ingles-que-demorei-para-aprender?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-05-05T04:20:06.000Z</published>
      <updated>2018-05-05T04:20:06.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/05/05/video-sacadas-para-estudar-ingles-que-demorei-para-aprender</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/05/05/video-sacadas-para-estudar-ingles-que-demorei-para-aprender">
        <![CDATA[<div xml:lang="pt-BR"><p>Algumas técnicas que uso até hoje para estudar inglês.
Queria que alguém tivesse me ensinado isso 10 anos atrás! 🙂</p>
<p><a href="https://www.youtube.com/watch?v=XCrb3dgoYGM"><img src="https://i.ytimg.com/vi_webp/XCrb3dgoYGM/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside><a href="https://www.youtube.com/lucascaton?sub_confirmation=1">Clique aqui</a> para se inscrever no meu canal no YouTube!</aside></p>
<p>Outros vídeos comentados no vídeo acima:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=rDacKeqsvNM">5 formas de aprender inglês de graça</a></li>
<li><a href="https://www.youtube.com/watch?v=5d5bkbWybqc">8 motivos para programar em inglês</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="ingles" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Aprenda Active Storage - parte 2]]></title>
      <summary><![CDATA[Aprenda a fazer upload de arquivos para o AWS S3, usar direct upload sem passar pelo seu servidor e também a enviar múltiplos arquivos de uma vez]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/04/17/video-aprenda-active-storage-parte-2?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-04-17T08:27:52.000Z</published>
      <updated>2018-04-17T08:27:52.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/04/17/video-aprenda-active-storage-parte-2</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/04/17/video-aprenda-active-storage-parte-2">
        <![CDATA[<div xml:lang="pt-BR"><p>Há 3 dias, publiquei <a href="https://www.lucascaton.com/2018/04/14/video-aprenda-active-storage-parte-1">o primeiro vídeo desta série</a>
sobre <strong>Active Storage</strong>, o grande destaque do <strong>Rails 5.2</strong>; recomendo que você o veja antes de assistir este.</p>
<p>Nesse segundo vídeo, vou mostrar como configurar o <strong>Active Storage</strong> para:</p>
<ul>
<li>Fazer <em>upload</em> de arquivos para o <strong>AWS S3</strong> (serviço de armazenamento de arquivos da <strong>Amazon</strong>);</li>
<li>Usar o <strong><em>direct upload</em></strong> (envio de arquivos do navegador diretamente para o <strong>S3</strong>, sem passar pelo seu servidor);</li>
<li>Fazer <em>upload</em> de <strong>vários arquivos</strong> de uma só vez.</li>
</ul>
<p><a href="https://www.youtube.com/watch?v=ZwkAqZ5lty4"><img src="https://i.ytimg.com/vi_webp/ZwkAqZ5lty4/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<ul>
<li><a href="https://www.lucascaton.com/2018/04/14/video-aprenda-active-storage-parte-1">Assista a <strong>parte 1</strong> dessa série</a></li>
<li><a href="http://guides.rubyonrails.org/active_storage_overview.html">Guia oficial do <strong>Active Storage</strong></a></li>
</ul>
<hr>
<p>Arquivos alterados no vídeo:</p>
<h3><code>config/storage.yml</code></h3>
<pre><code class="language-yaml"># ...
amazon:
  service: S3
  access_key_id: xxxxxxxxxxxxxxxxxxxx
  secret_access_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  region: xxxxxxxxxxxxxx
  bucket: xxxxxxx
# ...
</code></pre>
<h3><code>config/environments/development.rb</code></h3>
<pre><code class="language-ruby"># ...
config.active_storage.service = :amazon
# ...
</code></pre>
<h3><code>app/assets/javascripts/application.js</code></h3>
<pre><code class="language-javascript">// ...
//= require activestorage
// ...
</code></pre>
<h3><code>app/models/post.rb</code></h3>
<pre><code class="language-ruby">class Post &#x3C; ApplicationRecord
  has_many_attached :images
end
</code></pre>
<h3><code>app/controllers/posts_controller.rb</code></h3>
<pre><code class="language-ruby">class PostsController &#x3C; ApplicationController
  # ...
  def post_params
    params.require(:post).permit(:title, :body, images: [])
  end
end
</code></pre>
<h3><code>app/views/posts/_form.html.erb</code></h3>
<pre><code class="language-erb">&#x3C;!-- ... -->
&#x3C;div class="field">
  &#x3C;%= form.label :images %>
  &#x3C;%= form.file_field :images, direct_upload: true, multiple: true %>
&#x3C;/div>
&#x3C;!-- ... -->
</code></pre>
<h3><code>app/views/posts/show.html.erb</code></h3>
<pre><code class="language-erb">&#x3C;!-- ... -->
&#x3C;% @post.images.each do |image| %>
  &#x3C;%= image_tag image, style: 'width: 25%' %>
&#x3C;% end %>
&#x3C;!-- ... -->
</code></pre>
<h3><code>app/assets/javascripts/direct_uploads.js</code></h3>
<pre><code class="language-javascript">addEventListener("direct-upload:initialize", event => {
  const { target, detail } = event
  const { id, file } = detail
  target.insertAdjacentHTML("beforebegin", `
    &#x3C;div id="direct-upload-${id}" class="direct-upload direct-upload--pending">
      &#x3C;div id="direct-upload-progress-${id}" class="direct-upload__progress" style="width: 0%">&#x3C;/div>
      &#x3C;span class="direct-upload__filename">${file.name}&#x3C;/span>
    &#x3C;/div>
  `)
})
addEventListener("direct-upload:start", event => {
  const { id } = event.detail
  const element = document.getElementById(`direct-upload-${id}`)
  element.classList.remove("direct-upload--pending")
})
addEventListener("direct-upload:progress", event => {
  const { id, progress } = event.detail
  const progressElement = document.getElementById(`direct-upload-progress-${id}`)
  progressElement.style.width = `${progress}%`
})
addEventListener("direct-upload:error", event => {
  event.preventDefault()
  const { id, error } = event.detail
  const element = document.getElementById(`direct-upload-${id}`)
  element.classList.add("direct-upload--error")
  element.setAttribute("title", error)
})
addEventListener("direct-upload:end", event => {
  const { id } = event.detail
  const element = document.getElementById(`direct-upload-${id}`)
  element.classList.add("direct-upload--complete")
})
</code></pre>
<h3><code>app/assets/stylesheets/direct_uploads.css</code></h3>
<pre><code class="language-css">.direct-upload {
  display: inline-block;
  position: relative;
  padding: 2px 4px;
  margin: 0 3px 3px 0;
  border: 1px solid rgba(0, 0, 0, 0.3);
  border-radius: 3px;
  font-size: 11px;
  line-height: 13px;
}
.direct-upload--pending {
  opacity: 0.6;
}
.direct-upload__progress {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  opacity: 0.2;
  background: #0076ff;
  transition: width 120ms ease-out, opacity 60ms 60ms ease-in;
  transform: translate3d(0, 0, 0);
}
.direct-upload--complete .direct-upload__progress {
  opacity: 0.4;
}
.direct-upload--error {
  border-color: red;
}
input[type=file][data-direct-upload-url][disabled] {
  display: none;
}
</code></pre>
<p>Qualquer dúvida, mande nos comentários!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="active-storage" /><category term="rails" /><category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Aprenda Active Storage - parte 1]]></title>
      <summary><![CDATA[Gravei um vídeo rápido demonstrando o funcionamento do Active Storage, o grande destaque do Rails 5.2.]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/04/14/video-aprenda-active-storage-parte-1?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-04-14T01:15:25.000Z</published>
      <updated>2018-04-14T01:15:25.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/04/14/video-aprenda-active-storage-parte-1</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/04/14/video-aprenda-active-storage-parte-1">
        <![CDATA[<div xml:lang="pt-BR"><p>Há poucos dias, escrevi um
<a href="https://www.lucascaton.com/2018/04/10/rails-5-2-acaba-de-ser-lancado-confira-o-que-ha-de-novo">artigo falando sobre as novidades do Rails 5.2</a>,
lançado recentemente.</p>
<p>Hoje gravei o primeiro vídeo de <a href="https://www.lucascaton.com/tags/active-storage/">uma série</a>
demonstrando o funcionamento do <strong>Active Storage</strong>, o grande destaque do <strong>Rails 5.2</strong>:</p>
<p><a href="https://www.youtube.com/watch?v=RE0V3SqRIYM"><img src="https://i.ytimg.com/vi_webp/RE0V3SqRIYM/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside><a href="https://www.lucascaton.com/2018/04/17/video-aprenda-active-storage-parte-2">Assista a parte 2</a>: upload de arquivos para o AWS S3, <em>direct upload</em> sem passar pelo seu servidor e enviar múltiplos arquivos de uma vez.</aside></p>
<hr>
<p>Comandos executados no vídeo:</p>
<pre><code class="language-bash">$ rails new active_storage_demo -d postgresql
$ cd active_storage_demo
$ atom .
</code></pre>
<pre><code class="language-bash">$ rails generate scaffold post title body:text
$ rails db:create db:migrate
</code></pre>
<pre><code class="language-bash">$ rails active_storage:install
$ rails db:migrate
</code></pre>
<pre><code class="language-bash">$ rails s
</code></pre>
<hr>
<p>Arquivos alterados no vídeo:</p>
<h3><code>app/models/post.rb</code></h3>
<pre><code class="language-ruby">class Post &#x3C; ApplicationRecord
  has_one_attached :image
end
</code></pre>
<h3><code>app/controllers/posts_controller.rb</code></h3>
<pre><code class="language-ruby">class PostsController &#x3C; ApplicationController
  # ...
  def post_params
    params.require(:post).permit(:title, :body, :image)
  end
end
</code></pre>
<h3><code>app/views/posts/_form.html.erb</code></h3>
<pre><code class="language-erb">&#x3C;%= form_with(model: post, local: true, multipart: true) do |form| %>
&#x3C;!-- ... -->
&#x3C;div class="field">
  &#x3C;%= form.label :image %>
  &#x3C;%= form.file_field :image %>
&#x3C;/div>
&#x3C;!-- ... -->
</code></pre>
<h3><code>app/views/posts/show.html.erb</code></h3>
<pre><code class="language-erb">&#x3C;!-- ... -->
&#x3C;%= image_tag @post.image %>
&#x3C;!-- ... -->
</code></pre>
<p><aside><a href="https://www.lucascaton.com/2018/04/17/video-aprenda-active-storage-parte-2">Assista a parte 2</a>: upload de arquivos para o AWS S3, <em>direct upload</em> sem passar pelo seu servidor e enviar múltiplos arquivos de uma vez.</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="active-storage" /><category term="rails" /><category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[Rails 5.2 acaba de ser lançado; confira o que há de novo!]]></title>
      <summary><![CDATA[Grandes novidades nesta nova versão!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/04/10/rails-5-2-acaba-de-ser-lancado-confira-o-que-ha-de-novo?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-04-10T09:34:47.000Z</published>
      <updated>2018-04-10T09:34:47.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/04/10/rails-5-2-acaba-de-ser-lancado-confira-o-que-ha-de-novo</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/04/10/rails-5-2-acaba-de-ser-lancado-confira-o-que-ha-de-novo">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2018/04/rails-5.2.jpg" alt="Uma ferrovia atravessando o mar"></p>
<p>A nova versão do Rails estava em beta (e rc<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref aria-describedby="footnote-label">1</a></sup>) desde novembro do ano passado
e agora está finalmente disponível para todos!</p>
<p>Foram <a href="https://github.com/rails/rails/compare/v5.1.6...v5.2.0">quase 5000 commits</a> (!)
de <a href="http://contributors.rubyonrails.org/releases/5-2-0/contributors">440 desenvolvedores</a>,
incluindo uma pequena <a href="https://github.com/rails/rails/pull/29340">contribuição deste que vos escreve</a>.</p>
<p>Algumas novidades presentes nesta nova versão:</p>
<h2>Active Storage</h2>
<p>Sem dúvidas, o destaque da vez.</p>
<p>Desde quando foi lançado, o <strong>Ruby on Rails</strong> tem a premissa de ser um <a href="https://www.youtube.com/watch?v=SsYKd37r26s">framework completo</a>.
O <strong>Active Storage</strong> foi adicionado ao Rails justamente para suprir uma funcionalidade a qual antes dependia de ferramentas de terceiros: <em>upload</em> de arquivos.</p>
<p>O <em>framework</em> traz suporte nativo aos serviços <strong>Amazon S3</strong>, <strong>Google Cloud Storage</strong> e <strong>Microsoft Azure Storage</strong>.
A <a href="https://github.com/rails/rails/blob/5-2-stable/activestorage/README.md#compared-to-other-storage-solutions">abordagem</a>
utilizada simplifica a tarefa e vem com recursos bacanas, como
<a href="https://github.com/rails/rails/blob/5-2-stable/activestorage/README.md#direct-uploads"><em>uploads</em> direto para a nuvem</a>
(sem passar pelo seu servidor antes) e criação de
<a href="https://github.com/rails/rails/blob/5-2-stable/activestorage/README.md#examples"><em>thumbnails</em></a>
(miniaturas) de imagens, PDFs e até mesmo vídeos.</p>
<p><aside>Ah, eu gravei uma <a href="https://www.lucascaton.com/tags/active-storage/">série de vídeos sobre Active Storage</a>! 😉</aside></p>
<p><aside>Curiosidade: <strong>Active Storage</strong> é mais um caso de código que foi extraído do <a href="https://basecamp.com/">Basecamp</a>, da empresa fundada por <a href="https://twitter.com/dhh">DHH</a>, criador do Rails.</aside></p>
<h2>HTTP/2 Early Hints</h2>
<p>Rails agora suporta uma das coisas mais legais do <strong>HTTP/2</strong>:
poder instruir o servidor (como o <strong>Puma</strong>, que já <a href="https://github.com/puma/puma/pull/1403">suporta isso</a>)
para enviar antecipadamente arquivos JS e CSS. Isso se traduz em uma entrega mais rápida das páginas.</p>
<h2>Boot 50% mais rápido</h2>
<p>A gem <a href="https://github.com/Shopify/bootsnap"><strong>Bootsnap</strong></a> reduz o tempo para subir um servidor em 50%
e a partir do <strong>Rails 5.2</strong>, ela é adicionada por padrão em novos projetos.
Você também pode usá-la em projetos usando versões antigas do Rails, basta adicioná-la ao seu <code>Gemfile</code>.</p>
<h2>CSP (Content Security Policy)</h2>
<p>Uma nova DSL<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref aria-describedby="footnote-label">2</a></sup> foi adicionada para configurar <em>headers</em> <code>Content-Security-Policy</code>,
através da qual você poderá melhorar a segurança da sua aplicação.</p>
<h2>Credentials</h2>
<p>O arquivo de configuração <code>secrets.yml</code> foi criado no Rails 4.1
e transformado em um arquivo criptografado no Rails 5.1.
Só que isso sempre foi meio confuso e alguns desenvolvedores não sabiam exatamente
como (ou por qual motivo) usar, já que <em>envvars</em><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref aria-describedby="footnote-label">3</a></sup> resolviam o problema.</p>
<p>Para <del>tentar</del> resolver a confusão, agora foi criado o conceito de <strong>Credentials</strong>,
descontinuando o suporte ao <code>secret.yml</code> (e sua versão criptografada).</p>
<p>Se isso resolverá mesmo o problema e cairá no gosto dos desenvolvedores, só o tempo dirá!</p>
<h2>Suporte à gem Webpacker 3.0</h2>
<p>Rails vem adotando soluções modernas para uso de <strong>JavaScript</strong> e manter uma boa integração
com a gem <a href="https://github.com/rails/webpacker"><strong>Webpacker</strong></a> prova isso mais uma vez.</p>
<h2>Redis Cache Store</h2>
<p>Suporte nativo à cache usando <strong>Redis</strong>. Você encontra mais informações no
<a href="https://github.com/rails/rails/pull/31134/files"><em>pull request</em> em que esta funcionalidade foi adicionada</a>.</p>
<h2>O que mais?</h2>
<p>Obviamente, existe mais coisas que mudaram/evoluíram além dos destaques que listei acima.
As <a href="http://edgeguides.rubyonrails.org/5_2_release_notes.html">notas de liberação</a>
contém algumas dessas mudanças menos relevantes, caso você esteja interessado.</p>
<h2>Como atualizar?</h2>
<p>Atualmente, atualizar um projeto para uma nova versão do Rails é uma tarefa relativamente tranquila
(principalmente se comparada com as transições da versão 2 para a 3).</p>
<p>Eis o <a href="http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-5-1-to-rails-5-2">guia oficial para atualizar</a>.</p>
<p><aside>Uma boa cobertura de testes automatizados é altamente recomendada!</aside></p>
<h2>Rails 6?</h2>
<p>Seguindo a tradição, essa será a última versão da série <code>5.*</code>.
O branch <code>master</code> do repositório do Rails já contém mudanças que só virão no <strong>Rails 6</strong>,
o qual provavelmente veremos daqui a aproximadamente 1 ano e meio, se o histórico de lançamentos for similar aos que tivemos até hoje.</p>
<hr>
<section data-footnotes class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes</h2>
<ol>
<li id="user-content-fn-1">
<p><em>Release Candidates</em>: versões beta com potencial para serem a versão final <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
<li id="user-content-fn-2">
<p><em>Domain-specific language</em> (Linguagem de domínio específico): métodos ou códigos específicos dedicados à um domínio de problema particular <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref">↩</a></p>
</li>
<li id="user-content-fn-3">
<p><em>Environment Variables</em> (variáveis de ambiente): configurações disponíveis "globalmente" em um computador ou servidor <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="rails" /><category term="active-storage" />
    </entry>

    <entry>
      <title><![CDATA[Os desafios de trabalhar remotamente]]></title>
      <summary><![CDATA[Uma lista com os desafios mais comuns ao trabalhar remotamente e como enfrentá-los]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/03/27/os-desafios-de-trabalhar-remotamente?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-03-27T08:51:35.000Z</published>
      <updated>2018-03-27T08:51:35.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/03/27/os-desafios-de-trabalhar-remotamente</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/03/27/os-desafios-de-trabalhar-remotamente">
        <![CDATA[<div xml:lang="pt-BR"><p>Desde o começo de 2017, eu venho trabalhando remotamente 100% do tempo.
Atualmente isso é algo <a href="https://open.buffer.com/state-remote-work-2018/">muito comum</a>,
não apenas em empresas de tecnologia.
Quem mora em cidade grande e enfrenta trânsito ou corre risco de ser assaltado,
sabe o quanto é vantajoso não precisar de sair de casa para trabalhar.</p>
<p><img src="/images/posts/2018/03/home-office.jpg" alt="home-office"></p>
<p>{: .img-description }
Meu escritório atual (aka. <em>home office</em>)
<br>
<br></p>
<p>As vantagens são muitas. Uma das que eu mais aprecio é poder ver cada progresso do meu filho (que está com 1 ano e meio).
<strong>É uma forma de trocar o tempo gasto se locomovendo por tempo com sua família e/ou fazendo o que você gosta</strong>.</p>
<p>Outro ponto positivo é que a empresa nunca contratará alguém que more perto apenas por esse fato isolado;
você trabalhará com as melhores pessoas que sua empresa encontrou sem ter a localização como fator limitante, como o <em>tweet</em> abaixo assertivamente ilustra:</p>
<blockquote class="twitter-tweet"><p lang="und" dir="ltr">[pic.twitter.com/DO3xDPBmIE](https://t.co/DO3xDPBmIE)</p>&mdash; Mark Dalgleish (@markdalgleish) [March 16, 2018](https://twitter.com/markdalgleish/status/974447526282539008?ref_src=twsrc%5Etfw)</blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<br>
<br>
<p>Porém nem tudo são flores.</p>
<h2>Desafios (e soluções)</h2>
<p>Depois de 15 meses trabalhando em casa, identifiquei os desafios mais comuns
e vou listá-los abaixo, junto com as soluções que encontrei.
Caso eu tenha esquecido de algum, fique a vontade para mandar comentários no final deste artigo.</p>
<h3>Comunicação</h3>
<p>Existem várias ferramentas de chat como <a href="https://slack.com/">Slack</a> e <a href="https://rocket.chat/">Rocket Chat</a>
(as quais podemos chamar de versões modernas do <a href="https://pt.wikipedia.org/wiki/Internet_Relay_Chat">IRC</a>),
que ajudam a <strong>manter a equipe toda atualizada com o que está acontecendo na empresa</strong>, em projetos, etc.</p>
<p>Dizer no chat "bom dia" ou "vou ficar ausente por 15 minutos",
não apenas mostra que você é educado, como também permite que todo mundo fique sabendo se você está ou não disponível.
Também é útil ativar notificações para saber quando alguém precisa da sua atenção.
Só cuidado para não deixá-las ligadas fora do horário de trabalho e
<a href="https://medium.com/o-novo-mercado/o-que-diabos-aconteceu-com-gera%C3%A7%C3%A3o-y-73cd16ccc5c9">virar um escravo</a>.</p>
<p>Os bons e velhos <a href="https://hangouts.google.com/">Hangouts</a> e <a href="https://www.skype.com/pt-br/">Skype</a>
continuam excelentes para comunicação por voz/vídeo, incluindo compartilhamento de tela para demonstrar algum trabalho.
Eu também gosto de <a href="https://www.lucascaton.com/2018/02/04/como-gravar-screencasts-em-formato-gif-no-macos">gravar screencasts em formato GIF</a>
para compartilhar com o time.</p>
<h3>Lugar privado para trabalhar</h3>
<p>Quando eu me mudei para a casa onde moro hoje, procurei um lugar com um quarto extra,
pois já estava trabalhando remotamente e sabia que seria importante.</p>
<p>Você até pode trabalhar da sala, cozinha ou do seu próprio quarto por um tempo
(talvez pra fazer um teste e ver se trabalhar dessa forma funciona pra você?).
Porém, se trabalhar remoto é algo que você planeja fazer por mais tempo,
é importante <strong>ter um espaço privado para fazer reuniões, evitar distrações
e se manter focado no trabalho</strong> (sem seu filho gritando do seu lado).</p>
<h3>Disciplina</h3>
<p>Chances são que a Netflix e o Playstation serão (discutivelmente) mais atrativos do que seu trabalho.
Aqui a solução é <strong>ser maduro o suficiente pra entender que a empresa confia em você</strong>, portanto faça o que é esperado.</p>
<blockquote class="twitter-tweet" data-lang="pt" data-theme="light"><p lang="en" dir="ltr">Top Traits of Successful Remote Workers<br>* Strong communicators 💬<br>* Motivated self-starters 💪<br>* Results-oriented 📈<br>* Collaborative 🙎🏽👨🏻‍💼<br>* Trustworthy 🤝<br>* Disciplined ✅<br>* Organized 🗂</p>&mdash; Doist (@doist) [26 de fevereiro de 2018](https://twitter.com/doist/status/968191855228850176?ref_src=twsrc%5Etfw)</blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<h3>Conexão boa/confiável com a internet</h3>
<p>Isso provavelmente é essencial para a maioria das profissões.
Apesar de eu nunca ter tido problemas com o meu provedor,
<strong>eu sempre tenho uma conexão 4G de backup, caso algum problema aconteça</strong>.</p>
<h3>Fuso-horário diferente</h3>
<p>Trabalhar remoto significa que você (e seus colegas de trabalho) podem estar em qualquer parte do mundo.
Se for o caso, nem todo mundo irá necessariamente trabalhar no mesmo horário.
Consequentemente, <strong>é importante ter uma forma de deixar as pessoas saberem no que você está trabalhando e qual o <em>status</em> da sua tarefa atual</strong>.
Ferramentas de gerenciamento de projetos como o <a href="https://kanbanflow.com/">KanbanFlow</a>,
<a href="https://www.pivotaltracker.com/">Pivotal Tracker</a> e <a href="https://trello.com/">Trello</a> são ótimas para isso.</p>
<h3>Você vê colegas/amigos menos frequentemente</h3>
<p>Eu pensava que essa seria a pior parte.
Mas o fato é que usando ferramentas de <em>chat</em> mencionadas acima, isso nunca foi um problema pra mim.
Porém sair com amigos de vez em quando, mesmo que apenas para um café, ajuda a manter sua sanidade mental.</p>
<h3>Ferramentas de trabalho</h3>
<p>É importante ter um <em>home office</em> com tudo que você precisa para trabalhar:
uma mesa/escrivaninha, uma cadeira e um notebook são essenciais (no meu caso; tudo depende do tipo de trabalho que você faz).</p>
<p>Outras coisas podem não ser essenciais, mas melhoram a qualidade do trabalho: ar condicionado, monitor externo, máquina de café
e <strong>tudo que fizer a experiência de trabalhar de casa ser tão boa quanto a experiência de trabalhar em um escritório</strong>.
Você não precisa comprar tudo de uma vez, principalmente se for sua primeira vez trabalhando de casa.</p>
<h3>Saúde</h3>
<p>Ao ficar em casa o dia todo, você pode desenvolver problemas de saúde. Evitar isso não é tão difícil:</p>
<ul>
<li>Faça exercícios (uma caminhada diária já é melhor que nada)</li>
<li>Se alimente de forma saudável</li>
<li>Tenha uma cadeira confortável</li>
<li>Vá ao <del>Google</del> médico se notar que tem algo errado</li>
</ul>
<h2>Conclusão</h2>
<p>Trabalhar de casa pode não ser pra todo mundo.
Experimente alguns dias por semana primeiro, caso a empresa que você trabalhe permita isso.</p>
<p>Mas definitivamente vale a pena experimentar, as vantagens são muitas!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="trabalho-remoto" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: RubyConf Austrália 2018]]></title>
      <summary><![CDATA[Resumo de como foi o evento através de stories do Instagram]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/03/07/rubyconf-australia-2018?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-03-06T22:29:35.000Z</published>
      <updated>2018-03-06T22:29:35.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/03/07/rubyconf-australia-2018</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/03/07/rubyconf-australia-2018">
        <![CDATA[<div xml:lang="pt-BR"><p>Resumo de como foi o evento através de <a href="https://www.instagram.com/lucascaton.com.br/">stories do Instagram</a>:</p>
<p><a href="https://www.youtube.com/watch?v=jQrhOVn0q5A"><img src="https://i.ytimg.com/vi_webp/jQrhOVn0q5A/maxresdefault.webp" alt="YouTube video" /></a></p>
<ul>
<li>Meu instagram: <a href="https://www.instagram.com/lucascaton.com.br/">@lucascaton.com.br</a></li>
<li>Site oficial do evento: <a href="https://www.rubyconf.org.au/2018">www.rubyconf.org.au/2018</a></li>
<li>Twitter oficial do evento: <a href="https://twitter.com/rubyconf_au">@rubyconf_au</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="eventos" /><category term="rubyconf" /><category term="ruby" /><category term="rails" />
    </entry>

    <entry>
      <title><![CDATA[Estatísticas sobre tecnologia]]></title>
      <summary><![CDATA[Há um dito popular que diz: "números não mentem, mas mentirosos inventam números"]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/02/27/estatisticas-sobre-tecnologia?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-02-27T09:09:46.000Z</published>
      <updated>2018-02-27T09:09:46.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/02/27/estatisticas-sobre-tecnologia</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/02/27/estatisticas-sobre-tecnologia">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2018/02/olu-eletu-13086-unsplash.jpg" alt="image_description"></p>
<p>Há um dito popular que diz: "números não mentem, mas mentirosos inventam números".
O livro de 1954 de Darrell Huff "<a href="https://www.amazon.com.br/dp/858057952X/">Como Mentir com Estatística</a>"
ensina truques simples para manipular a percepção das pessoas usando números.
Em tempos de <a href="http://www.bbc.com/portuguese/internacional-41843695">notícias falsas</a>,
a obra é um guia útil para identificar valores distorcidos.
É uma das leituras favoritas de <a href="https://www.gatesnotes.com/Books/How-to-Lie-with-Statistics">Bill Gates</a>.</p>
<p>A <a href="http://www.ipardes.pr.gov.br/ojs/index.php/revistaparanaense/article/view/89">estatística é importante</a>
para sintetizar de forma quantitativa o grande volume de dados produzido pelo mundo.
Empresas de tecnologia <a href="https://codeascraft.com/2011/02/15/measure-anything-measure-everything/">medem tudo</a>;
o modelo de cobrança "<em>pay as you go</em>" adotado por provedores de serviço de computação em nuvem
depende da coleta de métricas de uso de recursos de processamento, armazenamento e rede, por exemplo.</p>
<p>Se você está começando um projeto de tecnologia e precisa entender o ambiente onde ele está inserido
para justificar certas escolhas, onde encontrar números confiáveis então?</p>
<p>Durante a faculdade, os professores sempre exigiam as fontes de informação em que baseavamos nossos trabalhos.
Mesmo sendo um setor de mudanças rápidas, é possível obter pesquisas e relatórios relevantes para observar
tendências baseadas em fatos na tecnologia.</p>
<p>"<a href="https://www.thoughtworks.com/pt/radar"><em>Technology Radar</em></a>" da ThoughtWorks analisa técnicas, plataformas,
ferramentas e linguagens &#x26; <em>frameworks</em>, indicando se vale a pena adotar ou não determinado item analisado.</p>
<p>O relatório "<a href="http://www.kpcb.com/internet-trends"><em>Internet Trends</em></a>" da KPCB,
umas das maiores firmas de capital de risco para tecnologia, oferece uma visão da adoção da Internet no mundo.
Na <a href="http://www.kpcb.com/file/2017-internet-trends-report">apresentação de 2017</a>, por exemplo,
verifica-se que 68% dos usuários pesquisados reagem de forma positiva a anúncios em formato de vídeo
que oferecem alguma recompensa (slide nº 26). Que tal usar essa estratégia no seu aplicativo?</p>
<p>As <a href="http://cetic.br/">publicações do Cetic.br</a> fornecem um panorâma da Internet no Brasil.
A <a href="http://cetic.br/tics/domicilios/2016/individuos/C16A/">edição de 2016</a> da pesquisa TIC Domicílios
destaca que mais de 40% dos usuários entrevistados acessam à Internet exclusivamente pelo celular.
Tá aí uma boa razão para tornar seu site responsivo, não?</p>
<p>O portal "<a href="https://www.thinkwithgoogle.com/"><em>Think with Google</em></a>" está cheio de dados e <em>insights</em>
para marcas e agências. Em 2017, por exemplo, as buscas usando o termo
"<a href="https://www.thinkwithgoogle.com/intl/pt-br/tendencias-de-consumo/alerta-de-tendencia-buscas-por-perto-de-mim/">perto de mim</a>"
cresceram 75%, indicando que os usuários estão incorporando a geolocalização em seu comportamento de busca.
Por que não <a href="https://developers.google.com/search/docs/data-types/local-business">enriquecer com metadados</a>
a página do seu negócio?</p>
<p>A <a href="https://www.ibm.com/services/insights/c-suite-study/">série de estudos com executivos</a> conduzida pela IBM
e o <a href="https://www.mckinsey.com/">site da consultoria McKinsey</a>
têm bastante conteúdo sobre gestão e estratégia para negócios digitais.
A 19ª edição do estudo da IBM mostra que
<a href="https://www-01.ibm.com/common/ssi/cgi-bin/ssialias?htmlfid=GBE03877USEN">34% das organizações pesquisadas estão investindo em inteligência artificial</a>
para resolver problemas complexos ou remodelar partes de seus negócios.
Uma pesquisa da McKinsey revela que 80% das empresas consultadas planejam
ter 10% ou mais de sua carga de trabalho rodando na nuvem pública ou
<a href="https://www.mckinsey.com/business-functions/digital-mckinsey/our-insights/making-a-secure-transition-to-the-public-cloud">dobrar seu uso da nuvem pública</a>
nos próximos 3 anos. Parece promissor estudar sobre IA e <em>cloud computing</em>, hein?</p>
<p>Por fim, um contraponto é necessário: "<a href="https://blog.bradfieldcs.com/you-are-not-google-84912cf44afb">você não é o Google</a>".
O professor de ciência da computação Ozan Onay chama a atenção daqueles que seguem cegamente as práticas
anunciadas por grandes empresas de tecnologia: a escala dos problemas enfrentados pelo Facebook, Amazon
ou LinkedIn é bem maior que aquela dos problemas enfrentados pelas empresas onde trabalhamos.
Por isso, entender o problema que precisamos resolver antes de usar uma solução de terceiro é crucial.
"<a href="https://www.safaribooksonline.com/library/view/the-little-book/9781292148458/html/chapter-109.html">O que as estatísticas revelam é sugestivo, mas o que escondem é essencial</a>".</p>
<p>Quais são as fontes de informação que você recomenda?</p>
</div>]]>
      </content>
      <author><name>Will Rosa</name></author>
      <category term="estatística" /><category term="tecnologia" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Criando sua primeira página web em 30 minutos (básico sobre HTML + CSS)]]></title>
      <summary><![CDATA[Topa o desafio de criar sua primeira página em 30 minutos? 😉]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/02/11/criando-sua-primeira-pagina-web-em-30-minutos-basico-sobre-html-e-css?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-02-10T23:29:48.000Z</published>
      <updated>2018-02-10T23:29:48.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/02/11/criando-sua-primeira-pagina-web-em-30-minutos-basico-sobre-html-e-css</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/02/11/criando-sua-primeira-pagina-web-em-30-minutos-basico-sobre-html-e-css">
        <![CDATA[<div xml:lang="pt-BR"><p>Gravei essa videoaula com o objetivo de ajudar quem quer <strong>aprender a criar uma página web do zero</strong>,
sem ter conhecimentos prévios.</p>
<p><a href="https://www.lucascaton.com/assets/html/criando-sua-primeira-pagina-web-em-30-minutos-basico-sobre-html-e-css/index.html">Clique aqui</a>
para ver a página que vamos criar.</p>
<p>É uma aula bem básica, porém com vários conceitos novos para quem está começando.
Se você tiver qualquer dúvida, me mande através dos comentários, eu vou responder <strong>todos</strong>! :)</p>
<p><a href="https://www.youtube.com/watch?v=KcPszmtF8cI"><img src="https://i.ytimg.com/vi_webp/KcPszmtF8cI/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Para aprofundar seus conhecimentos, conheça o meu <a href="https://www.lucascaton.com/pt-BR/cursos/dwdp">curso completo</a>!</aside></p>
<p><aside>Dica extra: <a href="https://www.lucascaton.com/2018/01/28/como-testar-seu-site-ou-app-em-diversos-dispositivos">clique aqui</a> para ver a técnica que eu uso para garantir que o layout fique bom independentemente da resolução e tamanho da tela do dispositivo!</aside></p>
<h2>Arquivos criados no vídeo:</h2>
<p>Você pode usar qualquer nome de arquivo que quiser, isso não interfere em nada.
Apenas lembre-se de referenciar o nome dos arquivos corretamente no HTML ;)</p>
<h3><code>index.html</code></h3>
<pre><code class="language-html">&#x3C;!DOCTYPE html>
&#x3C;html lang='pt'>
  &#x3C;head>
    &#x3C;title>Super banda!&#x3C;/title>
    &#x3C;link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
    &#x3C;link rel="stylesheet" href="application.css">
  &#x3C;/head>
  &#x3C;body>
    &#x3C;main>
      &#x3C;div class="logo">
        &#x3C;img src="ruby.png" alt="Logo da banda">
      &#x3C;/div>
      &#x3C;h1 class="band-name">Super banda!&#x3C;/h1>
      &#x3C;h2 class="headline">A melhor banda do mundo&#x3C;/h2>
      &#x3C;p>História da banda...  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&#x3C;/p>
      &#x3C;hr>
      &#x3C;div class="concerts">
        &#x3C;h2>Shows&#x3C;/h2>
        &#x3C;table>
          &#x3C;thead>
            &#x3C;tr>
              &#x3C;th>Cidade&#x3C;/th>
              &#x3C;th>Data&#x3C;/th>
            &#x3C;/tr>
          &#x3C;/thead>
          &#x3C;tbody>
            &#x3C;tr>
              &#x3C;td>São Paulo-SP&#x3C;/td>
              &#x3C;td>01/10/2018&#x3C;/td>
            &#x3C;/tr>
            &#x3C;tr>
              &#x3C;td>Rio de Janeiro-RJ&#x3C;/td>
              &#x3C;td>01/11/2018&#x3C;/td>
            &#x3C;/tr>
            &#x3C;tr>
              &#x3C;td>Belo Horizonte-MG&#x3C;/td>
              &#x3C;td>01/12/2018&#x3C;/td>
            &#x3C;/tr>
            &#x3C;tr>
              &#x3C;td>Refice-PE&#x3C;/td>
              &#x3C;td>01/01/2019&#x3C;/td>
            &#x3C;/tr>
          &#x3C;/tbody>
        &#x3C;/table>
      &#x3C;/div>
    &#x3C;/main>
  &#x3C;/body>
&#x3C;/html>
</code></pre>
<h3><code>application.css</code></h3>
<pre><code class="language-css">body {
  width: 95%;
  max-width: 800px;
  margin: auto;
  background: url(bg.jpg) center;
  font-family: 'Lato';
  line-height: 1.5;
  color: white;
}
main {
  background: #00000054;
  padding: 5px 40px;
  margin-top: 20px;
  border-radius: 10px;
}
.logo, .band-name, .headline {
  margin: 0;
  text-align: center;
}
.concerts {
  margin: 30px 0;
  text-align: center;
  width: 100%;
}
.concerts table {
  background: #cb3a3ab3;
  border-radius: 10px;
  padding: 10px;
  margin: 0 auto;
}
</code></pre>
<h3>Imagens:</h3>
<ul>
<li><a href="https://www.lucascaton.com/assets/html/criando-sua-primeira-pagina-web-em-30-minutos-basico-sobre-html-e-css/bg.jpg">bg.jpg</a></li>
<li><a href="https://www.lucascaton.com/assets/html/criando-sua-primeira-pagina-web-em-30-minutos-basico-sobre-html-e-css/ruby.png">ruby.png</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="html" /><category term="css" /><category term="web-design" /><category term="web-development" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Como gravar screencasts em formato GIF no macOS]]></title>
      <summary><![CDATA[Nesse vídeo, eu mostro como eu gravo screencasts, converto para o formato GIF, subo para a nuvem e compartilho a URL em menos de 30 segundos!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/02/04/como-gravar-screencasts-em-formato-gif-no-macos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-02-04T07:52:02.000Z</published>
      <updated>2018-02-04T07:52:02.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/02/04/como-gravar-screencasts-em-formato-gif-no-macos</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/02/04/como-gravar-screencasts-em-formato-gif-no-macos">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=nNdMn0MHi8I"><img src="https://i.ytimg.com/vi_webp/nNdMn0MHi8I/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Nesse vídeo, eu mostro como eu gravo screencasts (gravar a tela do meu computador),
converto para o formato GIF, subo para a nuvem e compartilho a URL em <strong>menos de 30 segundos</strong>!</p>
<p>Ferramentas mostradas no vídeo:</p>
<ul>
<li><a href="https://droplr.com/">Droplr</a></li>
<li><a href="https://itunes.apple.com/au/app/giphy-capture-the-gif-maker/id668208984?mt=12">GIPHY Capture</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="gif" /><category term="droplr" /><category term="giphy" /><category term="macOS" />
    </entry>

    <entry>
      <title><![CDATA[6 motivos para usar o PostgreSQL em vez do MySQL]]></title>
      <summary><![CDATA[Por que PostgreSQL é minha recomendação de banco de dados?]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/01/31/6-motivos-para-usar-o-postgresql-em-vez-do-mysql?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-01-31T08:30:30.000Z</published>
      <updated>2018-01-31T08:30:30.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/01/31/6-motivos-para-usar-o-postgresql-em-vez-do-mysql</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/01/31/6-motivos-para-usar-o-postgresql-em-vez-do-mysql">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2018/01/postgresql-vs-mysql.jpg" alt="Um elefante e um tubarão se enfrentando"></p>
<p>Muitos alunos do <a href="https://www.lucascaton.com/cursos/cplc">meu curso</a> me perguntam
porque eu recomendo o <strong>PostgreSQL</strong> em vez do <strong>MySQL</strong>.</p>
<p>O <strong>PostgreSQL</strong> vem se provando cada vez mais uma solução melhor
(não sou apenas eu quem está dizendo, boa parte da comunidade de desenvolvedores concorda com isso).
Mas eu gostaria de listar aqui alguns dos motivos pelos quais eu particularmente prefiro ele.</p>
<h2>1) Transações a nível de tabela</h2>
<p><a href="https://pt.wikipedia.org/wiki/Transa%C3%A7%C3%A3o_em_base_de_dados">Transações</a>
são extremamente úteis para uma série de tarefas, como por exemplo executar <em>queries</em> perigosas
(apagando registros por exemplo) diretamente no console do
<a href="https://pt.wikipedia.org/wiki/Sistema_de_gerenciamento_de_banco_de_dados">SGBD</a>.</p>
<p>Ao programar um software, uma boa hora de usar transações é ao
<a href="http://mergulhao.info/2007/6/3/um-pouco-de-migracoes/">migrar o <em>schema</em></a> do seu banco, ou seja,
criar, modificar, apagar tabelas, colunas, índices, etc.</p>
<p>O <strong>MySQL</strong> no entanto <strong>não</strong> oferece transações a nível de tabela. Por exemplo:</p>
<pre><code class="language-sql">BEGIN;
CREATE TABLE `users` (`name` varchar(255));
ROLLBACK;
</code></pre>
<p>Ao rodar as <em>queries</em> acima, seria esperado que a tabela <code>users</code> fosse criada e então apagada,
no entanto ela permanece.</p>
<p><aside>Execute o comando <code>SHOW TABLES;</code> para verificar.</aside></p>
<p>Já no <strong>PostgreSQL</strong>:</p>
<pre><code class="language-sql">BEGIN;
CREATE TABLE "users" ("name" character varying);
ROLLBACK;
</code></pre>
<p>Tudo funciona conforme o esperado e a tabela <code>users</code> é completamente removida.</p>
<p><aside>Execute o comando <code>\d</code> para verificar.</aside></p>
<h2>2) Funcionalidades</h2>
<ul>
<li><strong>Full-text search</strong> - O suporte à busca <em>full-text</em> do <strong>PostgreSQL</strong> não é só melhor que a do <strong>MySQL</strong>
como foi incluída muito tempo antes.</li>
<li><strong>UUID</strong> - Geração nativa de campos <a href="https://pt.wikipedia.org/wiki/Identificador_%C3%BAnico_universal">UUID</a>
é uma funcionalidade (até o momento) exclusiva do <strong>PostgreSQL</strong>, a qual pode inclusive ser usada como chave-primária.
Mais informações na <a href="https://www.postgresql.org/docs/current/static/datatype-uuid.html">documentação oficial</a>.</li>
</ul>
<h2>3) Encoding padrão</h2>
<p>O tipo de codificação padrão do <strong>PostgreSQL</strong> é o
<a href="https://pt.wikipedia.org/wiki/UTF-8">UTF-8</a>.
Simples assim!</p>
<p><del>Já o padrão do <strong>MySQL</strong> é <code>latin1</code>, o qual simplesmente não é preparado para
funcionar em qualquer canto do mundo (enquanto que o <code>UTF-8</code> é) e também não
aceita <em>emojis</em>. Além disso, você pode ter tabelas com diferentes <em>encodings</em>, o
que na minha opinião é um tanto confuso.</del></p>
<p><aside><strong>Atualização</strong>: em abril/2018, a <a href="https://mysqlserverteam.com/whats-new-in-mysql-8-0-generally-available">versão 8.0 do MySQL foi liberada</a> e o <em>character set</em> padrão passou a finalmente ser o <code>UTF-8</code>! Obrigado por avisar, <a href="https://www.lucascaton.com/2018/01/31/6-motivos-para-usar-o-postgresql-em-vez-do-mysql/#comment-4385635482">Fernando</a>!</aside></p>
<h2>4) Tipos de dados (colunas)</h2>
<p>A maioria dos tipos de colunas são mais amigáveis e consistentes no <strong>PostgreSQL</strong> que no <strong>MySQL</strong>.
Exemplo: um dado <a href="https://pt.wikipedia.org/wiki/Booleano">booleano</a>
é guardado como <code>boolean</code> no <strong>PostgreSQL</strong> e - por falta de algo mais apropriado -
guardado como <code>tinyint(1)</code> no <strong>MySQL</strong>.</p>
<p>O tipo <code>tinyint</code>, a princípio, guarda um valor inteiro de 1 dígito.
Para guardar um boleano nesse tipo de campo, usamos <code>1</code> ou <code>0</code>,
o que é popularmente conhecido como "gambiarra" :)</p>
<h3>Outros exemplos bacanas de tipos do <strong>PostgreSQL</strong> são:</h3>
<ul>
<li><a href="https://www.postgresql.org/docs/current/static/datatype-json.html">jsonb</a> - no qual você guarda dados em
<a href="https://pt.wikipedia.org/wiki/JSON">formato JSON</a> de forma bastante flexível, com direito à
<a href="https://www.postgresql.org/docs/current/static/gin.html">indices GIN</a> e tudo mais.
Quem usava um <a href="https://pt.wikipedia.org/wiki/NoSQL">banco de dados NoSQL</a> só para ter dados sem
<em>schema</em> definido, pode usar esse tipo de dado para potencialmente resolver esse problema.</li>
<li><a href="https://www.postgresql.org/docs/current/static/arrays.html">array</a> - permite definir <em>arrays</em>
multidimensionais de tamanhos variáveis.</li>
<li>Além de <a href="https://www.postgresql.org/docs/current/static/datatype-enum.html">enumerations</a>,
<a href="https://www.postgresql.org/docs/current/static/datatype-geometric.html">tipos geométricos</a>,
<a href="https://www.postgresql.org/docs/current/static/datatype-net-types.html">endereços de rede</a>
e <a href="https://www.postgresql.org/docs/current/static/datatype.html">vários outros</a>.</li>
</ul>
<h2>5) Comunidade e licenças</h2>
<p>Depois que o <strong>MySQL</strong> foi comprado pela Oracle, foi criado um
<a href="https://pt.wikipedia.org/wiki/Bifurca%C3%A7%C3%A3o"><em>fork</em></a> do projeto, chamado
<a href="https://mariadb.org/about/">MariaDB</a>, o qual no começo se comprometia a ser compatível com o
<strong>MySQL</strong>, porém totalmente livre em termos de licença.
Infelizmente ele já não é 100% compatível com o <strong>MySQL</strong>,
o que talvez seja um problema para algumas empresas ou desenvolvedores (ou não).</p>
<p>Já o <strong>PostgreSQL</strong> sempre foi <a href="https://github.com/postgres/postgres">open-source</a>
e apesar de ter uma <a href="https://opensource.org/licenses/postgresql">licença própria</a>,
ela é muito parecida com as licenças <strong>BSD</strong> e <strong>MIT</strong>.</p>
<h2>6) Preços</h2>
<p>Muita gente não sabe, mas a versão completa do <strong>MySQL</strong>
<a href="https://www.mysql.com/products/">não é gratuita</a>.</p>
<p>O <strong>PostgreSQL</strong> por sua vez oferece todas as suas funcionalidades pelo mesmo preço: <strong>zero</strong>!</p>
<h2>Conclusão</h2>
<p>Do jeito que eu listei as comparações aqui, pode parecer que o <strong>MySQL</strong> é o pior banco de dados
do mundo, mas de fato ele está longe disso.
O fato de ser tão popular e de tantas empresas usarem e apostarem nele provam isso.</p>
<p>Entretanto, pelos motivos citados acima, <strong>PostgreSQL</strong> é minha escolha pessoal.
Deixe nos comentários abaixo se você concorda ou discorda,
discussões (saudáveis) são sempre bem-vindas! 😉</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="banco-de-dados" /><category term="postgresql" /><category term="mysql" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Como testar seu site ou app em diversos dispositivos]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/01/28/como-testar-seu-site-ou-app-em-diversos-dispositivos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-01-28T06:24:34.000Z</published>
      <updated>2018-01-28T06:24:34.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/01/28/como-testar-seu-site-ou-app-em-diversos-dispositivos</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/01/28/como-testar-seu-site-ou-app-em-diversos-dispositivos">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=T2irIAXHyl8"><img src="https://i.ytimg.com/vi_webp/T2irIAXHyl8/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Nesse vídeo eu vou mostrar como testar o comportamento do seu <strong>site</strong> ou <strong>web app</strong> em diferentes dispositivos, para que você possa garantir que o layout fique bom independentemente da resolução e tamanho da tela do dispositivo.</p>
<p>Essa técnica é conhecida como <strong>design responsívo</strong> e as ferramentas que você vai precisar para testar vão te surpreender :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="desenvolvimento-web" /><category term="html" /><category term="css" /><category term="navegadores" /><category term="design-responsivo" />
    </entry>

    <entry>
      <title><![CDATA[Desenvolvimento web em 2018]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/01/18/desenvolvimento-web-em-2018?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-01-18T11:31:45.000Z</published>
      <updated>2018-01-18T11:31:45.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/01/18/desenvolvimento-web-em-2018</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/01/18/desenvolvimento-web-em-2018">
        <![CDATA[<div xml:lang="pt-BR"><p><aside><strong>Atualização:</strong> a <a href="https://www.lucascaton.com/2019/02/03/guia-desenvolvedor-web-2019">versão 2019</a> já está disponível!</aside></p>
<hr>
<p>Todos os dias, milhares de pessoas começam a programar.
Mas a decisão de qual caminho escolher, o que estudar, no que se especializar fica cada vez mais difícil, pois há cada vez mais opções.</p>
<p>Além disso, uma parte do mercado espera que você saiba o máximo de coisas possíveis (também conhecido como desenvolvedor "<em>full stack</em>"),
enquanto que a outra parte prefere profissionais que se especializam em uma determinada área.</p>
<p>Seja como for, o <em>roadmap</em> abaixo (criado por <a href="https://github.com/kamranahmedse/developer-roadmap">Kamran Ahmed</a>
e traduzido/adaptado por mim) pode ajudar a filtrar o mar de tecnologias disponíveis para profissionais da área.
Bons estudos! 😉</p>
<h2>🚀 Introdução</h2>
<p><a href="https://www.lucascaton.com/images/posts/2018/01/mapa-introducao.png"><img src="/images/posts/2018/01/mapa-introducao.png" alt="introdução"></a></p>
<h2>🎨 Front-end</h2>
<p>Novos frameworks não param de aparecer.
Saber bem o básico de JavaScript e CSS ainda é mais importante que frameworks.</p>
<p><a href="https://www.lucascaton.com/images/posts/2018/01/mapa-frontend.png"><img src="/images/posts/2018/01/mapa-frontend.png" alt="front-end"></a></p>
<h2>🎛 Back-end</h2>
<p>Para o <em>back-end</em>, eu continuo recomendando a linguagem <strong>Ruby</strong>.</p>
<p><a href="https://www.lucascaton.com/images/posts/2018/01/mapa-backend.png"><img src="/images/posts/2018/01/mapa-backend.png" alt="back-end"></a></p>
<h2>👷 DevOps</h2>
<p><strong>Docker</strong> (e <em>containers</em> em geral) estão cada vez mais relevantes.</p>
<p><a href="https://www.lucascaton.com/images/posts/2018/01/mapa-devops.png"><img src="/images/posts/2018/01/mapa-devops.png" alt="dev-ops"></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="desenvolvimento-web" /><category term="programacao" /><category term="back-end" /><category term="front-end" /><category term="dev-ops" />
    </entry>

    <entry>
      <title><![CDATA[Comandos para o terminal (Windows, macOS e Linux)]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2018/01/07/comandos-para-o-terminal-windows-macos-e-linux?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2018-01-07T05:29:38.000Z</published>
      <updated>2019-10-22T21:43:11.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2018/01/07/comandos-para-o-terminal-windows-macos-e-linux</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2018/01/07/comandos-para-o-terminal-windows-macos-e-linux">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2017/12/terminal.png" alt="image_description"></p>
<p>Há alguns dias, escrevi um artigo explicando <a href="https://www.lucascaton.com/2017/12/30/qual-a-diferenca-entre-terminal-ide-e-editor-de-textos">a diferença entre <strong>Terminal</strong>, <strong>IDE</strong> e
<strong>Editor de Textos</strong></a>.</p>
<p>Basicamente, <strong>terminal</strong> é um programa que usamos para gerenciar recursos mais avançados do
sistema. É geralmente uma tela preta, sem botões e sem elementos gráficos, a qual você interage
digitando linhas de comandos.</p>
<p>Como você deve imaginar, existem vários comandos que já vem por padrão em cada sistema operacional.
Esses comandos executam tarefas distintas e resolvem diferentes tipos de problemas, muitos dos quais
são relevantes para programadores.</p>
<p>Entretanto, para quem está começando no mundo da programação, pode ser um pouco assustador ver a
quantidade de comandos disponíveis. Na prática, essa quantidade é infinita, já que programas e
pacotes instalados também podem disponibilizar comandos próprios para serem executados, também
conhecidos como <strong>CLI</strong>s (<em>Command-line interface</em>, ou Interface de Linha de Comando).</p>
<p>Vou listar abaixo alguns comandos úteis (os mais básicos) que os sistemas operacionais já trazem
por padrão, mas antes vamos entender como executá-los e o que podemos esperar após cada execução.</p>
<h3>Como executar os comandos</h3>
<p>O processo é bem simples: você digita algum comando e pressiona <code>enter</code>.
O resultado do comando, na maioria das vezes, será exibido na tela.
Nesse momento, várias coisas podem acontecer:</p>
<ul>
<li>O comando é executado <strong>corretamente</strong> e uma mensagem de sucesso aparece.</li>
<li>O comando é executado <strong>corretamente</strong> porém nada é exibido (raro de acontecer).</li>
<li>O comando é executado e um <strong>erro</strong> é exibido.</li>
<li>O comando é executado, um <strong>erro</strong> acontece, porém nada é exibido na tela (muito raro de acontecer).</li>
</ul>
<h3>Case-sensitive</h3>
<p>Lembre-se que os comandos são <em>case-sensitive</em> (sensíveis à caixa), ou seja,
há diferença entre digitar um comando em <strong>maiúsculas</strong> e <strong>minúsculas</strong>.
Na grande maioria das vezes, tudo deve ser digitado com <strong>minúsculas</strong>.</p>
<hr>
<h2>Comandos para Windows</h2>
<p><img src="/images/posts/2018/01/terminal-windows.png" alt="image_description"></p>
<p><aside>Todos os comandos foram testados no <strong>Windows 10</strong>.</aside></p>
<p>O terminal no <strong>Windows</strong> é conhecido como <strong>"Prompt de Comando"</strong>
(apesar de existirem outros como o <strong>PowerShell</strong> e o novo <strong>Windows Terminal</strong>).</p>
<p>Para abri-lo, clique no <strong>Menu Iniciar</strong>, digite <code>cmd</code> e pressione <code>enter</code>.</p>
<p><aside>Se você estiver usando o <strong>PowerShell</strong>, alguns comandos podem ser ligeiramente diferentes (eles podem se parecer mais com os comandos do Linux/macOS).</aside></p>
<h3>➡ <code>date</code></h3>
<p>Exibir a data atual.</p>
<pre><code>C:\> date
A data atual é: Qui 23/10/2019
</code></pre>
<h3>➡ <code>time</code></h3>
<p>Exibir a hora atual.</p>
<pre><code>C:\> time
A hora atual é:  1:42:29.68
</code></pre>
<h3>➡ <code>echo %cd%</code></h3>
<p>Exibir qual é o diretório atual.</p>
<pre><code class="language-bash">C:\> echo %cd%
C:\
</code></pre>
<h3>➡ <code>dir</code></h3>
<p>Exibir arquivos/diretórios do diretório atual.</p>
<pre><code>C:\> dir
Volume in drive C has no label.
Volume Serial Number is 82C2-03F2
Directory of C:\
10/21/2019  09:34 PM    &#x3C;DIR>          PerfLogs
10/22/2019  10:52 PM    &#x3C;DIR>          Program Files
10/21/2019  11:08 PM    &#x3C;DIR>          Program Files (x86)
10/21/2019  10:07 PM    &#x3C;DIR>          samples
10/21/2019  09:45 PM    &#x3C;DIR>          Scripts
10/21/2019  09:30 PM    &#x3C;DIR>          Users
10/22/2019  10:50 PM    &#x3C;DIR>          Windows
              0 File(s)              0 bytes
              7 Dir(s)  99,198,668,800 bytes free
</code></pre>
<h3>➡ <code>cd</code></h3>
<p>Mudar o diretório atual.</p>
<pre><code>C:\> cd Documentos
C:\Documentos>
</code></pre>
<p>Voltar para o diretório acima.</p>
<pre><code>C:\Documentos> cd ..
C:\>
</code></pre>
<h3>➡ <code>mkdir</code></h3>
<p>Criar uma pasta.</p>
<pre><code>C:\> mkdir meus_projetos
C:\> dir
(...)
23/10/2019  07:34  &#x3C;DIR>  meus_projetos
</code></pre>
<p>Criar pasta e subdiretórios (de uma só vez).</p>
<pre><code>C:\> mkdir meus_projetos\repositorios\ruby
C:\> cd meus_projetos
C:\meus_projetos> cd repositorios
C:\meus_projetos\repositorios> cd ruby
C:\meus_projetos\repositorios\ruby>
</code></pre>
<h3>➡ <code>copy</code></h3>
<p>Copiar (duplicar) um arquivo.</p>
<pre><code>C:\Documentos> copy arquivo1.txt arquivo2.txt
        1 arquivo(s) copiado(s).
</code></pre>
<h3>➡ <code>move</code></h3>
<p>Mover (ou renomear) um arquivo ou pasta.</p>
<pre><code>C:/> move nome_antigo.txt nome_novo.txt
(O arquivo será renomeado)
</code></pre>
<pre><code>C:/Documentos> move telefones.txt meus_projetos
(O arquivo será movido para a pasta `meus_projetos`)
</code></pre>
<h3>➡ <code>del</code></h3>
<p>Deletar um arquivo.</p>
<p><aside><strong>Cuidado:</strong> o terminal não pede confirmação antes de deletar; tome muito cuidado para não deletar o arquivo errado!</aside></p>
<pre><code>C:/Documentos> del telefones.txt
</code></pre>
<h3>➡ <code>rmdir</code></h3>
<p>Deletar uma pasta vazia.</p>
<p><aside><strong>Cuidado:</strong> o terminal não pede confirmação antes de deletar; tome muito cuidado para não deletar a pasta errada!</aside></p>
<pre><code>C:/Documentos> rmdir meus_projetos
</code></pre>
<h3>➡ <code>rmdir /s</code></h3>
<p>Deletar uma pasta que não esteja vazia.</p>
<pre><code>C:/Documentos> rmdir /s meus_projetos
</code></pre>
<h3>➡ <code>type</code></h3>
<p>Exibir o conteúdo de um arquivo.</p>
<pre><code>C:/Documentos> type telefones.txt
(11) 1111-1111
(22) 2222-2222
(33) 3333-3333
</code></pre>
<h3>➡ <code>cls</code></h3>
<p>Limpar o terminal.</p>
<pre><code>C:\> cls
</code></pre>
<hr>
<h2>Comandos para macOS e Linux</h2>
<p>Para abrir o terminal no <strong>macOS</strong>, abra a pasta de <strong>Aplicativos</strong> (<em>Applications</em>)
e em seguida a pasta <strong>Utilitários</strong> (<em>Utilities</em>). Agora basta abrir o aplicativo <strong>Terminal</strong>.</p>
<p>Duas alternativas bastante interessantes (e populares entre programadores) são o
<a href="https://www.iterm2.com/">iTerm2</a> (<em>screenshot</em> abaixo) e o
<a href="https://hyper.is/">Hyper</a>.</p>
<p><img src="/images/posts/2017/12/terminal.png" alt="image_description"></p>
<p>Já para abrir o terminal no <strong>Ubuntu Linux</strong>, clique no ícone do <strong>Ubuntu</strong> no canto superior-esquerdo,
digite <code>terminal</code> e selecione o aplicativo <strong>Terminal</strong> na lista de resultados que vai aparecer:</p>
<p><img src="/images/posts/2018/01/terminal-ubuntu.png" alt="image_description"></p>
<h3>➡ <code>date</code></h3>
<p>Exibir a data e hora atuais.</p>
<pre><code class="language-bash">$ date
# Wed 23 Oct 2019 07:36:36 AEST
</code></pre>
<h3>➡ <code>cal</code></h3>
<p>Exibir um calendário.</p>
<pre><code class="language-bash">$ cal
#     October 2019
# Su Mo Tu We Th Fr Sa
#        1  2  3  4  5
#  6  7  8  9 10 11 12
# 13 14 15 16 17 18 19
# 20 21 22 23 24 25 26
# 27 28 29 30 31
</code></pre>
<h3>➡ <code>uptime</code></h3>
<p>Exibir há quanto tempo você não desliga/reinicia seu computador.</p>
<pre><code class="language-bash">$ uptime
# 18:58:47 up 34 days, 9:20, 1 user, load average: 0.00, 0.01, 0.05
</code></pre>
<h3>➡ <code>pwd</code></h3>
<p>Exibir qual é o diretório atual.</p>
<pre><code class="language-bash">$ pwd
# /Users/usuario/Documents
</code></pre>
<h3>➡ <code>ls</code></h3>
<p>Exibir arquivos/diretórios do diretório atual.</p>
<pre><code class="language-bash">$ ls
# foto.png      telefones.txt
</code></pre>
<p>Exibir arquivos/diretórios do diretório atual em formato de lista.</p>
<pre><code class="language-bash">$ ls -l
# -rw-r--r--@ 1 usuario  staff  4787  6 Mar 17:55 foto.png
# -rw-r--r--  1 usuario  staff  8186  6 Mar 17:54 telefones.txt
</code></pre>
<p>Exibir arquivos/diretórios do diretório atual incluindo arquivos ocultos.</p>
<pre><code class="language-bash">$ ls -la
# drwx------+  7 usuario  staff   238  6 Mar 17:57 .
# drwxr-xr-x+ 80 usuario  staff  2720  6 Mar 17:57 ..
# -rw-r--r--   1 usuario  staff     0  6 Mar 17:56 .arquivo_oculto.txt
# -rw-r--r--@  1 usuario  staff  4787  6 Mar 17:55 foto.png
# -rw-r--r--   1 usuario  staff     0  6 Mar 17:54 telefones.txt
</code></pre>
<h3>➡ <code>cd</code></h3>
<p>Mudar o diretório atual.</p>
<pre><code class="language-bash">$ pwd
# /Users/usuario
$ cd Documents
$ pwd
# /Users/usuario/Documents
</code></pre>
<p>Voltar para o diretório acima.</p>
<pre><code class="language-bash">$ pwd
# /Users/usuario/Documents
$ cd ..
$ pwd
# /Users/usuario
</code></pre>
<p>Voltar para o diretório do seu usuário (conhecido como pasta <strong>"home"</strong>).</p>
<pre><code class="language-bash">$ cd ~
$ pwd
# macOS: /Users/usuario
# Linux: /home/usuario
</code></pre>
<h3>➡ <code>mkdir</code></h3>
<p>Criar uma pasta.</p>
<pre><code class="language-bash">$ mkdir meus_projetos
$ ls
# meus_projetos
</code></pre>
<p>Criar pasta e subdiretórios.</p>
<pre><code class="language-bash">$ mkdir -p meus_projetos/repositorios/ruby
$ ls
# meus_projetos
$ cd meus_projetos
$ ls
# repositorios
$ cd ruby
$ ls
# Diretório vazio
</code></pre>
<h3>➡ <code>cp</code></h3>
<p>Copiar (duplicar) um arquivo.</p>
<pre><code class="language-bash">cp arquivo1.txt arquivo2.txt
</code></pre>
<h3>➡ <code>mv</code></h3>
<p>Mover (ou renomear) um arquivo ou pasta.</p>
<pre><code class="language-bash">mv nome_antigo.txt nome_novo.txt
# O arquivo será renomeado
</code></pre>
<pre><code class="language-bash">mv telefones.txt ~/Documents/
# O arquivo será movido para a pasta ~/Documents/
</code></pre>
<h3>➡ <code>rm</code></h3>
<p>Deletar um arquivo.</p>
<p><aside><strong>Cuidado:</strong> o terminal não pede confirmação antes de deletar; tome muito cuidado para não deletar o arquivo errado!</aside></p>
<pre><code class="language-bash">rm telefones.txt
</code></pre>
<h3>➡ <code>rm -rf</code></h3>
<p>Deletar uma pasta.</p>
<p><aside><strong>Cuidado:</strong> o terminal não pede confirmação antes de deletar; tome muito cuidado para não deletar a pasta errada!</aside></p>
<pre><code class="language-bash">$ rm -rf meus_projetos
</code></pre>
<h3>➡ <code>touch</code></h3>
<p>Criar um arquivo em branco (vazio).</p>
<pre><code class="language-bash">$ touch emails.txt
</code></pre>
<h3>➡ <code>cat</code></h3>
<p>Exibir o conteúdo de um arquivo.</p>
<pre><code class="language-bash">$ cat telefones.txt
# (11) 1111-1111
# (22) 2222-2222
# (33) 3333-3333
</code></pre>
<h3>➡ <code>clear</code></h3>
<p>Limpar o terminal (o atalho <code>Ctrl+l</code> também funciona na maioria dos terminais).</p>
<pre><code class="language-bash">$ clear
</code></pre>
<hr>
<h2>Como conseguir ajuda com um determinado comando?</h2>
<p>Digite o comando acompanhado de <code>-h</code> ou <code>--help</code> no final,
ou ainda utilize o comando <code>man &#x3C;comando></code>.
Exemplos:</p>
<pre><code class="language-bash">$ rails -h
</code></pre>
<pre><code class="language-bash">$ vim --help
</code></pre>
<pre><code class="language-bash">$ man cat
</code></pre>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="terminal" />
    </entry>

    <entry>
      <title><![CDATA[Qual a diferença entre Terminal, IDE e Editor de Textos?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/12/30/qual-a-diferenca-entre-terminal-ide-e-editor-de-textos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-12-29T21:15:26.000Z</published>
      <updated>2017-12-29T21:15:26.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/12/30/qual-a-diferenca-entre-terminal-ide-e-editor-de-textos</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/12/30/qual-a-diferenca-entre-terminal-ide-e-editor-de-textos">
        <![CDATA[<div xml:lang="pt-BR"><h2>Terminal</h2>
<h3>O que é?</h3>
<p>É um programa disponível em todos os sistemas operacionais para gerenciamento de recursos mais avançados do sistema.
É geralmente uma tela preta, sem botões e sem elementos gráficos, onde você utiliza apenas comandos para interagir.</p>
<p><img src="/images/posts/2017/12/terminal.png" alt="image_description"></p>
<p><small>Exemplo: <strong>iTerm2</strong></small></p>
<p>Pode ser um pouco assustador ver a quantidade de comandos disponíveis,
para quem está começando no mundo da programação, por isso escrevi
<a href="https://www.lucascaton.com/2018/01/07/comandos-para-o-terminal-windows-macos-e-linux">um pequeno guia com uma lista de comandos</a>.</p>
<h3>Windows</h3>
<p>No <strong>Windows</strong>, temos diferentes terminais, como o <strong>Prompt de Comando</strong> e o <strong>PowerShell</strong>.</p>
<h3>Linux</h3>
<p>No <strong>Linux</strong>, ele é chamado de <strong>Terminal</strong> mesmo.</p>
<h3>macOS</h3>
<p>No <strong>macOS</strong>, ele também é chamado de <strong>Terminal</strong>.</p>
<p>Apesar de o sistema trazer um terminal instalado, eu recomendo um outro terminal chamado <strong>iTerm2</strong>,
mais poderoso, o qual pode ser baixado através do site <a href="https://www.iterm2.com/">iterm2.com</a>.</p>
<hr>
<h2>IDE</h2>
<h3>O que é?</h3>
<p>É um programa que não vem instalado por padrão e é utilizado para o desenvolvimento de softwares.
É geralmente uma janela com muitos botões, muitos elementos gráficos e uma área para digitar os códigos.</p>
<p><img src="/images/posts/2017/12/ide.png" alt="image_description"></p>
<p><small>Exemplo: <strong>Xcode</strong>, para programar apps para iOS (iPhone e iPad), macOS, watchOS e tvOS</small></p>
<h3>Exemplos de IDEs:</h3>
<ul>
<li><a href="https://developer.apple.com/xcode/">Xcode</a></li>
<li><a href="https://developer.android.com/studio/">Android Studio</a></li>
<li><a href="https://www.visualstudio.com/vs/">Visual Studio</a></li>
<li><a href="https://www.jetbrains.com/idea/">IntelliJ IDEA</a></li>
<li><a href="https://eclipse.org/">Eclipse</a></li>
</ul>
<hr>
<h2>Editor de Textos</h2>
<h3>O que é?</h3>
<p>Para programar em algumas linguagens (<a href="https://www.lucascaton.com/tags/ruby/">Ruby</a> por exemplo),
não é necessário uma <strong>IDE</strong>, podemos utilizar apenas um <strong>editor de texto</strong>, que é mais simples e mais rápido.</p>
<p>Editores servem para editar textos e também códigos.
Os editores que vem instalado por padrão (<strong>Bloco de Notas</strong>, por exemplo) são simples demais,
portanto não são recomendados para desenvolver programas.
No geral, eles são apenas uma janela com poucos botões (às vezes nenhum) e uma grande área para digitar os códigos.</p>
<p><img src="/images/posts/2017/12/editor.png" alt="image_description"></p>
<p><small>Exemplo: <strong>Atom</strong></small></p>
<h3>Exemplos de editores de texto:</h3>
<ul>
<li><a href="https://code.visualstudio.com/">VS Code</a></li>
<li><a href="https://atom.io/">Atom</a></li>
<li><a href="https://www.sublimetext.com/">Sublime Text</a></li>
<li><a href="http://www.vim.org/">Vim</a>, <a href="https://gvim.en.softonic.com/">gVim</a> e <a href="http://macvim-dev.github.io/macvim/">MacVim</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="terminal" /><category term="ide" /><category term="editor-de-textos" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Fazer ou não faculdade para trabalhar com computação?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/12/19/fazer-ou-nao-faculdade-para-trabalhar-com-computacao?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-12-19T06:10:53.000Z</published>
      <updated>2017-12-19T06:10:53.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/12/19/fazer-ou-nao-faculdade-para-trabalhar-com-computacao</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/12/19/fazer-ou-nao-faculdade-para-trabalhar-com-computacao">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=DpzYqg-jBtI"><img src="https://i.ytimg.com/vi_webp/DpzYqg-jBtI/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Dia desses uma pessoa me perguntou algumas coisas sobre diploma/faculdade de computação e após responder percebi que poderia ser um tema interessante para um vídeo.</p>
<p>O resultado você vê no vídeo acima, espero que goste e não deixe de comentar sua opinião aqui em baixo :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="computacao" /><category term="faculdade" /><category term="universidade" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Permita que usuários façam login no seu app Rails usando o Facebook]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/12/06/screencast-permita-que-usuarios-facam-login-no-seu-app-rails-usando-o-facebook?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-12-06T08:21:36.000Z</published>
      <updated>2017-12-06T08:21:36.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/12/06/screencast-permita-que-usuarios-facam-login-no-seu-app-rails-usando-o-facebook</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/12/06/screencast-permita-que-usuarios-facam-login-no-seu-app-rails-usando-o-facebook">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=Ts5ZeOsvJ9s"><img src="https://i.ytimg.com/vi_webp/Ts5ZeOsvJ9s/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Nesse novo screencast, vou ensinar como adicionar uma interessante funcionalidade ao seu app: <strong>autenticação usando o Facebook</strong>.</p>
<p>Para ficar mais interessante, usei um projeto real: o <a href="https://www.easybills.io/?locale=pt-BR">Easy Bills</a>.
O projeto usa <strong>Ruby</strong> e <strong>Ruby on Rails</strong> e adicionalmente, eu incluí a gem <a href="https://github.com/mkdynamic/omniauth-facebook">omniauth-facebook</a>.</p>
<hr>
<p>Abaixo, você encontra os arquivos que eu criei ou alterei no vídeo:</p>
<p><code>Gemfile</code>:</p>
<pre><code class="language-ruby">gem 'omniauth-facebook'
</code></pre>
<p><code>app/assets/images/social-sign-in/facebook.svg</code>:</p>
<pre><code class="language-xml">&#x3C;?xml version="1.0" encoding="utf-8"?>
&#x3C;!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
&#x3C;svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
   width="35px" height="35px" viewBox="0 0 300 300" enable-background="new 0 0 266.893 266.895"
   xml:space="preserve">
&#x3C;path id="f" fill="#FFFFFF" d="M182.409,262.307v-99.803h33.499l5.016-38.895h-38.515V98.777c0-11.261,3.127-18.935,19.275-18.935
  l20.596-0.009V45.045c-3.562-0.474-15.788-1.533-30.012-1.533c-29.695,0-50.025,18.126-50.025,51.413v28.684h-33.585v38.895h33.585
  v99.803H182.409z"/>
&#x3C;/svg>
</code></pre>
<p><code>app/assets/stylesheets/authentication.sass</code> (ou <code>app/assets/stylesheets/application.sass</code>):</p>
<pre><code class="language-sass">@import 'modules/social-buttons'
</code></pre>
<p><code>app/assets/stylesheets/modules/social-buttons.sass</code>:</p>
<pre><code class="language-sass">// https://github.com/vagnervjs/social-signin-btns
$services: google #DD4B39, facebook #3B5998, twitter #00ACED, microsoft #e3b30d, github #2a2a2a, foursquare #95c330, instagram #906248, linkedin #0b5ea3, evernote #5ca629, dropbox #1b73d1
.btn-si
  background-position: 1em
  background-repeat: no-repeat
  background-size: 2em
  border-radius: .5em
  border: none
  color: #fff
  cursor: pointer
  font-size: 1em
  line-height: 1em
  padding: 0 2em 0 4em
  text-decoration: none
  transition: all .5s
@each $service in $services
  .btn-#{nth($service, 1)}
    background-color: #{nth($service, 2)}
    &#x26;, &#x26;:hover, &#x26;:active
      background-image: image-url("social-sign-in/#{nth($service, 1)}.svg")
      color: #fff
    &#x26;:hover
      background-color: lighten(nth($service, 2), 10%)
    &#x26;:active
      background-color: darken(nth($service, 2), 10%)
.btn-si-a
  padding: 15px 15px 15px 65px !important
  font-family: arial
.smaller .btn-si-a
  padding-left: 40px !important
  font-size: 12px
</code></pre>
<p><code>app/controllers/users/omniauth_callbacks_controller.rb</code>:</p>
<pre><code class="language-ruby">module Users
  class OmniauthCallbacksController &#x3C; Devise::OmniauthCallbacksController
    def facebook
      @user = User.from_omniauth(request.env['omniauth.auth'])
      if @user.persisted?
        sign_in_and_redirect @user, event: :authentication # Throws if @user is not activated
        set_flash_message(:notice, :success, kind: 'Facebook') if is_navigational_format?
      else
        session['devise.facebook_data'] = request.env['omniauth.auth']
        redirect_to new_user_registration_url
      end
    end
    def failure
      redirect_to new_user_session_path
    end
  end
end
</code></pre>
<p><code>app/models/concerns/omniauthenticable.rb</code>:</p>
<pre><code class="language-ruby">module Omniauthenticable
  extend ActiveSupport::Concern
  included do
    def self.from_omniauth(auth)
      existing_user = User.find_by(email: auth['info']['email'])
      if existing_user
        existing_user.update!(provider: auth.provider, uid: auth.uid)
        existing_user
      else
        where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
          user.email                 = auth.info.email
          user.password              = Devise.friendly_token[0, 20]
          user.password_confirmation = user.password
          user.name                  = auth.info.name
          user.photo                 = auth.info.image
          user.skip_confirmation!
        end
      end
    end
    def self.new_with_session(params, session)
      super.tap do |user|
        data = session['devise.facebook_data'] &#x26;&#x26;
          session['devise.facebook_data']['extra']['raw_info']
        user.email = data['email'] if data &#x26;&#x26; user.email.blank?
      end
    end
  end
end
</code></pre>
<p><code>app/models/user.rb</code>:</p>
<pre><code class="language-ruby">class User &#x3C; ApplicationRecord
  include Omniauthenticable
  devise :omniauthable, omniauth_providers: %i[facebook]
  # etc
end
</code></pre>
<p><code>app/views/devise/sessions/new.html.haml</code>:</p>
<pre><code class="language-haml">%hr.m-t-25
.m-b-10 or
.fg-line.m-b-10
  = link_to 'Sign in with Facebook', user_facebook_omniauth_authorize_path,
    class: 'btn btn-si btn-si-a btn-facebook'
</code></pre>
<p><code>config/initializers/devise.rb</code>:</p>
<pre><code class="language-ruby">config.omniauth :facebook, 'FACEBOOK_APP_ID', 'FACEBOOK_APP_SECRET'
</code></pre>
<p><code>config/routes.rb</code>:</p>
<pre><code class="language-ruby">devise_for :users, controllers: {
  omniauth_callbacks: 'users/omniauth_callbacks',
  # etc
}
</code></pre>
<p><code>db/migrate/20171204023306_add_omniauth_to_users.rb</code>:</p>
<pre><code class="language-ruby">class AddOmniauthToUsers &#x3C; ActiveRecord::Migration[5.1]
  def change
    add_column :users, :provider, :string
    add_column :users, :uid,      :string
  end
end
</code></pre>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="ruby" /><category term="rails" /><category term="facebook" /><category term="omniauth" />
    </entry>

    <entry>
      <title><![CDATA[Trocar de ferramenta não vai ajudar você a resolver seu problema]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/11/10/trocar-de-ferramenta-nao-vai-ajudar-voce-a-resolver-seu-problema?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-11-10T16:20:53.000Z</published>
      <updated>2017-11-10T16:20:53.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/11/10/trocar-de-ferramenta-nao-vai-ajudar-voce-a-resolver-seu-problema</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/11/10/trocar-de-ferramenta-nao-vai-ajudar-voce-a-resolver-seu-problema">
        <![CDATA[<div xml:lang="pt-BR"><p>Quem nunca passou por isso?!</p>
<p><a href="https://www.youtube.com/watch?v=dpZMciLOBFU"><img src="https://i.ytimg.com/vi_webp/dpZMciLOBFU/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="programacao" /><category term="ferramentas" /><category term="produtividade" /><category term="metodologias" /><category term="agil" />
    </entry>

    <entry>
      <title><![CDATA[Por que você deveria ter um blog?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/10/21/por-que-voce-deveria-ter-um-blog?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-10-20T22:41:56.000Z</published>
      <updated>2017-10-20T22:41:56.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/10/21/por-que-voce-deveria-ter-um-blog</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/10/21/por-que-voce-deveria-ter-um-blog">
        <![CDATA[<div xml:lang="pt-BR"><p>Eis os motivos que me fizeram começar e os que até hoje me fazem continuar!</p>
<p><a href="https://www.youtube.com/watch?v=pomeohwS9rw"><img src="https://i.ytimg.com/vi_webp/pomeohwS9rw/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Artigo mencionado no vídeo: <a href="https://www.lucascaton.com/2017/10/04/refiz-meu-blog-do-zero">Refiz meu blog do zero</a></p>
<hr>
<h3>Como começar?</h3>
<p>Uma das maneiras mais práticas de começar é usando o <a href="https://br.wordpress.com/">Wordpress</a>. É uma plataforma gigante, de graça e tem muitos temas e plugins. Sem contar a comunidade que é gigante, então é muito fácil encontrar no Google soluções para qualquer problema que você eventualmente tenha.</p>
<p>Se você quiser algo um pouco mais avançado (gerando páginas que tem muitos benefícios), você pode usar o
<a href="https://www.lucascaton.com/2017/10/04/refiz-meu-blog-do-zero#jekyll-vs-hugo">Jekyll ou o Hugo</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="site" /><category term="blog" /><category term="carreira" />
    </entry>

    <entry>
      <title><![CDATA[Como escrever mensagens de commits no Git]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/10/16/como-escrever-mensagens-de-commits-no-git?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-10-16T08:13:55.000Z</published>
      <updated>2017-10-16T08:13:55.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/10/16/como-escrever-mensagens-de-commits-no-git</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/10/16/como-escrever-mensagens-de-commits-no-git">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://xkcd.com/1296/"><img src="/images/posts/2017/10/git-commits-messages.jpg" alt="Mensagens de commits do Git"></a></p>
<p>Se você nunca viu/escreveu mensagens de <em>commits</em> como estas acima, parabéns.</p>
<p>Apesar de a maioria dos desenvolvedores escrever boas mensagens, não podemos generalizar:
sempre tem alguém para <del>provar que a zueira não tem limites</del> estragar a estatística.</p>
<h2>Como escrever boas mensagens</h2>
<p>Devemos escrever a mensagem no presente? No futuro? Em português? Em inglês?
São infinitas as formas as quais uma mensagem de <em>commit</em> pode ser escrita.</p>
<p>Antes de mais nada, você deveria escrever as mensagens de <em>commits</em> em <strong>inglês</strong>. Eu escrevi um
artigo com <a href="https://www.lucascaton.com/2015/05/22/8-motivos-pra-programar-em-ingles">8 motivos para programar em inglês</a>, e os
mesmos motivos se aplicam aqui.</p>
<p>O correto é escrever na <strong>forma imperativa</strong>.
Ou seja, você precisa sempre estar apto a completar a seguinte frase:</p>
<blockquote>
<p>If applied, this commit will <code>your subject line here</code></p>
</blockquote>
<p>Tradução livre: "Se aplicado, esse commit vai <code>seu resumo aqui</code>"</p>
<h2>Exemplos:</h2>
<p>Encontrei exemplos bacanas <a href="https://cbea.ms/git-commit/">nesse artigo (em inglês)</a>
e vou listá-los abaixo:</p>
<ul>
<li>✅ If applied, this commit will <code>Refactor subsystem X for readability</code></li>
<li>✅ If applied, this commit will <code>Update getting started documentation</code></li>
<li>✅ If applied, this commit will <code>Remove deprecated methods</code></li>
<li>✅ If applied, this commit will <code>Release version 1.0.0</code></li>
<li>✅ If applied, this commit will <code>Merge pull request #123 from user/branch</code></li>
</ul>
<p>Note como isso <strong>não</strong> fica legal escrevendo de forma não-imperativa:</p>
<ul>
<li>❌ If applied, this commit will <code>Fixed bug with Y</code></li>
<li>❌ If applied, this commit will <code>Changing behavior of X</code></li>
<li>❌ If applied, this commit will <code>More fixes for broken stuff</code></li>
<li>❌ If applied, this commit will <code>Sweet new API methods</code></li>
</ul>
<p>Nota: não é preciso adicionar um ponto no final da mensagem.</p>
<h2>Resumo e corpo da mensagem do commit</h2>
<p>Encontrei nesse <a href="http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html">artigo</a>
um modelo (em inglês) de mensagem para commits:</p>
<pre><code>Capitalized, short (50 chars or less) summary
More detailed explanatory text, if necessary.  Wrap it to about 72
characters or so.  In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body.  The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
or "Fixes bug."  This convention matches up with commit messages generated
by commands like git merge and git revert.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, followed by a
  single space, with blank lines in between, but conventions vary here
- Use a hanging indent
</code></pre>
<p>Basicamente a primeira linha - conhecida como <em>summary</em> (resumo) - deve conter 50 ou menos caracteres,
enquanto que as linhas seguintes - conhecidas como <em>body</em> (corpo) - pode conter quantas linhas forem necessárias, limitadas a 72 caracteres por linha.</p>
<p>No corpo, eu costumo incluir explicações detalhadas, links, listas e qualquer outra coisa relevante quando necessário.</p>
<h2>Por que uma boa mensagem importa?</h2>
<p>Alguns motivos:</p>
<ul>
<li>Caso um bug seja introduzido, uma boa mensagem de <em>commit</em> facilita a identificação de onde/quando isso aconteceu;</li>
<li>Se você <a href="https://git-scm.com/docs/git-revert">reverter um commit</a>, a mensagem será <code>Revert "mensagem original"</code>, deixando claro o que está sendo revertido;</li>
<li>Boas mensagens se tornam útias ao exibir listas de commits através de comandos como <code>git blame</code>, <code>git log</code>, <code>git shortlog</code>, etc.</li>
</ul>
<p>Para finalizar, a regra principal é o <strong>bom senso</strong>.
Se você usar como desculpa que não teve 10 segundos pra pensar em uma boa mensagem, eu vou certamente duvidar :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="git" />
    </entry>

    <entry>
      <title><![CDATA[O que haverá de novo no Ruby 2.5?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/10/11/o-que-havera-de-novo-no-ruby-2-5?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-10-11T07:17:26.000Z</published>
      <updated>2017-10-11T07:17:26.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/10/11/o-que-havera-de-novo-no-ruby-2-5</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/10/11/o-que-havera-de-novo-no-ruby-2-5">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2017/10/ruby.jpg" alt="ruby"></p>
<p>A versão <code>2.5.0-preview1</code> da linguagem Ruby acaba de ser liberada.
Por não se tratar de uma versão estável, seu uso ainda <strong>não é recomendado</strong>.</p>
<h2>Novas funcionalidades</h2>
<h3>Backtrace invertido</h3>
<p>O <strong>backtrace</strong> (lista de métodos que foram executados antes de um erro acontecer) vai começar a ser exibida em ordem inversa.
Usando o seguinte código como exemplo:</p>
<pre><code class="language-ruby"># Arquivo `teste.rb`
def a
  b
end
def b
  c
end
def c
  raise 'error'
end
a
</code></pre>
<p><strong>Executando com Ruby 2.4:</strong></p>
<pre><code class="language-bash">$ ruby teste.rb
teste.rb:10:in `c': error (RuntimeError)
    from teste.rb:6:in `b'
    from teste.rb:2:in `a'
    from teste.rb:13:in `&#x3C;main>'
</code></pre>
<p><strong>Executando com Ruby 2.5:</strong></p>
<pre><code class="language-bash">Traceback (most recent call last):
    3: from teste.rb:13:in `&#x3C;main>'
    2: from teste.rb:2:in `a'
    1: from teste.rb:6:in `b'
</code></pre>
<h3>Rescue/else/ensure serão permitidos dentro de blocos do/end</h3>
<p><strong>Executando com Ruby 2.4:</strong></p>
<p>Atualmente nós só conseguimos capturar <code>exceptions</code> dentro de métodos ou blocos <code>begin</code>/<code>end</code>, ou seja:</p>
<pre><code class="language-ruby">begin
  raise 'boom'
rescue Exception => e
  puts "Erro capturado: #{e.message}"
end
</code></pre>
<p>Saída: <code>Erro capturado: boom</code>.</p>
<pre><code class="language-ruby">def meu_metodo
  raise 'boom'
rescue Exception => e
  puts "Erro capturado: #{e.message}"
end
meu_metodo
</code></pre>
<p>Saída: <code>Erro capturado: boom</code>.</p>
<p>Porém o código abaixo não funciona:</p>
<pre><code class="language-ruby">[1, 2, 3].map do |i|
  raise 'boom'
rescue Exception => e
  puts "Erro capturado: #{e.message}"
end
</code></pre>
<pre><code>syntax error, unexpected keyword_rescue, expecting keyword_end
rescue Exception => e
</code></pre>
<p><strong>Executando com Ruby 2.5:</strong></p>
<p>Na versão que está para ser lançada, isso é possível. A saída do código acima será:</p>
<pre><code>Erro capturado: boom
Erro capturado: boom
Erro capturado: boom
</code></pre>
<h3>Novo método yield_self</h3>
<p>De acordo com a <a href="https://docs.ruby-lang.org/en/trunk/Object.html#method-i-yield_self">documentação oficial</a>:</p>
<blockquote>
<p>Yields self to the block and returns the result of the block.</p>
</blockquote>
<p>Apesar de ser muito parecido com o método <code>tap</code> da classe <code>Object</code> (que é muito útil, diga-se de passagem), seus <strong>retornos</strong> são diferentes.</p>
<p>Enquanto que com o método <code>tap</code> você abre um bloco e no final o próprio objeto é retornado, com o <code>yield_self</code>, o resultado do bloco é retornado.</p>
<p>Exemplo:</p>
<pre><code class="language-ruby">objeto.tap { |obj| obj.save } # => objeto
# O método `save` foi chamado,
# mas `objeto` é que é retornado
</code></pre>
<pre><code class="language-ruby">objeto.yield_self { |obj| obj.save } # => true
# A última execução do bloco será retornada.
# Ou seja, se supormos que o método `save` retorna `true`,
# o retorno dessa linha toda será `true` também
</code></pre>
<p>Não consegui pensar em um caso prático pra usá-lo, mas com certeza teve uma razão para ter sido adicionado :)</p>
<h2>Outras mudanças</h2>
<p>A nova versão também trará outras novidades, como suporte ao Unicode versão 10, que inclui
<a href="https://emojipedia.org/emoji-5.0/">56 emojis criados esse ano</a>.
Você pode ver uma lista completa com todas as novidades
<a href="https://github.com/ruby/ruby/blob/v2_5_0_preview1/NEWS">nesse documento</a>.</p>
<hr>
<p>Para instalar o <strong>Ruby 2.5</strong> (apesar de ainda não recomendado por não ser uma versão estável) através do RVM, basta rodar:</p>
<pre><code>rvm install 2.5.0-preview1
</code></pre>
<p><em>Happy hacking!</em></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="programacao" /><category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[Refiz meu blog do zero]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/10/04/refiz-meu-blog-do-zero?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-10-03T22:17:42.000Z</published>
      <updated>2017-10-03T22:17:42.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/10/04/refiz-meu-blog-do-zero</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/10/04/refiz-meu-blog-do-zero">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.lucascaton.com/2009/07/14/primeiro-post">Começei esse blog</a> usando <strong>WordPress</strong>.
Alguns anos depois <a href="https://www.lucascaton.com/2011/05/19/porque-voltei-a-usar-o-wordpress">migrei para Enki</a> (uma <em>engine open-source</em> baseada em Ruby on Rails), mas acabei voltando tudo como era antes depois de apenas 2 semanas e relatando o motivo <a href="/2011/05/19/porque-voltei-a-usar-o-wordpress">nesse artigo</a>.
Tudo estava relativamente bem desde então; WordPress continua sendo sensacional na minha opinião.</p>
<p>Mas eu queria mudar algumas coisas e abandonar o WordPress é sempre um <em>trade-off</em>.
A migração acabou dando mais trabalho do que eu previ, no entanto fiquei muito satisfeito com o resultado.
Vou contar um pouco o que foi alterado e porquê:</p>
<h2>Nova fase do blog/site</h2>
<p>Talvez o motivo mais relevante para eu ter feito todas essas mudanças, é porque pretendo publicar mais conteúdo aqui.
Alunos do <a href="https://www.lucascaton.com/cursos/cplc">meu curso</a> me pedem explicações fora do contexto do curso e que eu acho que também seria interessante para quem já me segue aqui.</p>
<h2>Páginas estáticas</h2>
<p>A maior alteração foi começar usar uma ferramenta que gere arquivos estáticos.
Isso significa que nesse exato momento você <strong>não</strong> está lendo um artigo gerado dinamicamente, são apenas arquivos HTML, CSS e JS pré-compilados (e recompilados quando eu escrevo um novo artigo ou altero um antigo).</p>
<p>Isso tem uma série de vantagens, sendo <strong>performance</strong> uma das mais importantes. Como o arquivo HTML já está gerado e pronto para ser lido, as páginas abrem muito rápido!</p>
<p>Eu considerei duas ferramentas para isso:</p>
<h2>Jekyll vs Hugo</h2>
<p>Como já fiz bastante coisa usando o <a href="https://jekyllrb.com/">Jekyll</a>, essa seria a escolha mais óbvia.
Porém, eu dei uma chance à uma outra ferramenta bastante similar chamada <a href="https://gohugo.io/">Hugo</a>, principalmente por influência de dois amigos que o usam:
<a href="https://pothix.com/post/hugo-github-pages-and-https/">Pothix</a> e
<a href="https://tableless.com.br/site-tableless-estatico/">Diego Eis</a>.</p>
<p>A instalação foi tranquila (apesar dele não vir com um tema padrão), mas acabei tendo alguns problemas e não quis perder mais tempo do que eu já tinha perdido com isso.
No final das contas, eu não vi uma real vantagem em relação ao Jekyll: os procedimentos e resultados de ambos são muito parecidos (me avise nos comentários se eu estiver perdendo algo grandioso que eu não sei).</p>
<p>Acho que o Jekyll tem uma comunidade maior (e consequentemente um maior número de gems/plugins) enquanto que o Hugo é absurdamente mais rápido. Fiquei com o Jekyll e estou bastante satisfeito :)</p>
<h3>Artigos em Markdown</h3>
<p>Muitas pessoas que escrevem frequentemente gostam da sintaxe <a href="https://daringfireball.net/projects/markdown/">Markdown</a> e não é a toa:
é muito prático formatar texto e usar o editor de textos de sua preferência.</p>
<p>Utilizei o <a href="https://github.com/jekyll/jekyll-import">jekyll-import</a>, ferramenta oficial do Jekyll para importar conteúdo de outros gerenciadores de blogs. Fiquei surpreso de quão bem tudo funcionou!</p>
<p>Agora, 90% dos posts estão devidamente migrados para MarkDown, mas a parte bacana é que códigos HTML podem ser inseridos em arquivos MarkDown sem nenhum efeito colateral: tudo funcionará conforme o esperado.</p>
<h3>URL</h3>
<p>Era hora de eu finalmente mudar a URL também; juntar o blog com outras coisas que eu publicava no domínio principal (<code>www.lucascaton.com.br</code>), o que possivelmente irá melhorar um pouco o <strong>SEO</strong>.</p>
<p>O subdomínio <code>blog.lucascaton.com.br</code> agora redireciona para o novo endereço <code>www.lucascaton.com.br</code>.
O restante do endereço continua exatamente o mesmo, o que facilitou nos redirecionamentos que adicionei ao <strong>nginx</strong>.</p>
<h3>Único repositório</h3>
<p>Por causa da mudança da URL, acabei juntando os dois repositórios (blog e meu site) em um só, facilitando as alterações e <em>deployments</em>.</p>
<h3>Faxina</h3>
<p>Aproveitei para apagar muitos (35 para ser exato) artigos antigos que ou não fazem mais sentido ou não eram tão bons:</p>
<p><img src="/images/posts/2017/10/35-posts-deleted.jpg" alt="35-posts-deleted"></p>
<p>Se por qualquer motivo você precisar de um artigo antigo que foi deletado, me avise nos comentários.</p>
<h3>Comentários</h3>
<p>Utilizo o <a href="https://disqus.com/">Disqus</a> para gerenciamento dos comentários e como mudei o domínio, foi necessário uma migração.
A boa notícia é que o site oferece uma <a href="https://disqus.com/admin/discussions/migrate/">ótima ferramenta para isso</a>, apesar de ser um pouco confusa:</p>
<blockquote class="twitter-tweet" data-lang="en-gb"><p lang="en" dir="ltr">[@disqus](https://twitter.com/disqus?ref_src=twsrc%5Etfw) hi there. All comments from my website are no longer showing up, could you please shed some light?[https://t.co/O0AhxhnQcX](https://t.co/O0AhxhnQcX)</p>&mdash; Lucas Caton (@lucascaton) [3 October 2017](https://twitter.com/lucascaton/status/915353715783041024?ref_src=twsrc%5Etfw)</blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Por fim, resolvi o problema seguindo <a href="https://disqus.com/home/channel/discussdisqus/discussion/channel-discussdisqus/bug_reports_feedback_comments_are_on_disqus_admin_but_not_on_my_website/#comment-3556230045">esses passos</a>.</p>
<h3>Hospedagem</h3>
<p>Uma das vantagens de gerar arquivos 100% estáticos é a facilidade para hospedá-los.
Seria bastante simples (e barato) armazená-los no <a href="https://aws.amazon.com/s3/">S3</a>, que é como eu faço no <a href="http://blog.easybills.io/br/">blog do Easy Bills</a>.
Mas o <a href="https://pages.github.com/">GitHub Pages</a> é tão simples quanto e ainda é gratuito, o que me fez escolher essa opção.</p>
<p><del>No momento, os arquivos ainda estão no servidor antigo - no qual eu rodava o WordPress - por um simples motivo: analisar os logs e ver se eu esqueci algum <em>redirect</em> importante.</del> Tudo devidamente migrado e rodando no <strong>GitHub Pages</strong> agora! \o/</p>
<h3>SSL</h3>
<p>Eu usava <a href="https://letsencrypt.org/">Let's Encrypt</a> para gerar certificados SSL, mas como pretendo mover os arquivos para o GitHub Pages em breve, comecei a usar o
<a href="https://www.cloudflare.com/"><strong>Cloudflare</strong></a>, que também é ótimo!</p>
<h2>Novo layout</h2>
<p><img src="/images/posts/2017/10/new-layout.png" alt="new-layout"></p>
<hr>
<p>É isso! Se tiver qualquer dúvida, me mande nos comentários :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="site" /><category term="blog" /><category term="jekyll" /><category term="hugo" />
    </entry>

    <entry>
      <title><![CDATA[How to run your feature specs using Capybara and Headless Chrome]]></title>
      <summary><![CDATA[Enjoy faster testing!]]></summary>
      <link href="https://www.lucascaton.com/2017/06/22/how-to-run-your-feature-specs-using-capybara-and-headless-chrome?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-06-22T11:03:20.000Z</published>
      <updated>2018-04-15T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2017/06/22/how-to-run-your-feature-specs-using-capybara-and-headless-chrome</id>
      <content type="html" xml:base="https://www.lucascaton.com/2017/06/22/how-to-run-your-feature-specs-using-capybara-and-headless-chrome">
        <![CDATA[<div xml:lang="en"><p>Google has recently announced a way to run the
<a href="https://developers.google.com/web/updates/2017/04/headless-chrome">Chrome browser in a headless environment</a>.
If you're using <a href="https://github.com/teamcapybara/capybara">Capybara gem</a>,
you can easily start using headless Chrome. Without further ado, let's do it:</p>
<ol>
<li>Make sure you have one of the following <strong>Chrome versions</strong>:</li>
</ol>
<ul>
<li>57+ on <strong>Linux</strong></li>
<li>59+ on <strong>macOS</strong></li>
<li>60+ on <strong>Windows</strong></li>
</ul>
<ol start="2">
<li>
<p>Add (or update) the gem <code>selenium-webdriver</code>;</p>
</li>
<li>
<p>Make sure you're using <strong>ChromeDriver</strong> version 2.30 or higher.
You can install it by running:</p>
</li>
</ol>
<ul>
<li><code>brew install chromedriver</code> on <strong>macOS</strong>;</li>
<li><code>apt-get install chromium-chromedriver</code> on <strong>Debian/Ubuntu Linux</strong>.</li>
</ul>
<ol start="4">
<li>Add the following <code>driver</code> to your <code>spec/support/capybara.rb</code>, <code>spec/spec_helper.rb</code>, or <code>spec/rails_helper.rb</code>:</li>
</ol>
<pre><code class="language-ruby">Capybara.javascript_driver = :selenium_chrome_headless
</code></pre>
<p>Or, if you need to use some custom options:</p>
<pre><code class="language-ruby">Capybara.register_driver :chrome do |app|
  Capybara::Selenium::Driver.new app, browser: :chrome,
    options: Selenium::WebDriver::Chrome::Options.new(args: %w[headless disable-gpu])
end
Capybara.javascript_driver = :chrome
</code></pre>
<p>Done, enjoy headless Chrome! ᕕ( ᐛ )ᕗ</p>
<hr>
<p>You might get a warning like the following:</p>
<pre><code class="language-bash">WARN Selenium [DEPRECATION] :args or :switches is deprecated. Use Selenium::WebDriver::Chrome::Options#add_argument instead.
</code></pre>
<p>Make sure you don't have another registered driver, I made this mistake myself and had an <code>iphone</code> driver, which was passing <code>args</code> in the old way and turned out to be the reason why I was getting the warning.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="chrome" /><category term="linux" /><category term="windows" /><category term="rspec" /><category term="selenium" /><category term="capybara" /><category term="headless" /><category term="macOS" /><category term="capybara-driver" /><category term="headless-chrome" />
    </entry>

    <entry>
      <title><![CDATA[Meu Curso de Programação]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/03/07/meu-curso-de-programacao?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-03-07T08:56:33.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/03/07/meu-curso-de-programacao</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/03/07/meu-curso-de-programacao">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.lucascaton.com/cursos/cplc/"><img src="/images/posts/2017/03/cover.jpg" alt="cover"></a></p>
<p>É com muito prazer que venho contar a vocês que finalmente publiquei meu <strong>Curso de Programação</strong>.</p>
<p>Caso você não me conheça, meu nome é Lucas, sou desenvolvedor desde 2004, fundador da startup
<a href="https://www.easybills.io/?locale=pt-BR">Easy Bills</a>, escrevo nesse blog desde 2009 e dei o meu
melhor para criar um curso para quem quer <strong>aprender a programar começando do zero, através de
videoaulas 100% online</strong>.</p>
<p>Com esse curso, você aprenderá a criar páginas web dinâmicas, criar aplicações onde o usuário
precisa se autenticar (login e senha), enviar emails através da sua aplicação, criar layouts para
páginas mesmo sem ter experiência em design, negociar a venda de projetos (incluindo preços), qual
salário é justo para o seu nível e muito mais.</p>
<p>E você vai desenvolver dois aplicativos durante o curso, um <strong>gerenciador de tarefas</strong> e um
<strong>clone do Instagram</strong>.</p>
<p><aside><a href="https://www.lucascaton.com/cursos/cplc">Clique aqui</a> para mais informações.</aside></p>
<p>Visite a página do curso ou marque nos comentários abaixo aquele amigo que quer aprender programação :)</p>
<hr>
<p>Abaixo você encontra um vídeo com mais detalhes sobre o curso:</p>
<p><a href="https://www.youtube.com/watch?v=N94o9ox6ZdY"><img src="https://i.ytimg.com/vi_webp/N94o9ox6ZdY/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="css" /><category term="rails" /><category term="linguagem-de-programacao" /><category term="javascript" /><category term="programacao" /><category term="curso" /><category term="html" /><category term="mercado-de-trabalho" />
    </entry>

    <entry>
      <title><![CDATA[How to set up multiple Heroku accounts in heroku-cli]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2017/02/13/how-to-setup-multiple-heroku-accounts-in-heroku-cli?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-02-13T08:17:00.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2017/02/13/how-to-setup-multiple-heroku-accounts-in-heroku-cli</id>
      <content type="html" xml:base="https://www.lucascaton.com/2017/02/13/how-to-setup-multiple-heroku-accounts-in-heroku-cli">
        <![CDATA[<div xml:lang="en"><p><img src="/images/posts/2017/02/how-to-setup-multiple-heroku-accounts-in-heroku-cli.jpg" alt="heroku"></p>
<p>Both <a href="https://heroku.com/">Heroku</a> and <a href="https://devcenter.heroku.com/articles/heroku-cli">its CLI</a> are great. However, there's no way to access multiple accounts via terminal out of the box. If you have a personal and a work account and need an easy way to switch between them, I have good news for you! :)</p>
<p>Heroku's team has created a plugin called <a href="https://github.com/heroku/heroku-accounts">heroku-accounts</a>. You can find <a href="https://github.com/heroku/heroku-accounts#installation">how to install</a> and <a href="https://github.com/heroku/heroku-accounts#usage">how to use</a> in its project page on Github.</p>
<p>To make it even easier, I've added the following aliases to my <code>~/.zshrc</code> (or <code>~/.bashrc</code>):</p>
<pre><code class="language-bash"># Heroku
alias hp='heroku accounts:set personal'
alias hw='heroku accounts:set work'
</code></pre>
<p>Happy hacking!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="heroku" /><category term="zshrc" /><category term="plugins" /><category term="heroku-accounts" />
    </entry>

    <entry>
      <title><![CDATA[Li e recomendo o livro "Desconstruindo a Web"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2017/02/09/li-e-recomendo-o-livro-desconstruindo-a-web?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2017-02-08T22:37:07.000Z</published>
      <updated>2021-07-01T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2017/02/09/li-e-recomendo-o-livro-desconstruindo-a-web</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2017/02/09/li-e-recomendo-o-livro-desconstruindo-a-web">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2017/02/daw.jpg" alt="daw"></p>
<p>Acabei de ler o livro <strong>"Desconstruindo a Web: As tecnologias por trás de uma requisição"</strong>, escrito
pelo meu amigo <a href="https://twitter.com/PotHix">PotHix</a> (Willian Molinari).</p>
<p>Se você é programador ou está de alguma forma envolvido com aplicações web, servidores, redes ou
simplesmente tem curiosidade de entender como a web funciona "por baixo dos panos", nos mínimos
detalhes, você deveria ler esse livro.</p>
<p>Esse não é um daqueles livros chatos que você lê na faculdade. Para você ter uma idéia, o
certificado <code>HTTPS</code> é explicado através de uma metáfora com o <em>Senhor dos Anéis</em>!
Tem como ficar mais legal que isso? 😁</p>
<p>O único detalhe é que alguns capítulos se focam bastante na área de redes e como eu vejo isso no
dia-a-dia, vou provavelmente acabar esquecendo vários conceitos explicados :)</p>
<p>Você encontra todos os detalhes do livro (inclusive como comprar) aqui:</p>
<p><a href="https://desconstruindoaweb.com.br/">https://desconstruindoaweb.com.br/</a></p>
<p>Você também pode ver
<a href="https://www.goodreads.com/book/show/31686001-desconstruindo-a-web">a página do livro no GoodReads</a>!</p>
<p>O PotHix também conta como foi o
<a href="https://pothix.com/post/escrevendo-o-desconstruindo-a-web/">processo de escrita do livro</a>,
o que eu também achei muito interessante.</p>
<p>Tenho <a href="https://www.youtube.com/watch?v=3XDLfXc3zFg">escutado muito mais podcasts</a> que livros
ultimamente, mas esse definitivamente me chamou a atenção e decidi comprar e ler.
Resultado: valeu a pena, recomendo!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="browser" /><category term="https" /><category term="livro" /><category term="web" /><category term="http" /><category term="servidores" />
    </entry>

    <entry>
      <title><![CDATA[[Ruby] How to get the name of the calling method?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2016/11/04/ruby-how-to-get-the-name-of-the-calling-method?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2016-11-04T03:36:04.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2016/11/04/ruby-how-to-get-the-name-of-the-calling-method</id>
      <content type="html" xml:base="https://www.lucascaton.com/2016/11/04/ruby-how-to-get-the-name-of-the-calling-method">
        <![CDATA[<div xml:lang="en"><p>I was about to run a rake task which would make important changes in my database.
My code was similar to this:</p>
<pre><code class="language-ruby">def migrate_active_accounts
  accounts = Account.active
  # Code to migrate accounts here...
end
def migrate_inactive_accounts
  accounts = Account.inactive
  # Code to migrate accounts here...
end
</code></pre>
<p>This migration was very critical. Thus, I decided to log everything to make sure it would run as expected.
So I wrote a separate method to log what accounts were going to run by which method.</p>
<p>In order to do that, I'd need to know which method was calling my logger method.</p>
<p>I ended up <a href="http://stackoverflow.com/a/15098459/1445184">finding the answer on StackOverflow</a> (where else would I? ).</p>
<h2>Solution</h2>
<p>As usual, Ruby has a neat solution for it: <code>Kernel</code> module has a <a href="https://ruby-doc.org/core-2.3.1/Kernel.html#method-i-caller_locations"><code>caller_locations</code></a> method, which returns an array with the current execution stack. So all we need to do is to use <code>caller_locations.first.label</code> to get the first element from the stack and then get its label.</p>
<p>My final code was looking like the following:</p>
<pre><code class="language-ruby">def migrate_active_accounts
  accounts = Account.active
  log_migration_info(accounts)
  # Code to migrate accounts here...
end
def migrate_inactive_accounts
  accounts = Account.inactive
  log_migration_info(accounts)
  # Code to migrate accounts here...
end
private
def log_migration_info(accounts)
  caller_method = caller_locations.first.label
  Rails.logger.info "Running [MyClass##{caller_method}]
    for the following accounts: #{accounts.map(&#x26;:id).to_sentence}"
end
</code></pre>
<h2>Ruby prior to 2.0</h2>
<p>If you're using an old version of Ruby (<a href="https://www.lucascaton.com/2014/02/28/have-a-rails-2-app-you-can-run-it-on-the-newest-ruby">even though you shouldn't</a>),
you'll need to use <code>caller</code> method along with a regular expression:</p>
<pre><code class="language-ruby">caller.first[/`(.*)'/, 1]
</code></pre>
<p>Happy hacking!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[New blog theme]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2016/11/04/new-blog-theme?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2016-11-04T01:11:54.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2016/11/04/new-blog-theme</id>
      <content type="html" xml:base="https://www.lucascaton.com/2016/11/04/new-blog-theme">
        <![CDATA[<div xml:lang="en"><p>Last time <a href="https://www.lucascaton.com/2012/10/02/new-blog-layout/">I updated this blog's theme</a> was in 2012! 😮</p>
<p>It was about time to have a fresh new look and there you have it! \o/</p>
<p><img src="/images/posts/2016/11/new-theme.jpg" alt="new-theme"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="site" /><category term="blog" /><category term="theme" /><category term="layout" />
    </entry>

    <entry>
      <title><![CDATA[Prevent Rails from writing log files in development and test]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2016/10/27/prevent-rails-from-writing-developmenttest-log-files?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2016-10-27T00:44:27.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2016/10/27/prevent-rails-from-writing-developmenttest-log-files</id>
      <content type="html" xml:base="https://www.lucascaton.com/2016/10/27/prevent-rails-from-writing-developmenttest-log-files">
        <![CDATA[<div xml:lang="en"><p>I can't remember the last time I needed to open/read <code>log/development.log</code> or <code>log/test.log</code>.
These files usualy just consume disk space unnecessarily (some <code>test.log</code> files can easily reach more than 1 GB).</p>
<p>After talking to some other developers, all of them agreed they don't use it as well.
So what I've been doing in my projects is adding the following code (note that it'll still display logs through the <code>STDOUT</code> though):</p>
<h2>Rails 4+</h2>
<p><code>config/environments/development.rb</code>:</p>
<pre><code class="language-ruby"># Prevents from writing logs on `log/development.log`
logger           = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger    = ActiveSupport::TaggedLogging.new(logger)
</code></pre>
<p><code>config/environments/test.rb</code>:</p>
<pre><code class="language-ruby"># Prevents from writing logs on `log/test.log`
config.log_level = :warn
logger           = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger    = ActiveSupport::TaggedLogging.new(logger)
</code></pre>
<h2>Rails 3</h2>
<p><code>config/environments/development.rb</code>:</p>
<pre><code class="language-ruby"># Prevents from writing logs on `log/development.log`
logger        = ::Logger.new(STDOUT)
config.logger = ActiveSupport::TaggedLogging.new(logger)
# Replace `config.active_support.deprecation = :log` with:
config.active_support.deprecation = :stderr
</code></pre>
<p><code>config/environments/test.rb</code>:</p>
<pre><code class="language-ruby"># Prevents from writing logs on `log/test.log`
config.log_level = :warn
logger           = ::Logger.new(STDOUT)
config.logger    = ActiveSupport::TaggedLogging.new(logger)
</code></pre>
<p>Ps.: I've sent a suggestion to <a href="https://groups.google.com/forum/?fromgroups#!searchin/rubyonrails-core/lucascaton%7Csort:relevance/rubyonrails-core/MGwMVsQPjzw/ubL8-54wAwAJ">rubyonrails-core mailing list</a> to make it default from next Rails versions, let's see their thoughts.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="rails" /><category term="logs" />
    </entry>

    <entry>
      <title><![CDATA[Puma vs. Unicorn]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2016/03/13/puma-vs-unicorn?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2016-03-13T04:24:26.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2016/03/13/puma-vs-unicorn</id>
      <content type="html" xml:base="https://www.lucascaton.com/2016/03/13/puma-vs-unicorn">
        <![CDATA[<div xml:lang="en"><blockquote>
<p><strong>TL; DR</strong> - Just use <a href="http://puma.io/">Puma</a>.</p>
</blockquote>
<p>Rails has <a href="https://github.com/rails/rails/pull/23906/files">changed its default server from Webrick to Puma</a> in Rails 5!</p>
<p>It also supports <strong>Action Cable</strong> (one of the new features from Rails 5) and Basecamp said <a href="http://weblog.rubyonrails.org/2015/12/18/Rails-5-0-beta1/">they're using Puma in production</a>.</p>
<p>I was wondering if <strong>Puma</strong> has been in fact better than <strong>Unicorn</strong> so I've read some blog posts about it:</p>
<ul>
<li><a href="http://blog.codeship.com/puma-vs-unicorn/">Codeship's</a></li>
<li><a href="https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server">Heroku's</a></li>
<li><a href="https://www.engineyard.com/articles/rails-server">EngineYard's</a></li>
</ul>
<p>Basically, the answer is <strong>yes - it is a bit better</strong>, but don't wait for a huge improvement.</p>
<p>It'd be a good idea if you're either about to start a new project and migrating your current project to Rails 5 or newer.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="rails5" /><category term="unicorn" /><category term="puma" /><category term="server" /><category term="webserver" /><category term="webrick" />
    </entry>

    <entry>
      <title><![CDATA[Rake task to import a production DB dump]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2016/03/12/rake-task-to-import-a-production-db-dump?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2016-03-11T23:45:52.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2016/03/12/rake-task-to-import-a-production-db-dump</id>
      <content type="html" xml:base="https://www.lucascaton.com/2016/03/12/rake-task-to-import-a-production-db-dump">
        <![CDATA[<div xml:lang="en"><p>Every now and then I need to write a script (rake task) to import a production database dump.</p>
<p>This is code I usually use:</p>
<pre><code class="language-ruby">require 'yaml'
namespace :db do
  desc 'Downloads and imports a production DB dump'
  task :import_production_dump do
    puts '➙ Generating production DB dump...'
    execute_on_server %(
      PGPASSWORD="`cat /var/www/project/current/config/database.yml | \
        grep password | awk '{ print $2 }'`" \
        pg_dump database_name -h custom_url.rds.amazonaws.com -U user_name \
        --column-inserts --no-owner --no-privileges > backup.sql
    )
    puts '➙ Downloading production DB dump...'
    system "scp #{server_user_and_host}:#{backup_file_name} ."
    puts '➙ Deleting production DB dump...'
    execute_on_server "rm #{backup_file_name}"
    puts '➙ Cleaning your local DB...'
    %w[drop create].each { |task| Rake::Task["db:#{task}"].invoke }
    puts '➙ Importing production DB dump...'
    system "bin/rails db development &#x3C; #{backup_file_name} > /dev/null"
    puts '➙ Removing local dump...'
    system "rm #{backup_file_name}"
    puts '➙ Done!'
  end
  def execute_on_server(commands)
    system %(ssh -T #{server_user_and_host} &#x3C;&#x3C; 'SSH'
      #{commands}
    SSH).split("\n").map(&#x26;:strip).join("\n")
  end
  def server_user_and_host
    'username@example.com'
  end
  def backup_file_name
    'backup.sql'
  end
end
</code></pre>
<p>Let me know in the comments if you have a better solution! Perhaps a small gem? :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="postgresql" /><category term="mysql" /><category term="database" />
    </entry>

    <entry>
      <title><![CDATA[[Off-topic] Como é o sotaque australiano?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2016/03/10/off-topic-como-e-o-sotaque-australiano?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2016-03-10T02:40:57.000Z</published>
      <updated>2016-03-10T02:40:57.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2016/03/10/off-topic-como-e-o-sotaque-australiano</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2016/03/10/off-topic-como-e-o-sotaque-australiano">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2016/03/sydney.jpg" alt="Cidade de Sydney"></p>
<p>Muitas pessoas me perguntam como é o sotaque australiano.</p>
<p>A primeira coisa notável é que o inglês australiano segue a gramática britânica.
Exemplo: escreve-se "colour" e "behaviour" em vez de "color" e "behavior".</p>
<p>O melhor jeito de demonstrar como é o sotaque australiano é através de vídeos, por isso selecionei alguns:</p>
<p><a href="https://www.youtube.com/watch?v=lUiBOzzdDbo"><img src="https://i.ytimg.com/vi_webp/lUiBOzzdDbo/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><em>Versão australiana do programa de TV "Family Feud"</em></p>
<p><a href="https://www.youtube.com/watch?v=dG0v9tZStAk"><img src="https://i.ytimg.com/vi_webp/dG0v9tZStAk/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><a href="https://www.youtube.com/watch?v=QVgiG7_Ey9k"><img src="https://i.ytimg.com/vi_webp/QVgiG7_Ey9k/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><a href="https://www.youtube.com/watch?v=C9cazQj3Y2k"><img src="https://i.ytimg.com/vi_webp/C9cazQj3Y2k/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><a href="https://www.youtube.com/watch?v=xuRrp83jCuQ"><img src="https://i.ytimg.com/vi_webp/xuRrp83jCuQ/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><a href="https://www.youtube.com/watch?v=ZH4ZQH_3_pE"><img src="https://i.ytimg.com/vi_webp/ZH4ZQH_3_pE/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><a href="https://www.youtube.com/watch?v=DWbYEJC4j4U"><img src="https://i.ytimg.com/vi_webp/DWbYEJC4j4U/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<p>Pra finalizar: um vídeo do canal "De dentro para fora", que explica as vantagens e desvantagens de estudar inglês australiano:</p>
<p><a href="https://www.youtube.com/watch?v=dYxVAbb0vq0"><img src="https://i.ytimg.com/vi_webp/dYxVAbb0vq0/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><aside>Se você quiser saber mais sobre a Austrália, se inscreva no meu outro <a href="https://www.youtube.com/RezaaLenda?sub_confirmation=1">canal no YouTube</a> e entre no grupo do Facebook <a href="https://www.facebook.com/groups/comoirparaaaustralia/">Brasileiros que querem ir para a Austrália</a>! 🙂</aside></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" /><category term="ingles" />
    </entry>

    <entry>
      <title><![CDATA[Why I regenerated my SSH key and maybe you should too]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2016/02/23/why-i-regenerated-my-ssh-key-and-maybe-you-should-too?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2016-02-23T08:55:15.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2016/02/23/why-i-regenerated-my-ssh-key-and-maybe-you-should-too</id>
      <content type="html" xml:base="https://www.lucascaton.com/2016/02/23/why-i-regenerated-my-ssh-key-and-maybe-you-should-too">
        <![CDATA[<div xml:lang="en"><p><img src="/images/posts/2016/02/security.jpg" alt="security"></p>
<p>I think we all agree it's a good practice to regenerate your SSH key from time to time. Not sure about you, but the first thing that comes to my mind when I think about that is: it'd take forever to replace my key in all servers I need to access, all online services that use my key, etc.</p>
<p>Overcoming my laziness, I decided at least to list those place it turned out it was a small list:</p>
<ul>
<li>Servers</li>
<li>Github</li>
<li>BitBucket</li>
</ul>
<p>Although now it looks more reasonable, I was still lazy to do it. But then I noticed that <a href="https://help.github.com/articles/which-remote-url-should-i-use/">Github recommends</a> the use of <strong>HTTPS</strong> instead of <strong>SSH</strong> for Git repositories syncs:</p>
<p><img src="/images/posts/2016/02/1.jpg" alt="1"></p>
<p>What does one thing have to do with another? Well, by using <code>HTTPS</code>, you don't need to upload your SSH key to <strong>Github</strong> (check this out: <a href="https://github.com/lucascaton.keys">mine isn't longer at Github</a>).</p>
<p><strong>BitBucket</strong> also supports it, which means I'd be able to regenerate my SSH key without having to upload it again to these services.</p>
<h2>Servers</h2>
<p>What's left? Servers! From now on, every time I realise it's time to regenerate my SSH key, all I need to update are the servers.
I ended up making a list of servers that I'd need to update and found out in the end it wasn't a big list and it'd be way easier than I thought it would.</p>
<p>Let's face the truth: I had been using the same SSH key in the last 5 years or so and it'd be totally worth it to ensure my security as well as the security of the projects from the company I work for.</p>
<h2>Becoming safer</h2>
<p>There's more! This is the interesting part of this post: I've changed other things that made everything even safer:</p>
<ul>
<li>My new SSH key uses <strong>4096 bits</strong> - <a href="https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/">recommended by Github</a> - instead of the default (<strong>2048 bits</strong>).</li>
<li>As I mentioned before, I've changed all my local repositories to use <code>HTTPS</code> instead of <code>SSH</code> (see how in the end of this post).</li>
<li>I'm now using a <a href="https://help.github.com/articles/creating-an-access-token-for-command-line-use/">personal access token</a> rather than my Github password (you can <a href="https://github.com/settings/tokens">create it here</a>), along with <a href="https://help.github.com/articles/about-two-factor-authentication/">two-factor authentication</a>, which I was already using.</li>
<li>Cool, but would I need to type this token every time? Nope. There's a nifty tool called <code>ssh-agent</code> that can save your token. If you're using macOS, it's even easier: <a href="https://help.github.com/articles/working-with-ssh-key-passphrases/#os-x-keychain">Keychain</a> can save and encrypt your token for you.</li>
<li>My SSH key now has a <a href="https://help.github.com/articles/working-with-ssh-key-passphrases/">passphrase</a>, also saved encrypted on macOS's Keychain, which means I don't need to type it every time either.</li>
</ul>
<h2>HTTPS is faster!</h2>
<p>According to some tests I made here, <code>HTTPS</code> is faster than <code>SSH</code>:</p>
<pre><code class="language-bash"># SSH
$ time git clone git@github.com:rails/rails.git
# 24.28s user 9.56s system 49% cpu 1:08.20 total
</code></pre>
<pre><code class="language-bash"># HTTPS
$ time git clone https://github.com/rails/rails.git
# 13.52s user 6.41s system 39% cpu 50.730 total
</code></pre>
<h2>In order to use HTTPS in my Git repos, do I need to re-clone every project?</h2>
<p>Nope. Just open <code>.git/config</code> file and replace:</p>
<pre><code class="language-bash">url = git@github.com:username/repo.git
</code></pre>
<p>with:</p>
<pre><code class="language-bash">url = https://github.com/username/repo.git
</code></pre>
<h2>Conclusion</h2>
<p>Regenerating your SSH key every now and then isn't as painful as you might think.
I'd recommend doing it every 3 years or even less if you're paranoic or you work on something critic.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="github" /><category term="ubuntu" /><category term="linux" /><category term="git" /><category term="macOS" /><category term="ssh" /><category term="https" /><category term="ssh-key" /><category term="bitbucket" /><category term="servers" />
    </entry>

    <entry>
      <title><![CDATA[What is "frozen_string_literal" in Ruby?]]></title>
      <summary><![CDATA[Why use this magic comment?]]></summary>
      <link href="https://www.lucascaton.com/2016/01/19/what-is-frozen_string_literal-in-ruby?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2016-01-18T23:33:30.000Z</published>
      <updated>2024-09-11T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2016/01/19/what-is-frozen_string_literal-in-ruby</id>
      <content type="html" xml:base="https://www.lucascaton.com/2016/01/19/what-is-frozen_string_literal-in-ruby">
        <![CDATA[<div xml:lang="en"><p><strong>Freezing Strings</strong> feature improves apps performance by freezing Strings. So, <a href="https://twitter.com/yukihiro_matz">Matz</a>, Ruby's creator, decided to make all String literals frozen (immutable) <a href="https://bugs.ruby-lang.org/issues/11473">by default in Ruby 3.0</a>. <em>Update: the Ruby team changed their mind and this didn't happen when Ruby 3.0 was released.</em></p>
<p>In order to have a transition path to this coming big change, it was decided to have a magic comment at the beginning of files, so you can use in <strong>Ruby 2.x</strong>.
To do so, just add this comment in the first line of your files:</p>
<pre><code class="language-ruby"># frozen_string_literal: true
class YourClass
  # ...
end
</code></pre>
<p>Try adding it to your <code>spec_helper</code> or <code>rails_helper</code> file and let me know in the comments if your performance gets any better.</p>
<hr>
<p>More info: <a href="https://bugs.ruby-lang.org/issues/8976">Ruby issue #8976</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="frozen-string-literal" />
    </entry>

    <entry>
      <title><![CDATA[If you really need to create a monkey patch, do it properly]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2015/12/10/if-you-really-need-to-create-a-monkey-patch-do-it-properly?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2015-12-10T05:15:44.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2015/12/10/if-you-really-need-to-create-a-monkey-patch-do-it-properly</id>
      <content type="html" xml:base="https://www.lucascaton.com/2015/12/10/if-you-really-need-to-create-a-monkey-patch-do-it-properly">
        <![CDATA[<div xml:lang="en"><p><img src="/images/posts/2015/12/Top-5-Ruby-IDE-Solutions-for-Web-Developers.png" alt="Top-5-Ruby-IDE-Solutions-for-Web-Developers"></p>
<p>Sometimes we need to create a monkey patch for a gem or external lib. In these cases, it's good to force it to fail if the gem has been bumped up. Let's use Paperclip as an example:</p>
<pre><code class="language-ruby">if Paperclip::VERSION != '1.2.3'
  # If you see this message, please test removing this file
  # If it's still required, please bump up the version above
  fail 'Please remove me, Paperclip version has changed'
end
</code></pre>
<p>If the gem doesn't provide you the version through a method, you can solve it with:</p>
<pre><code class="language-ruby">if Bundler.load.specs.find { |gem| gem.name == 'paperclip' }.version.to_s != '1.2.3'
  # If you see this message, please test removing this file
  # If it's still required, please bump up the version above
  fail 'Please remove me, Paperclip version has changed'
end
</code></pre>
<p>Or even when you're waiting for a new Rails version, e.g.:</p>
<pre><code class="language-ruby">fail 'Remove this file' if Rails::VERSION::MAJOR >= 5
</code></pre>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="monkey-patch" />
    </entry>

    <entry>
      <title><![CDATA[Como eu faço backups]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2015/08/23/como-eu-faco-backups?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2015-08-23T05:39:41.000Z</published>
      <updated>2025-01-25T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2015/08/23/como-eu-faco-backups</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2015/08/23/como-eu-faco-backups">
        <![CDATA[<div xml:lang="pt-BR"><p>Faz tempo que penso em escrever sobre as ferramentas e estratégias que utilizo para backups.
Ao escutar <a href="https://tecnoblog.net/181260/tecnocast-024-quem-tem-um-nao-tem-nenhum/">esse episódio do Tecnocast sobre o assunto</a>, decidi que era hora de documentar o que eu faço.</p>
<h2>Meus arquivos pessoais (pasta ~/)</h2>
<p><img src="/images/posts/2015/08/Screen-Shot-2015-08-23-at-2.08.16-pm.png" alt="Screen-Shot-2015-08-23-at-2.08.16-pm"></p>
<p>A pasta do meu usuário possui 3 cópias extras:</p>
<ol>
<li>
<p>Assino o plano familiar (U$ 12,50/mês) do <a href="https://www.code42.com/crashplan/"><strong>CrashPlan</strong></a>, o qual realiza backup automatico e em tempo real do meu computador, da minha esposa e ainda do da minha mãe. Todos os dados ficam na nuvem e eu consigo recuperá-los a qualquer momento, a partir de qualquer lugar, de qualquer computador.</p>
</li>
<li>
<p>A segunda cópia extra dos meus arquivos ficam no meu <a href="http://www.apple.com/br/airport-time-capsule/"><strong>TimeCapsule</strong></a>, que rodam diariamente de forma automática através do <a href="http://www.apple.com/br/airport-time-capsule/#time-machine"><strong>Time Machine</strong></a>.</p>
</li>
<li>
<p>Por fim, faço uma <strong>cópia mensal num HD externo</strong> (que é bem rápido graças à sua conexão USB 3) utilizando o rsync pra realizar um backup diferencial. O comando / parametros que utilizo para isso é:</p>
</li>
</ol>
<pre><code class="language-bash">rsync -a --progress \
  --delete --delete-excluded --exclude "*.DS_Store" \
  /Users/lucascaton/ /Volumes/Backups/lucascaton/
</code></pre>
<blockquote>
<p><strong>Importante:</strong> não esqueça do <code>/</code> no final de cada <code>path</code> do comando acima.</p>
</blockquote>
<h2>Arquivos importantes</h2>
<p><img src="/images/posts/2015/08/important-files.jpg" alt="important-files"></p>
<p>Ficam dentro da pasta do <a href="https://www.dropbox.com/"><strong>Dropbox</strong></a>. Ou seja, uma cópia extra além do CrashPlan, Time Machine e HD externo mencionados acima.</p>
<h2>Arquivos encriptografados</h2>
<p><img src="/images/posts/2015/08/20-seguranca.jpg" alt="20-seguranca"></p>
<p>Se você utiliza <del>OS X</del> macOS, é fácil criar uma pasta protegida com senha (tecnicamente é uma imagem de disco, mas você pode encarar como se fosse uma pasta). Veja como fazer isso nesse <a href="https://support.apple.com/en-us/HT201599">artigo de suporte da Apple</a>.</p>
<p>Nessa pasta, eu guardo:</p>
<ul>
<li>Códigos de recuperação de servicos com <a href="https://en.wikipedia.org/wiki/Two-factor_authentication">autenticação de 2 fatores</a>;</li>
<li>Screenshots dos QR codes de autenticação de 2 fatores. É extremamente útil se você precisar resetar seu celular, já que o Google Authenticator (e outras apps) não salvam esses dados na nuvem (por motivos de segurança);</li>
<li>Chaves privadas SSH (pra acessar servidores);</li>
<li>Algumas poucas senhas que prefiro manter nessa pasta do que em gerenciadores de senha como o 1Password, o qual eu uso para todo o resto (veja mais informações sobre o 1Password no tópico "Senhas" no final desse artigo.</li>
</ul>
<h2>Arquivos que não ficam no meu computador</h2>
<p><img src="/images/posts/2015/08/61XThv-M2rL._SL1300_.jpg" alt="61XThv-M2rL.SL1300"></p>
<p>Alguns arquivos eu não mantenho no meu computador por serem muitos grandes ou simplesmente por não fazer sentido tê-los comigo o tempo todo. Um exemplo são os <a href="https://www.youtube.com/RezaaLenda?sub_confirmation=1">vídeos do Reza a Lenda</a>.</p>
<p>Eu os mantenho no <strong>Time Capsule</strong> e mensalmente faço um backup destes para o mesmo HD que mencionei no começo do artigo, também utilizando o <strong>rsync</strong>.</p>
<h2>VPS</h2>
<p><img src="/images/posts/2015/08/vps-hosting.png" alt="vps-hosting"></p>
<p>Faço backup das minhas <a href="https://en.wikipedia.org/wiki/Virtual_private_server">VPSs</a> através de scripts que realizam backups mensais (os quais rodam diretamente no servidor) e mandam esses arquivos para o meu computador (de novo através de um <strong>rsync</strong>).</p>
<h2>Documentos (RG, CPF, passaporte, etc)</h2>
<p><img src="/images/posts/2015/08/passport.jpg" alt="passport"></p>
<p>Tenho foto de todos os meus documentos e estes ficam em uma pasta específica dentro do meu Dropbox, a qual é sincronizada automaticamente com o meu celular (através do iTunes), tornando-se disponível no meu celular mesmo quando não há internet disponível.</p>
<h2>Fotos</h2>
<p><img src="/images/posts/2015/08/pictures-folder.png" alt="pictures-folder"></p>
<p>Não ficam na nuvem (por enquanto). Também não utilizo nenhum software para gerenciá-las, apenas pastas organizadas por datas. E não chega a ser um problema: consigo ser disciplinado e manter tudo organizado. Nunca deixo nada no celular, quando o conecto ao computador eu já copio as fotos pro lugar apropriado.</p>
<p>Apesar disso, o novo <a href="https://photos.google.com/"><strong>Google Photos</strong></a> parece um bom lugar pra mantê-las de forma segura.</p>
<h2>Músicas</h2>
<p><img src="/images/posts/2015/08/spotify.jpg" alt="spotify"></p>
<p>100% das minhas músicas estão no <a href="https://www.spotify.com/"><strong>Spotify</strong></a>. Assino o plano premium, então elas também ficam disponíveis off-line no meu celular.</p>
<h2>Emails e calendário</h2>
<p><img src="/images/posts/2015/08/gmail-and-google-calendar.jpg" alt="gmail-and-google-calendar"></p>
<p>Versões web do <a href="https://mail.google.com/"><strong>Gmail</strong></a> e <a href="https://www.google.com/calendar"><strong>Google Calendar</strong></a>. Simples assim.</p>
<h2>Senhas</h2>
<p><img src="/images/posts/2015/08/1P5-Mac-icon.png" alt="1P5-Mac-icon"></p>
<p>Gerencio todas as minhas senhas através do <a href="https://agilebits.com/onepassword"><strong>1Password</strong></a>, mas tem uma regra de ouro pra evitar problemas se a segurança do 1Password um dia falhar: a senha do meu Inbox / Gmail não está salva em lugar algum, está apenas na minha cabeça - assim eu consigo recuperar a senha de qualquer serviço caso necessário, utilizando o recurso "Esqueci minha senha", que a maioria dos serviços oferece.</p>
<h2>Filmes e séries</h2>
<p><img src="/images/posts/2015/08/itunes-and-netflix.jpg" alt="itunes-and-netflix"></p>
<p>Eu costumava alugar filmes e séries na locadora suéca (também conhecida como locadora do Paulo Coelho), mas comecei a fazer as contas: eu assisto uma média de 12 séries por ano, cada uma custa em média $25 por temporada no <a href="https://www.apple.com/au/itunes/"><strong>iTunes</strong></a>, ou seja, $25 por mês. Às vezes tem no <a href="https://www.netflix.com/"><strong>Netflix</strong></a> e acabo gastando menos. Já alugar um filme recém-lancado em HD no iTunes custa em média $4. Moral da história: decidi parar completamente de fazer pirataria e comprar / alugar tudo da <a href="https://www.youtube.com/watch?v=Vine0O9TNwI">forma correta</a> :)</p>
<h2>Conclusão</h2>
<p>Ok, eu sei que sou um pouco (muito?) paranóico, mas pelo menos nunca perdi nada </p>
<p>Me conte nos comentários abaixo como você faz seus backups e o que você achou desse post!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="macOS" /><category term="backups" />
    </entry>

    <entry>
      <title><![CDATA[8 motivos para programar em inglês]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2015/05/22/8-motivos-pra-programar-em-ingles?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2015-05-22T13:09:27.000Z</published>
      <updated>2022-11-26T03:55:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2015/05/22/8-motivos-pra-programar-em-ingles</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2015/05/22/8-motivos-pra-programar-em-ingles">
        <![CDATA[<div xml:lang="pt-BR"><p>Vejo muitos brasileiros escrevendo código em português. Na faculdade até pode fazer um pouco de sentido por ser mais didático, mas vou apresentar alguns motivos pelos quais isso deve ser evitado no mundo real:</p>
<ol>
<li>
<p>O motivo mais importante: inglês é o idioma internacional para código (e para documentações). Mais especificamente, o inglês americano é o padrão. Eu trabalho em uma empresa australiana e embora a Austrália siga a gramática britânica, o código que escrevemos segue a gramática americana (exemplo: "color" e não "colour").</p>
</li>
<li>
<p>Se você pretende um dia trabalhar fora do Brasil, potenciais empresas querendo te contratar vão querer ver seu código, mas não irão entender se estes estiverem em português. Então procure deixar seus repositórios no Github com código e documentação em inglês.</p>
</li>
<li>
<p>Os comandos e palavras-chave de linguagens em programação são em inglês, então mesmo que você queria escrever em português, vai acabar ficando inevitavelmente uma mistura.</p>
</li>
<li>
<p>Algumas linguagens e frameworks estão preparados para entender o inglês em termos de semântica. Exemplo: o Ruby on Rails sabe que a tabela no banco de dados para um determinado model deve ser sempre o nome do model no plural. Ou seja, ao ter um model <code>Person</code>, ele vai automaticamente procurar uma tabela <code>people</code>.</p>
</li>
<li>
<p>Contribuições para projetos <em>open-source</em> devem ser em inglês. Eu sinceramente não conheço um projeto <em>open-source</em> famoso que não esteja em inglês.</p>
</li>
<li>
<p>Muitas empresas no Brasil já escrevem códigos em inglês. Então se eventualmente você começar a trabalhar em um dessas empresas, você terá que se adaptar de qualquer forma.</p>
</li>
<li>
<p>Acentos, <code>ç</code> e caracteres especiais não funcionam bem em todas as linguagens (mesmo quando você usa UTF-8), fazendo que você tenha palavras escritas de forma incorreta se você as escrever em português. Exemplo: <code>producao</code> em vez de <code>produção</code>.</p>
</li>
<li>
<p>Você treina e melhora seu inglês, que é útil para outras coisas na vida, como filmes, seriados, games, etc! 🙂</p>
</li>
</ol>
<hr>
<p>Gravei também um vídeo (que faz parte do <a href="https://www.lucascaton.com/cursos/cplc/">meu curso</a>), comentando os items dessa lista:</p>
<p><a href="https://www.youtube.com/watch?v=5d5bkbWybqc"><img src="https://i.ytimg.com/vi_webp/5d5bkbWybqc/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="web-development" /><category term="carreira" /><category term="open-source" /><category term="software-development" /><category term="programacao" />
    </entry>

    <entry>
      <title><![CDATA[Por que escutar Podcasts?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2015/05/02/por-que-escutar-podcasts?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2015-05-02T03:06:22.000Z</published>
      <updated>2015-05-02T03:06:22.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2015/05/02/por-que-escutar-podcasts</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2015/05/02/por-que-escutar-podcasts">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2015/05/mic.jpg" alt="Microfone"></p>
<p>Ao escutar o episódio <a href="http://www.b9.com.br/57386/podcasts/braincast/braincast-146-o-impacto-da-internet-no-jornalismo/">“O impacto da internet no jornalismo” do
Braincast</a>,
refleti sobre algo que escreverei nesse artigo. Se você não escutou ou não
conhece o podcast, eu o recomendo fortemente.</p>
<p>Desde criança, sempre gostei muito de ir à bancas de jornais. Conforme você
cresce, o interesse muda um pouco: você substitui os gibis da Turma da Mônica
por revista de games e álbuns de Pokémon por revistas como Super interessante e
Galileu. Eu gastava boa parta de minha mesada com isso e era recompensador.</p>
<p><img src="/images/posts/2015/05/super-interessante.jpg" alt="super-interessante"></p>
<p>De repente — em casa — tínhamos internet. E eu acreditei que era só uma questão
de tempo até todo aquele excelente conteúdo das bancas chegar ao mundo online.
Mas o fato é que isso até hoje isso não aconteceu por completo. Apesar de
portais de notícias (incluindo BuzzFeed, Facebook, etc), onde a mídia digital
substituiu com competência a mídia física, acho que foi um pouco diferente com
conteúdos que não necessariamente tem urgência em serem publicados.</p>
<p>Lembro-me de capas da revista Super Interessante trazendo temas como Matrix (o
filme) e viagem no tempo por exemplo, onde a leitura era completa ao ponto de
satisfazer desde o leigo ao estudante das teorias da relatividade de Einstein.</p>
<p><aside>Aproveite para conhecer o <a href="https://www.lucascaton.com/podcast">meu podcast</a>!</aside></p>
<p>E sinceramente não vejo isso acontecer da mesma maneira online até hoje. Essas
revistas eram o meio-termo de quem queria algo mais rápido que um livro, porém
não tão superficial quanto um artigo, já que incluíam várias páginas com fotos,
infográficos, diagramas, etc.</p>
<p><img src="/images/posts/2015/05/macbook.jpg" alt="macbook"></p>
<p>O mundo online tem essa pressa toda — onde ninguém mais assiste um vídeo com
mais de 5 minutos ou lê um artigo com mais de uma página. Preferem no entanto,
ler dezenas de posts por minuto no Facebook. Não quero ser hipócrita — eu também
faço isso. Também não quero pagar de velho, dizendo que “no meu tempo, tudo era
melhor”. Mas eu realmente sinto falta de conteúdos mais profundos que os memes
do Instagram e mais confiáveis que a Wikipedia.</p>
<p>E aqui eu chego na parte interessante desse post: talvez os podcasts tenham
ocupado esse lugar. Eu atualmente escuto vários podcasts sobre os mais variados
temas, como programação, design, tecnologia, publicidade, empreendedorismo,
games, entre outros. Então se você — assim como eu — sente falta desse tipo de
conteúdo no mundo digital, talvez você possa encontrá-los em <strong>podcasts</strong> :-)</p>
<p><img src="/images/posts/2015/05/podcast.png" alt="podcast"></p>
<p>Para finalizar, segue uma lista dos Podcasts que eu escuto atualmente:</p>
<h4>Em português:</h4>
<ul>
<li>Braincast</li>
<li>Nerdcast</li>
<li>MacMagazine no Ar</li>
<li>Tecnocast</li>
<li>99 vidas</li>
<li>Grok Podcast</li>
<li>ZOFE — Zone of Front-Enders</li>
<li>Hack ‘n’ Cast</li>
<li>CBN — Max Gehringer</li>
<li>English Experts</li>
</ul>
<h4>Em inglês:</h4>
<ul>
<li>ATP — Accidental Tech Podcast</li>
<li>HI — Hello Internet</li>
<li>Security Now</li>
<li>Debug</li>
<li>Stuff You Should Know</li>
<li>The English We Speak (BBC)</li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="podcasts" />
    </entry>

    <entry>
      <title><![CDATA[Meu novo canal no YouTube]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2015/04/16/meu-novo-canal-no-youtube?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2015-04-16T03:06:39.000Z</published>
      <updated>2015-04-16T03:06:39.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2015/04/16/meu-novo-canal-no-youtube</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2015/04/16/meu-novo-canal-no-youtube">
        <![CDATA[<div xml:lang="pt-BR"><p>Cerca de 2 meses atrás, eu criei um novo canal no YouTube, com o propósito de
mostrar e contar sobre coisas relacionadas à viagens, tecnologia, vídeo games,
como é a vida na Austrália, inglês, entre outros assuntos.</p>
<p>O canal se chama <strong>"Reza a Lenda"</strong>:
<a href="https://www.youtube.com/RezaALenda?sub_confirmation=1">youtube.com/RezaALenda</a></p>
<p>Já tem
<a href="https://www.youtube.com/channel/UCtfeqX1atfOfi3dD9segYCg/videos">vários vídeos publicados</a>,
confere lá e me conta depois se gostou :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="youtube" /><category term="rezaalenda" /><category term="australia" />
    </entry>

    <entry>
      <title><![CDATA[You should be respectful]]></title>
      <summary><![CDATA[My thoughts on an article from BBC about Brazil]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2015/02/04/you-should-be-respectful?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2015-02-03T20:00:00.000Z</published>
      <updated>2021-07-01T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2015/02/04/you-should-be-respectful</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2015/02/04/you-should-be-respectful">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2015/02/you-should-be-respectful.jpg" alt="image_description"></p>
<p>My manager has shared an article with me called
<a href="http://www.bbc.com/news/magazine-31018302">"Getting lost in translation in Brazil"</a> from BBC News.</p>
<p>This was what I reply to him and I though it'd be nice to make it public:</p>
<blockquote>
<p>That's a very interesting article, thanks for sharing. I agree with most of the points, although
Brazil doesn't have as many immigrants as Australia (or other countries) so it's rare to see
people speaking other languages than Portuguese.</p>
<p>If you are living on a country where you weren't born, you should be respectful.
With the language, the culture, the people, everything actually.</p>
<p>My personal experience has been great: Australians haveare always nice to me. I try my best to do
the same. Living in another country has been one of the most amazing experiences I've had in my
life. Sometimes it's hard, but it's definitely rewarding.</p>
</blockquote>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" /><category term="brazil" />
    </entry>

    <entry>
      <title><![CDATA[Nem tudo são flores quando você mora fora do Brasil]]></title>
      <summary><![CDATA[Quando você muda de país, existem muitas coisas diferentes. E isso pode ser um pouco assustador.]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/12/04/nem-tudo-sao-flores-quando-voce-mora-fora-do-brasil?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-12-03T21:00:00.000Z</published>
      <updated>2021-03-15T12:52:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/12/04/nem-tudo-sao-flores-quando-voce-mora-fora-do-brasil</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/12/04/nem-tudo-sao-flores-quando-voce-mora-fora-do-brasil">
        <![CDATA[<div xml:lang="pt-BR"><p><figure><img src="https://www.lucascaton.com/images/posts/2014/12/melbourne.jpg" alt="Cidade de Melbourne" width="1280" height="720" /><figcaption>Foto: Lucas Caton — Melbourne, Australia — 2014</figcaption></figure></p>
<p>Se você pensa que morar fora do Brasil é uma experiência fantástica através da
qual você vai descobrir lugares lindos, conhecer pessoas diferentes, ficar
imerso em culturas diferentes, ter a oportunidade de aprender um idioma novo,
pagar menos por produtos e ganhar salários mais altos... você está certo!
De fato vai se deparar com tudo isso! 🙂</p>
<p>No entanto, eu vou te contar um pouco sobre o que não é tão legal. Quando você
muda de país, você pode não estar preparado para encontrar tantas coisas
diferentes. E isso pode ser um pouco assustador e chocante.
No começo, é bastante normal que você mal saiba pedir coisas básicas em um
supermercado. Você mal vai saber escolher um prato ou pedir a conta em um
restaurante.</p>
<p>O idioma pode ser o maior problema. Você vai se tocar que nunca se preocupou em
aprender várias palavras no idioma do país, como utensílios domésticos por
exemplo. Isso geralmente não é o tipo de coisa que você aprende em um curso de
inglês, ao menos nos que eu frequentei.</p>
<p>Vai notar também que nem todas as regras gramaticais que fizeram questão que
você aprendesse no curso de inglês são respeitadas. Você se sente uma criança
de 3 anos, sabendo o que quer, mas nem sempre sabendo se expressar corretamente.
E não é só em relação ao idioma, você estará longe de todos que conhecia e
muitas vezes você deve se comportar diferente do que está acostumado.</p>
<p>Eu e minha esposa tivemos sorte de ter tipo meio que uma experiência
preparatória: saímos do interior de São Paulo e moramos na capital por 3 anos
antes de sair do país.
Foi útil no sentido de saber como seria morar longe da família e amigos.
Claro que lá foi diferente: é muito mais fácil fazer amigos novos,
se comunicar, pouco tempo de viagem até nossa cidade natal, etc.
Mas não deixou de ser uma preparação antes de vir morar fora.</p>
<p>Apesar de todas as vantagens que citei no começo, somados ao respeito que as
pessoas têm por saberem que você é de fora... você começa uma vida nova
totalmente fora da sua zona de conforto e isso pode ser bastante desafiador.
Além disso, mesmo com a internet facilitando as coisas, nem sempre seus os
amigos do Brasil estão disponíveis, a vida lá continua também e todo mundo tem
problemas. Então ou você se adapta ou vai passar por momentos difíceis.</p>
<p>Não quero ser negativo, mas às vezes é preciso de um "banho de água fria" para
não elevar tanto as expectativas e se desanimar quando chegar à um novo país!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" />
    </entry>

    <entry>
      <title><![CDATA[CampJS 2014 - the best geek event I ever attended]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2014/11/21/campjs-2014-the-best-nerd-event-i-ever-attended?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-11-20T15:11:04.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2014/11/21/campjs-2014-the-best-nerd-event-i-ever-attended</id>
      <content type="html" xml:base="https://www.lucascaton.com/2014/11/21/campjs-2014-the-best-nerd-event-i-ever-attended">
        <![CDATA[<div xml:lang="en"><p>A few days ago I was in CampJS, the best geek event I ever attended.</p>
<p><img src="/images/posts/2014/11/campjs.jpg" alt="campjs"></p>
<p>This is the official website (which is pretty cool by the way): <a href="https://campjs.com/">https://campjs.com/</a>.</p>
<p>Why it was the best in my opinion:</p>
<ul>
<li>It happened at an amazing place - close to the nature and changing the usual environment is renewable. I'd definitely recommend it!</li>
<li>I had the chance to talk to a lot of other Javascript developers</li>
<li>Awesome talks and workshops</li>
<li>Good food and beers</li>
<li>A live podcast was recorded in there</li>
</ul>
<p>A friend of mine (<a href="https://x.com/erikEcoologic">@erikEcoologic</a>) has written an <a href="https://netengine.com.au/blofg/campjs_2014/">awesome blog post</a> about the event, so check it out! ;)</p>
<p>A special thanks to <a href="https://x.com/brucestronge">@brucestronge</a> and to <a href="https://netengine.com.au/">NetEngine</a> for the tickets!</p>
<h1>Video &#x26; photos</h1>
<p><a href="https://www.youtube.com/watch?v=xVFY5VzJavQ"><img src="https://i.ytimg.com/vi_webp/xVFY5VzJavQ/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><img src="/images/posts/2014/11/IMG_0.jpg" alt="IMG_0"></p>
<p><img src="/images/posts/2014/11/IMG_1067.jpg" alt="IMG_1067"></p>
<p><img src="/images/posts/2014/11/IMG_1099.jpg" alt="IMG_1099"></p>
<p><img src="/images/posts/2014/11/IMG_1199.jpg" alt="IMG_1199"></p>
<p><img src="/images/posts/2014/11/IMG_1202.jpg" alt="IMG_1202"></p>
<p><img src="/images/posts/2014/11/IMG_1206.jpg" alt="IMG_1206"></p>
<p><img src="/images/posts/2014/11/IMG_1267.jpg" alt="IMG_1267"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="eventos" /><category term="campjs" /><category term="events" /><category term="javascript" />
    </entry>

    <entry>
      <title><![CDATA[Depois de quase 28 anos de idade, formei minha opinião sobre religião]]></title>
      <summary><![CDATA[Repense como você leva sua vida, o que tem feito de bom e no que pode melhorar como cidadão do mundo]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/11/15/depois-de-quase-28-anos-de-idade-formei-minha-opiniao-sobre-religiao?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-11-14T21:00:00.000Z</published>
      <updated>2014-11-14T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/11/15/depois-de-quase-28-anos-de-idade-formei-minha-opiniao-sobre-religiao</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/11/15/depois-de-quase-28-anos-de-idade-formei-minha-opiniao-sobre-religiao">
        <![CDATA[<div xml:lang="pt-BR"><p><figure><img src="https://www.lucascaton.com/images/posts/2014/11/cathedral-of-st-stephen-brisbane.jpg" alt="Cathedral of St. Stephen, Brisbane, Austrália" width="1920" height="1080" /><figcaption>Cathedral of St. Stephen, Brisbane, Austrália</figcaption></figure></p>
<p>Uma vez escutei que não existem assuntos que não possam ser discutidos. O que existem são pessoas com as quais não se deve discutir. Apesar disso, resolvi tornar esse texto público, mesmo sendo sobre um assunto que potencialmente causa polêmica e que às vezes pode incomodar à alguns.</p>
<p>Eu fui criado e vivi boa parte da minha vida com minha avó, a qual é católica e bastante religiosa. Por isso, desde criança frequentei a igreja, reservando uma hora dos meus domingos para ir à missa com ela.</p>
<p>Lá pelos menos 14 anos, me desinteressei um pouco — acredito que isso deve acontecer com uma certa frequência na adolescência. Nunca fiquei muito tempo sem ir à uma missa, mas ao mesmo tempo nunca fui um fanático religioso, tampouco sei o tanto que gostaria sobre o assunto.</p>
<p>Não vou mentir, já houve uma época inclusive que eu não acreditava em mais nada, virei praticamente um ateu. Depois de muito tempo sem ter certeza do que acreditava, eu me dei conta de que eu acreditava sim em algo maior e voltei à ir à missa quase todos os domingos.</p>
<p>Domingo passado fui à missa com minha esposa. Fomos caminhando até a igreja e durante o caminho começamos a conversar sobre o que cada um acredita, o que “fé” significa pra cada um e outros assuntos relacionados. Durante a missa, comecei a refletir tudo isso e meio que finalmente me dei conta no que eu acredito. Tem coisas na vida que demoram um pouco para que tenhamos uma opinião formada e essa foi uma delas.</p>
<p>Você pode até discordar de algumas regras da igreja ou com o que os líderes religiosos falam, mas uma coisa é fato: as intenções e exemplos são na sua maioria coisas boas. Não vou entrar no assunto relacionado à dinheiro e charlatões, embora eles existam e não são poucos. O ponto é que os ensinamentos são sempre positivos, como perdão, pensar no próximo, etc.</p>
<p>Então finalmente formei minha opinião sobre o assunto: prefiro acreditar que existe sim um Deus. Além disso, ir à missa definitivamente me faz muito bem. Se eu estiver errado e não existir Deus nem nada, ainda assim está sendo válido, já que eu reservo esse momento na semana para ir repensar como ando levando minha vida, o que tenho feito de bom e no que eu posso melhorar como cidadão do mundo.</p>
<p>Conclusão: você não precisa usar a definição tradicional de Deus e de religião. Você pode simplesmente definir isso como uma forma de nos transformar em pessoas melhores.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="religiao" />
    </entry>

    <entry>
      <title><![CDATA[Como você contribui para um mundo melhor?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/10/17/como-voce-contribui-para-um-mundo-melhor?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-10-16T15:58:52.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/10/17/como-voce-contribui-para-um-mundo-melhor</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/10/17/como-voce-contribui-para-um-mundo-melhor">
        <![CDATA[<div xml:lang="pt-BR"><p>Somos consumidores assíduos de conteúdo (offline e especialmente online). E a idéia desse post é listar o que eu tenho feito em troca disso e também incentivar aos que não fazem a considerar a idéia! :)</p>
<ul>
<li>Eu mantenho esse blog desde 2009 (mais de 5 anos já!) com posts sobre Ruby, Rails, Linux, macOS, mobile, etc. Eventualmente publico sobre assuntos <em>off-topic</em> também;</li>
<li>Mantenho também um canal no <a href="https://www.youtube.com/lucascaton">YouTube</a> com screencasts técnicos;</li>
<li>No meu <a href="https://github.com/lucascaton/">Github</a> tem alguns projetos
open-source, alguns bastante genéricos, como meus <a href="https://github.com/lucascaton/dotfiles/">dotfiles</a> e meus <a href="https://github.com/lucascaton/vimfiles">vimfiles</a> ;</li>
<li>Criei e mantenho alguns grupos de discussão, como <a href="https://groups.google.com/forum/#!forum/vim-users-br">Vim Users
BR</a>, <a href="https://groups.google.com/forum/#!forum/swiftbr">Swift BR</a>, <a href="https://groups.google.com/forum/#!forum/neo4j-br">Neo4k BR</a> e <a href="https://groups.google.com/forum/#!forum/gxt-br">Gxt (ExtGwt) [BR]</a>;</li>
<li>Faço parte do staff que cuida dos eventos do <a href="https://www.gurusp.org/">GuruSP</a>. Quando eu morava em São Paulo eu ajudava mais, agora ajudo apenas remotamente.</li>
<li>Meu <a href="https://twitter.com/lucascaton">twitter</a> é basicamente para discussões relacionadas à tecnologia;</li>
<li>Para finalizar: faço sempre que possível <a href="https://www.lucascaton.com/tags/apresentacoes/">palestras e apresentações</a> (às vezes online) sobre ferramentas interessantes que tenho usado (infelizmente algumas foram feitas em empresas e não estão públicas).</li>
</ul>
<p>Não ganho nada fazendo essas coisas, mas é recompensador!</p>
<p>Mandem seus 2 cents nos comentários!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="site" /><category term="blog" /><category term="eventos" /><category term="palestras" /><category term="apresentacoes" /><category term="open-source" />
    </entry>

    <entry>
      <title><![CDATA[Onde encontrar emprego na Austrália]]></title>
      <summary><![CDATA[Compilei uma lista com os principais sites de emprego australianos]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/10/12/onde-encontrar-emprego-na-australia?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-10-12T09:00:00.000Z</published>
      <updated>2024-03-21T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/10/12/onde-encontrar-emprego-na-australia</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/10/12/onde-encontrar-emprego-na-australia">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2014/10/brisbane-australia.jpg" alt="Brisbane"></p>
<p>Como muitas pessoas me perguntam como conseguir emprego aqui na Austrália,
compilei uma lista com os principais sites de emprego australianos:</p>
<ul>
<li><a href="https://www.linkedin.com/">https://www.linkedin.com/</a></li>
<li><a href="https://www.seek.com.au/">https://www.seek.com.au/</a></li>
<li><a href="https://au.indeed.com/">https://au.indeed.com/</a></li>
<li><a href="https://au.jora.com/jobs">https://au.jora.com/jobs</a></li>
<li><a href="https://www.gumtree.com.au/jobs">https://www.gumtree.com.au/jobs</a></li>
<li><a href="https://www.workforceaustralia.gov.au/">https://www.workforceaustralia.gov.au/</a></li>
<li><a href="https://whoishiring.io/">https://whoishiring.io/</a></li>
<li><a href="https://www.applynow.com.au/">https://www.applynow.com.au/</a></li>
<li><a href="https://www.bluecollar.com.au/">https://www.bluecollar.com.au/</a></li>
<li><a href="https://careerhub.com.au/">https://careerhub.com.au/</a></li>
<li><a href="https://www.careerone.com.au/">https://www.careerone.com.au/</a></li>
<li><a href="https://www.workforceaustralia.gov.au/">https://www.workforceaustralia.gov.au/</a></li>
</ul>
<h2>Outros links relevantes:</h2>
<ul>
<li><a href="https://immi.homeaffairs.gov.au/">Site do departamento de imigração com todos os detalhes oficiais</a></li>
<li><a href="https://www.youtube.com/watch?v=mS0AkhGnSxY">[Vídeo] Como consegui meu visto australiano</a></li>
<li><a href="https://www.facebook.com/groups/comoirparaaaustralia">Grupo no Facebook “Brasileiros que querem ir para a Austrália”</a></li>
<li><a href="https://www.youtube.com/RezaaLenda?sub_confirmation=1">Canal "Reza a Lenda" (YouTube)</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" /><category term="emprego" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Ruby on Rails - Assets / Assets Pipeline]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/10/02/screencast-ruby-on-rails-assets-assets-pipeline?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-10-02T09:36:42.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/10/02/screencast-ruby-on-rails-assets-assets-pipeline</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/10/02/screencast-ruby-on-rails-assets-assets-pipeline">
        <![CDATA[<div xml:lang="pt-BR"><p>Mais um <em>screencast</em> gravado; esse sobre <code>assets</code> e o <code>Assets Pipeline</code> do <strong>Rails</strong>:</p>
<p><a href="https://www.youtube.com/watch?v=_08qNEt9QTQ"><img src="https://i.ytimg.com/vi_webp/_08qNEt9QTQ/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Links comentados no vídeo:</p>
<ul>
<li><a href="http://guides.rubyonrails.org/asset_pipeline.html">Rails Guides - Asset Pipeline</a></li>
<li><a href="http://www.akitaonrails.com/2012/07/01/asset-pipeline-para-iniciantes">Asset Pipeline para iniciantes</a> by <a href="https://twitter.com/akitaonrails">Fabio Akita</a></li>
</ul>
<hr>
<p>Assista <a href="https://www.youtube.com/playlist?list=PLz4HUyGp2Iyk4tANWisKz4JfVXF8JzivN">outros screencasts do meu canal</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="videos" />
    </entry>

    <entry>
      <title><![CDATA[How to use the command line on macOS]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2014/08/31/how-to-use-command-line-on-macos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-08-31T11:49:02.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2014/08/31/how-to-use-command-line-on-macos</id>
      <content type="html" xml:base="https://www.lucascaton.com/2014/08/31/how-to-use-command-line-on-macos">
        <![CDATA[<div xml:lang="en"><p>A friend of mine (who used to use Windows) has recently purchased a Mac and asked me how to use the command line on macOS. I thought I'd share here what I sent him:</p>
<ul>
<li>99% of commands are identical to Linux ones, which is great as there are so many great material about it available on the Internet.</li>
<li><code>Terminal.app</code> from macOS is ok but far from ideal. I (and 90% of software engineers I know) use <a href="https://iterm2.com/">iTerm2</a>. It's light (3mb), free, open-source, has a better UI than the native one and lots of useful features! Best terminal I've ever used.</li>
<li>There's an awesome <a href="https://www.git-tower.com/blog/command-line-cheat-sheet/">Command Line Cheat Sheet</a> made by the Git-tower team, check it out!</li>
<li>Finally, if you speak Portuguese, I've recorded a screencast explaining how to create scripts on both macOS and Linux (similar to BAT files on Windows):</li>
</ul>
<p><a href="https://www.youtube.com/watch?v=W84Ok6XGnow"><img src="https://i.ytimg.com/vi_webp/W84Ok6XGnow/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="mac" /><category term="macos" /><category term="linux" /><category term="shell" /><category term="bash" /><category term="command-line" /><category term="terminal" />
    </entry>

    <entry>
      <title><![CDATA[What's in my macOS menu bar?]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2014/08/10/what-do-i-have-on-my-macos-menu-bar?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-08-10T10:56:30.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2014/08/10/what-do-i-have-on-my-macos-menu-bar</id>
      <content type="html" xml:base="https://www.lucascaton.com/2014/08/10/what-do-i-have-on-my-macos-menu-bar">
        <![CDATA[<div xml:lang="en"><p><img src="/images/posts/2014/08/menubar.png" alt="menubar"></p>
<table>
<thead>
<tr>
<th align="left">Application</th>
<th align="left">Description</th>
<th align="left">Type</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><a href="https://apps.apple.com/au/app/caffeine/id411246225">Caffeine</a></td>
<td align="left">Prevent your Mac from automatically going to sleep, dimming the screen or starting screen savers</td>
<td align="left">Free</td>
</tr>
<tr>
<td align="left"><a href="https://apps.apple.com/app/colorsnapper/id418176775">ColorSnapper</a></td>
<td align="left">Color picker</td>
<td align="left">Paid</td>
</tr>
<tr>
<td align="left"><a href="https://apps.apple.com/au/app/1password-password-manager/id443987910">1Password</a></td>
<td align="left">Password manager</td>
<td align="left">Paid</td>
</tr>
<tr>
<td align="left"><a href="https://www.dropbox.com/">Dropbox</a></td>
<td align="left">File hosting service</td>
<td align="left">Free/Paid</td>
</tr>
<tr>
<td align="left"><a href="http://www.code42.com/crashplan/">CrashPlan</a></td>
<td align="left">Online data backup in real time</td>
<td align="left">Paid</td>
</tr>
<tr>
<td align="left"><a href="http://spectacleapp.com/">Spectacle</a></td>
<td align="left">Window control</td>
<td align="left">Free/Open source</td>
</tr>
<tr>
<td align="left"><a href="https://apps.apple.com/au/app/evernote/id406056744">Evernote</a></td>
<td align="left">Although Evernote is great, I don't use this icon at all. When I close it, it returns automatically 🤷‍♂️</td>
<td align="left">Free/Paid</td>
</tr>
<tr>
<td align="left"><a href="https://www.google.com/intl/en-AU/chrome/browser/">Chrome notifications</a></td>
<td align="left">I never really use it, but there's no way to remove it</td>
<td align="left">Free</td>
</tr>
<tr>
<td align="left"><a href="http://smilesoftware.com/TextExpander/index.html">Text Expander</a></td>
<td align="left">Custom keyboard shortcuts into frequently-used texts</td>
<td align="left">Paid</td>
</tr>
<tr>
<td align="left"><a href="http://www.apple.com/airplay/">AirPlay</a></td>
<td align="left">Play content on your TV via Apple TV</td>
<td align="left">Free</td>
</tr>
<tr>
<td align="left"><a href="https://www.apple.com/au/support/timemachine/">Time Machine</a></td>
<td align="left">Built-in backup feature of macOS that works with an external HD or Time Capsule</td>
<td align="left">Free</td>
</tr>
</tbody>
</table>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="macOS" />
    </entry>

    <entry>
      <title><![CDATA[Um conselho para estudantes de computação]]></title>
      <summary><![CDATA[Na época de faculdade eu fazia estas mesmas perguntas]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/08/03/um-conselho-para-estudantes-de-computacao?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-08-02T20:43:44.000Z</published>
      <updated>2018-05-16T21:54:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/08/03/um-conselho-para-estudantes-de-computacao</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/08/03/um-conselho-para-estudantes-de-computacao">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2014/08/Faculdade.jpg" alt="Faculdade"></p>
<p>Recentemente, uma pessoa me perguntou no Facebook:</p>
<blockquote>
<p>Terminei meu 1º semestre de Ciência da Computação e por enquanto, tudo parece tranquilo.
Mas não deixo de me preocupar quando a coisa ficar realmente "interessante".</p>
<p>Fico pensando naqueles códigos de tamanho imenso, na lógica maciça empregada nele.
Será que não enche o saco? Resolver bugs, procurando linha por linha onde está o erro? Valeu Lucas!</p>
</blockquote>
<p>Achei que valia a pena transformar minha resposta em um post:</p>
<hr>
<p>Olá! Interessante sua pergunta. Me lembro que na época de faculdade eu fazia estas mesmas perguntas :)</p>
<p>Apesar de projetos / códigos crescerem, eu diria para você não se preocupar muito com isso agora.
Existem ferramentas que te ajudarão a organizar tudo isso. Exemplos:
<a href="https://www.lucascaton.com/2011/06/01/slides-bio-labs-1-por-que-testar-e-importante-e-algumas-boas-praticas">testes automatizados</a>,
<a href="http://git-scm.com/">Git</a>,
<a href="http://www.akitaonrails.com/2014/07/31/small-bites-ides-e-editores-como-escolher">bons</a>
<a href="https://www.lucascaton.com/2017/12/30/qual-a-diferenca-entre-terminal-ide-e-editor-de-textos">editores de texto (ou IDEs)</a>,
etc.</p>
<p>Se você quiser saber como será sua profissão futuramente, uma boa maneira é olhar os <em>pull requests</em>
de projetos <em>open-source</em> e ver o que está sendo discutido lá.
Aproveite e veja os códigos também, você vai ver que mesmo em um projeto grande,
não existe bicho de 7 cabeças (ok, algumas raras vezes existe).
A página de
<a href="https://github.com/rails/rails/pulls"><em>pull requests</em> do <strong>Rails</strong></a>, por exemplo,
é um bom lugar para ver isso:</p>
<p>Eu sou completamente apaixonado por essa área e não consigo me ver fazendo outra coisa.
O bacana é que você pode trabalhar com muitas coisas diferentes, como desenvolvimento web (back-end ou front-end),
desenvolvimento de jogos, desenvolvimento <em>mobile</em> (iOS/Android), robótica, IA, BI, entre outros - a lista é grande.
É definitivamente uma área interessante para se trabalhar! :)</p>
<p>Claro que nem tudo são flores. Tem dia que enche o saco, tem dia que nada funciona e isso pode ser um pouco irritante.
Mas nada que uma noite bem dormida e um bom café para renovar e partir para o código novamente.</p>
<p>Minha dica final é: siga pessoas da área. Mas não se limite somente à blogs,
veja também o que bons programadores (brasileiros e gringos) estão falando nas redes sociais,
leia bons livros, participe de eventos da comunidade
(exemplo: <a href="https://www.gurusp.org/">GuruSP</a>),
seja curioso (pergunte sempre) e não se limite somente ao que a faculdade pode te oferecer.</p>
<p>Durante o período de faculdade você tem basicamente 3 fontes de aprendizado:
sozinho (autodidata), através de colegas e através das aulas (professores).
Todas são importantes, mas <strong>nunca</strong> siga seu caminho utilizando apenas as aulas.
Ler bons livros, criar uma boa base de conhecimento na área e fazer boas amizades
durante esse período é essencial.
Além disso, colegas da faculdade são potenciais futuros colegas de emprego
(podem te ajudar a conseguir um) ou ainda futuros sócios! :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="carreira" /><category term="faculdade" /><category term="computacao" /><category term="estudos" />
    </entry>

    <entry>
      <title><![CDATA[Como é o processo de imigração para a Austrália]]></title>
      <summary><![CDATA[Dicas para conseguir um emprego e o visto australiano]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/07/21/como-e-o-processo-de-imigracao-para-a-australia?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-07-21T06:07:44.000Z</published>
      <updated>2023-08-19T05:29:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/07/21/como-e-o-processo-de-imigracao-para-a-australia</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/07/21/como-e-o-processo-de-imigracao-para-a-australia">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2014/07/sydney.jpg" alt="Cidade de Sydney"></p>
<p><aside><strong>Disclaimer:</strong> o que você lerá abaixo é relativo à minha experiência. Eu cheguei na Austrália em agosto de 2013 e o departamento de imigração pode ter mudado algumas coisas, então recomendo você sempre consultar o <a href="https://immi.homeaffairs.gov.au/">site oficial</a>.</aside></p>
<h2>Versão em vídeo:</h2>
<p><a href="https://www.youtube.com/watch?v=mS0AkhGnSxY"><img src="https://i.ytimg.com/vi_webp/mS0AkhGnSxY/maxresdefault.webp" alt="YouTube video" /></a>
Nunca imaginei que esse vídeo chegaria a mais de 78.000 visualizações! 🙂</p>
<hr>
<h2>Por que estou escrevendo esse post?</h2>
<p>Vários amigos tem me enviado dúvidas, então eu compilei as respostas em um único lugar,
para ajudar outras pessoas que também tenham interesse.</p>
<h2>Grupo no Facebook para saber mais</h2>
<p>Eu criei um <a href="https://www.facebook.com/groups/comoirparaaaustralia/">grupo no Facebook</a>
(já somos mais de 21 mil membros, dado atualizado em 2023)
para que discussões sejam acessíveis a todos.</p>
<p>Já existe bastante conteúdo lá, vale a pena dar uma olhada:
<a href="https://www.facebook.com/groups/comoirparaaaustralia/">“Brasileiros que querem ir para a Austrália”</a>,
principalmente no <a href="https://www.facebook.com/groups/comoirparaaaustralia/permalink/566400210197941/">post fixo</a>.</p>
<h2>Por que Austrália?</h2>
<p>Quando conheci minha esposa, em 2010, descobrimos uma coisa em comum:
uma vontade enorme de morar fora do Brasil, conhecer outras culturas, aprender outro idioma,
vivenciar diferentes costumes e conhecer pessoas diferentes.
Já no primeiro dia descobri que ela iria fazer um intercâmbio para os EUA.</p>
<p>Alguns anos mais tarde, alguns amigos estavam mudando pra fora do país e
<a href="https://www.lucascaton.com/2013/08/13/australia-uma-nova-vida">me motivaram</a>
a pesquisar mais sobre como tornar isso possível.
No começo eu não tinha exatamente uma preferência, então comecei a fazer entrevistas
em vários países: Alemanha, Canadá, Inglaterra, Austrália, entre outros.
Eu estava em busca de um país onde a lingua nativa fosse o inglês,
mas isso não era necessariamente um fator limitante caso surgisse uma oportunidade interessante.</p>
<p>O que aconteceu foi que eu participei de um longo processo seletivo em uma
empresa australiana que durou mais de 2 meses. Durante esse período eu
pesquisava muito sobre o país e me identificava muito. Decidi então que era pra
cá que eu queria vir e meu foco se resumiu em uma palavra: “Austrália”.
Infelizmente a empresa não me ofereceu um emprego. Isso aconteceu várias vezes
(não somente na Austrália) e às vezes é bastante frustrante.</p>
<p>O <a href="https://www.linkedin.com/">LinkedIn</a> foi fundamental nessa fase: através dele
consegui várias entrevistas. Algumas poucas deram certo mas para trabalhar com
algo que não era exatamente o que eu queria. Desisti. E comecei de novo. E
desisti novamente. Esse ciclo se repetiu algumas vezes. Pensei em aceitar
qualquer coisa. Pensei em vir como estudante e ver no que dava depois que
chegasse aqui. Mas o ideal seria mesmo conseguir um emprego antes de vir.</p>
<p>Persisti então até que — pouco mais de um ano depois — deu certo! Serei
eternamente grato pela ajuda que recebi do <a href="https://twitter.com/rbernardelli">Ricardo
Bernardeli</a>, com o qual eu trabalho hoje. E a
lição que tirei disso tudo é que não existe segredo: basta estudar bastante o
idioma do país, se preparar bastante para executar o trabalho que será
necessário e ter persistência, que é uma das coisas mais importantes. Lembre-se:
mesmo que você esteja fazendo várias entrevistas e todas estejam dando errado,
você só precisa que uma dê certo, apenas uma já é o suficiente. Persista até
conseguir!</p>
<h3>Vantagens de vir para a Austrália</h3>
<ol>
<li><strong>Você não perde sua cidadania brasileira</strong> — ou seja, você pode ficar com as duas.
Na Alemanha por exemplo, você perde a brasileira.</li>
<li><strong>Dependentes podem trabalhar/estudar</strong> — Nos EUA ou Canadá por exemplo,
eles não poderiam fazer isso nos primeiros anos.</li>
<li><strong>Clima agradável</strong> — muito similar ao do Brasil.</li>
<li><strong>Salários bons</strong> — a Austrália tem um dos
<a href="http://www.visaustralia.com/en/blog/item/41-increasing-minimum-wages-in-australia.html">melhores salários do mundo</a>.
Além disso, existe uma lei que determina o valor mínimo por ano para o salário de imigrantes.</li>
<li><strong>Qualidade de vida</strong> — a Austrália tem o
<a href="http://en.wikipedia.org/wiki/List_of_countries_by_Human_Development_Index#Complete_list_of_countries">segundo melhor IDH do mundo</a>.</li>
</ol>
<h2>Como é o processo de migração para a Austrália</h2>
<p>Depois que você consegue um "sponsor", ou seja, uma empresa que te
“patrocinará”, você precisa fazer algumas coisas, que podem variar um pouco de
pessoa pra pessoa. No meu caso, resumidamente, foi:</p>
<ul>
<li><strong>Traduzir uma série de documentos</strong> — precisa ser realizado por um tradutor
autorizado pela imigração australiana e depois enviar estes documentos para a
imigração. Tudo é feito online;</li>
<li><strong>Tirar o passaporte</strong> — caso você não tenha ainda. Se estiver perto da data de
vencimento, você precisará tirar outro;</li>
<li><strong>Fazer alguns exames médicos</strong> — em clínicas autorizadas pela imigração;</li>
<li><strong>Se vacinar contra febre amarela</strong> — isso é importante, você pode ser deportado
assim que chegar aqui se não tiver o comprovante de que se vacinou;</li>
<li><strong>Pagar a taxa de imigração</strong> — essa taxa muda de tempo em tempo, no momento é
algo em torno de A$ 1000,00.</li>
<li><strong>Fazer o exame IELTS</strong> — para provar proficiência em inglês — a nota mínima que
você precisa tirar é **4.5 **em cada uma das modalidades do exame: <em>listening</em>,
<em>reading</em>, <em>writing</em> e <em>speaking</em>;</li>
<li><strong>Dinheiro</strong> — a passagem e a acomodação inicial não são muito baratas. Na
verdade, o custo de vida na Austrália é alto. Mas isso é compensado pelos
salários, considerados um dos melhores do mundo.</li>
<li><strong>Se livrar das coisas que você tem no Brasil</strong> — eu me casei 6 meses antes de
vir e tinha ganhado vários presentes de casamento, mas precisei de me livrar de
quase tudo, infelizmente;</li>
<li><strong>[Opcional] Solicitar a PID</strong> — ou seja, a “Permissão Internacional para
Dirigir”. Você solicita isso no Detran (o valor varia de estado para estado — em
SP custa cerca de R$ 230 e no RJ custa cerca de R$ 107) e poderá dirigir aqui
enquanto sua atual habilitação brasileira for válida.</li>
</ul>
<p>Esse processo todo demora entre 1 e 4 meses para ser aprovado (3 meses na média).</p>
<h2>Dependentes</h2>
<p>Eu vim com minha esposa e ela recebeu automaticamente o visto de dependente, mas
para isso precisa ser casado no civil e traduzir a certidão de casamento.
Certidão de união estável também conta, mas é ligeiramente mais burocratico. Ela
tem os mesmos direitos que eu tenho aqui: trabalhar em tempo integral e estudar
ou fazer faculdade. Se tivéssemos filhos, eles receberiam o visto de dependente
também.</p>
<p>Quando o visto é alterado (para o visto permanente ou cidadania — por exemplo),
os vistos dos dependentes são atualizados também.</p>
<p>A única coisa que não temos direito por enquanto é o <em>Medicare</em> (sistema de saúde
pública) e votar nas eleições. De resto, acho que podemos tudo.</p>
<h2>Como conseguir o visto permanente?</h2>
<p>O blog <a href="https://www.brazilaustralia.com/">Brazil Austrália</a>
tem publicado artigos sobre quais são as
<a href="http://www.brazilaustralia.com/carreiras-em-demanda-na-australia-2015/">carreiras em demanda</a>
e
<a href="http://www.brazilaustralia.com/como-reconhecer-sua-profissao-residencia-australia/">como reconhecer sua profissão para residência na Austrália</a>.
Isso significa que você pode conseguir diretamente um visto de residência,
ou seja, mesmo sem ter conseguido o visto de trabalho antes.</p>
<p>O blog também conta com vários outros artigos interessantes
<a href="https://www.brazilaustralia.com/os-salarios-na-australia-por-profissao/">sobre salários</a>,
<a href="https://www.brazilaustralia.com/o-melhor-pais-do-mundo/">sobre o país</a> e
<a href="https://www.brazilaustralia.com/os-paises-com-melhor-qualidade-de-vida-em-2013/">sobre a qualidade de vida daqui</a>.</p>
<h3>No meu caso...</h3>
<p>O visto que eu tenho é o 457 (<em>Work visa</em>) e ele tem validade de 4 anos,
podendo ser renovado por mais 4 até quando você ou a empresa quiserem.
Porém, depois de 2 anos, a empresa que te contratou pode solicitar para a imigração que
mudem o seu visto para o <strong>"visto permanente"</strong>. Isso te desvincula da empresa e
você poderá mudar de emprego se quiser. Ou ainda ficar desempregado sem ter que
voltar pro Brasil (antes disso você seria deportado depois de 90 dias sem estar
trabalhando). Se a empresa não quiser te ajudar nessa parte, você pode ainda
esperar completar 4 anos aqui e solicitar esse novo visto de qualquer forma.</p>
<h3>E a cidadania?</h3>
<p>Depois de 4 anos morando na Austrália (e desde que o último seja com o visto
permanente) você consegue a cidadania… nesse ponto você tem 100% dos mesmos
direitos que um australiano. Mais informações:
<a href="https://immi.homeaffairs.gov.au/citizenship/become-a-citizen/permanent-resident">https://immi.homeaffairs.gov.au/citizenship/become-a-citizen/permanent-resident</a>.</p>
<p>* * *</p>
<p>Basicamente é isso. Se tiverem alguma dúvida é só mandar!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" />
    </entry>

    <entry>
      <title><![CDATA[Coisas sobre Linux que me chamaram a atenção recentemente]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/07/18/coisas-sobre-linux-que-me-chamaram-a-atencao-recentemente?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-07-17T20:30:18.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/07/18/coisas-sobre-linux-que-me-chamaram-a-atencao-recentemente</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/07/18/coisas-sobre-linux-que-me-chamaram-a-atencao-recentemente">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2014/07/LinuxVersions.jpg" alt="LinuxVersions"></p>
<p>Você pode não saber (ou esquecer às vezes), mas o Linux está <strong>muito</strong> presente na sua vida. Mesmo que você não o use diretamente como sistema operacional principal, mais da metade dos sites que você acessa está rodando em plataforma Linux. Isso inclui empresas gigantes como Google, Facebook, Twitter, Soundcloud, Amazon, Spotify, etc - a lista é muito, mas muito longa.</p>
<p>A maioria dos filmes que você assiste <a href="http://jordanhall.co.uk/general-articles/avatar-film-rendered-with-enormous-ubuntu-server-farm-4701468/">utilizam Linux</a> para renderizar cenas extremamente complexas que às vezes levam semanas ou mesmo meses para serem renderizados.</p>
<p>O sistema móvel Android <a href="http://en.wikipedia.org/wiki/Android_(operating_system)">também é um Linux</a> também caso você não saiba. E o seu roteador e a sua SmartTV provavelmente rodam Linux também!</p>
<p>Embora atualmente meu computador principal rode macOS, eu estou em contato com vários servidores que rodam Linux os quais acesso frequentemente.</p>
<p>Além disso, utilizei Linux como S.O. principal de 2007 à 2011, através das distros Ubuntu e OpenSUSE (além de outras que utilizei por pouco tempo, como Slackware e Debian).</p>
<hr>
<p>Na última semana várias coisas me chamaram a atenção no mundo Linux e esse é o motivo desse post:</p>
<ol>
<li>
<p>O último episódio do podcast do <strong>Hack 'n' Cast</strong> (v0.3) foi uma introdução ao Linux e foi muito bom, vale a pena escutar: <a href="http://mindbending.org/pt/hack-n-cast-v03-introducao-ao-gnulinux">http://mindbending.org/pt/hack-n-cast-v03-introducao-ao-gnulinux</a>.</p>
</li>
<li>
<p>Um amigo que é programador disse que <strong>nunca</strong> (palavra forte!) usaria Linux porque nem criar um script similar ao batch do "Janelas" ele conseguia. Bom, pensando que isso pudesse ser útil para mais pessoas, gravei um screencast ensinando como criar scripts no Linux e no <del>OS X</del> macOS: <a href="http://youtu.be/W84Ok6XGnow">http://youtu.be/W84Ok6XGnow</a>.</p>
</li>
<li>
<p>Assisti à uma ótima palestra chamada "Linux Sucks": <a href="http://youtu.be/5pOxlazS3zs">http://youtu.be/5pOxlazS3zs</a>.</p>
</li>
<li>
<p>Lembrei e reli o excelente ponto de vista do <a href="https://twitter.com/PotHix">@Pothix</a> sobre porque ele deixou o macOS e voltou a usar Linux: <a href="https://pothix.com/mac-linux/">https://pothix.com/mac-linux/</a>.</p>
</li>
<li>
<p>Para finalizar (e descontraír), há um tempo atrás eu ganhei de um amigo que trabalha na <a href="https://www.redhat.com/">RedHat</a> um chapél vermelho (red hat, rá!), o qual foi parar na cabeca do Tux que eu tenho na minha estante, vide fotos abaixo. Ficou bem bacana! :)</p>
</li>
</ol>
<p><img src="/images/posts/2014/07/1.jpg" alt="1"></p>
<p><img src="/images/posts/2014/07/2.jpg" alt="2"></p>
<p>Bom, essa <a href="https://www.lucascaton.com/tags/linux">não é a primeira vez que eu escrevo sobre Linux</a> e também não será a última.</p>
<p>Linux é muito mais importante do que as pessoas pensam.
Pense 2 vezes antes de subestimar o sistema do pinguim! :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="linux" /><category term="ubuntu" /><category term="google" /><category term="shell" /><category term="open-source" /><category term="red-hat" />
    </entry>

    <entry>
      <title><![CDATA[Saudade]]></title>
      <summary><![CDATA[Saudade é provavelmente a expressão mais significativa e típica da alma brasileira]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/06/21/saudade?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-06-20T21:00:00.000Z</published>
      <updated>2014-06-20T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/06/21/saudade</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/06/21/saudade">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2014/06/saudade.jpg" alt="Mulher sentada olhando para o horizonte"></p>
<p>Não me lembro onde encontrei esse texto. Mas gostei muito! :-)</p>
<blockquote>
<p><strong>Saudade</strong> é provavelmente a expressão mais significativa e típica da alma brasileira, uma combinação de anseios e desejo, misturado com nostalgia e melancolia. Saudade é o desejo por algo ou alguém que está longe ou é inatingível. Os brasileiros têm saudades quando vivem no exterior e sentem falta do lar, quando estão separados de seus entes queridos, ou quando lembram dos bons e velhos tempos. Mas saudade não é apenas uma resposta emocional a uma situação ou memória. É um estado de espírito no qual os brasileiros procuram prosperar.</p>
</blockquote>
<h4>English version</h4>
<blockquote>
<p><strong>Saudade</strong> is probably the most significant and typical expression of the Brazilian soul, a combination of longing and desire, mixed with nostalgia and melancholy. Saudade is the desire for something or someone who is far away or is unattainable. Brazilians have saudades when they live abroad and get homesick, when they are separated from a loved one, or when they recall good old times. But saudade is not merely an emotional response to a situation or memory. It is a state of mind that Brazilians seek and thrive on.</p>
</blockquote>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="pensamentos" />
    </entry>

    <entry>
      <title><![CDATA[An awesome Wiki built with Ruby and Rails! ]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2014/04/05/an-awesome-wiki-built-with-ruby-and-rails?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-04-04T18:14:53.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2014/04/05/an-awesome-wiki-built-with-ruby-and-rails</id>
      <content type="html" xml:base="https://www.lucascaton.com/2014/04/05/an-awesome-wiki-built-with-ruby-and-rails">
        <![CDATA[<div xml:lang="en"><p>I've been worked on a small open-source project.
I'm talking about <a href="https://github.com/lucascaton/ruby_wiki">ruby_wiki</a>, a simple wiki built with Ruby on Rails.</p>
<p>If you're interested, feel free to fork and contribute to the project.</p>
<p><img src="/images/posts/2014/04/1.png" alt="1"></p>
<p><img src="/images/posts/2014/04/2.png" alt="2"></p>
<p><img src="/images/posts/2014/04/3.png" alt="3"></p>
<p><img src="/images/posts/2014/04/4.png" alt="4"></p>
<p><img src="/images/posts/2014/04/5.png" alt="5"></p>
<p><img src="/images/posts/2014/04/6.png" alt="6"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="web-development" /><category term="ruby" /><category term="rails" /><category term="wiki" /><category term="open-source" />
    </entry>

    <entry>
      <title><![CDATA[Have a Rails 2 app? You can run it on the newest Ruby!]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2014/02/28/have-a-rails-2-app-you-can-run-it-on-the-newest-ruby?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-02-28T00:36:17.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2014/02/28/have-a-rails-2-app-you-can-run-it-on-the-newest-ruby</id>
      <content type="html" xml:base="https://www.lucascaton.com/2014/02/28/have-a-rails-2-app-you-can-run-it-on-the-newest-ruby">
        <![CDATA[<div xml:lang="en"><p>Do you have a legacy app still running on Rails 2?</p>
<p>There are several reasons to migrate your application to a newer version of Rails: improving security, using a better syntax, taking advantage of new features, and ensuring compatibility with most current gems, which typically require Rails 3 or higher. However, this process can be challenging, especially for large projects. It's worth noting that many projects are still running on Rails 2 today (in 2014).</p>
<p>But there's one important thing you can (and should) do! I'm talking about using the newest Ruby version. Yes, I'm serious. When I wrote this post, the latest Ruby version was <a href="https://www.ruby-lang.org/en/news/2014/02/24/ruby-2-1-1-is-released/">2.1.1</a>, and it's not too difficult to get it working smoothly with Rails 2.</p>
<p>Obviously, it's better if you have good test coverage.</p>
<p>That said, let's break it down into a few steps:</p>
<h2>Replacements</h2>
<ul>
<li><code>Gemfile</code></li>
</ul>
<p>Rails 2 apps don't use Bundler by default. If you're not already using Bundler to manage your gems, you should <a href="http://bundler.io/v1.3/rails23.html">check this guide</a> to set it up.</p>
<pre><code class="language-ruby">## There's no way to know for sure if future Ruby versions will work,
## but so far the current one does:
ruby "2.1.1"
## The same for the `rake` gem:
rake "10.1.1"
## You might need the `iconv` gem:
gem "iconv"
</code></pre>
<ul>
<li><code>Rakefile</code></li>
</ul>
<pre><code class="language-ruby">## Replace:
## require "rake/rdoctask"
## with:
require "rake/task"
</code></pre>
<ul>
<li><code>config.ru</code></li>
</ul>
<pre><code class="language-ruby">## Replace:
## require "config/environment"
## with:
require File.dirname(__FILE__) + "/config/environment"
</code></pre>
<ul>
<li><code>FasterCSV</code> ➙ <code>CSV</code></li>
</ul>
<p>Replace all <code>FasterCSV</code> constants with <code>CSV</code>.
Also, include <code>require "csv"</code> to relevant files (or include the <code>require</code> to your <code>config/environment.rb</code> file).</p>
<h2>Inclusions</h2>
<ul>
<li><code>config/environment.rb</code></li>
</ul>
<pre><code class="language-ruby">## Include this before the `Rails::Initializer.run` line:
if RUBY_VERSION >= "2.0.0"
  module Gem
    def self.source_index
      sources
    end
    def self.cache
      sources
    end
    SourceIndex = Specification
    class SourceList
      # If you want vendor gems, this is where to start writing code.
      def search(*args); []; end
      def each(&#x26;block); end
      include Enumerable
    end
  end
end
</code></pre>
<ul>
<li><code>config/initializers/paperclip.rb</code></li>
</ul>
<pre><code class="language-ruby">## The patches below are needed when using an old version of PaperClip + Ruby 2.x
## https://github.com/thoughtbot/paperclip/issues/262
## https://github.com/thoughtbot/paperclip/commit/1bcfc14388d0651c5fc70ab9ca3511144c698903
module Paperclip
  class Tempfile &#x3C; ::Tempfile
    def make_tmpname(basename, n)
      extension = File.extname(basename)
      sprintf("%s,%d,%d%s", File.basename(basename, extension), $$, n.to_i, extension)
    end
  end
end
module IOStream
  def to_tempfile
    name = respond_to?(:original_filename) ? original_filename : (respond_to?(:path) ? path : "stream")
    tempfile = Tempfile.new(["stream", File.extname(name)])
    tempfile.binmode
    self.stream_to(tempfile)
  end
end
</code></pre>
<h2>New files</h2>
<ul>
<li><code>config/initializers/ruby2.rb</code></li>
</ul>
<pre><code class="language-ruby">## This is a very important monkey patch to make Rails 2.3.18 to work with Ruby 2+
## If you're thinking to remove it, really, don't, unless you know what you're doing.
if Rails::VERSION::MAJOR == 2 &#x26;&#x26; RUBY_VERSION >= "2.0.0"
  module ActiveRecord
    module Associations
      class AssociationProxy
        def send(method, *args)
          if proxy_respond_to?(method, true)
            super
          else
            load_target
            @target.send(method, *args)
          end
        end
      end
    end
  end
end
</code></pre>
<ul>
<li><code>config/initializers/rails_generators.rb</code></li>
</ul>
<p>It'll prevent Rails migration generator from stop working, otherwise you'll receive the following error message:</p>
<pre><code class="language-ruby">undefined local variable or method `vars' for # Rails::Generator::Commands::Create
</code></pre>
<p>(Thanks to <a href="https://disqus.com/by/disqus_J5madOMsmT/">Mr. S</a> and <a href="https://disqus.com/by/jnwheeler44/">jnwheeler44</a> for helping me to fix this one)</p>
<pre><code class="language-ruby">## This is a very important monkey patch to make Rails 2.3.18 to work with Ruby 2+
## If you're thinking to remove it, really, don't, unless you know what you're doing.
if Rails::VERSION::MAJOR == 2 &#x26;&#x26; RUBY_VERSION >= "2.0.0"
  require "rails_generator"
  require "rails_generator/scripts/generate"
  Rails::Generator::Commands::Create.class_eval do
    def template(relative_source, relative_destination, template_options = {})
      file(relative_source, relative_destination, template_options) do |file|
        # Evaluate any assignments in a temporary, throwaway binding
        vars = template_options[:assigns] || {}
        b = template_options[:binding] || binding
        # this no longer works, eval throws "undefined local variable or method `vars'"
        # vars.each { |k, v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b }
        vars.each { |k, v| b.local_variable_set(:"#{k}", v) }
        # Render the source file with the temporary binding
        ERB.new(file.read, nil, "-").result(b)
      end
    end
  end
end
</code></pre>
<h2>RSpec</h2>
<ul>
<li>Make sure you're using the last compatible version with <code>Rails 2.3.18</code>:</li>
</ul>
<pre><code class="language-ruby">gem "rspec", "1.3.2"
gem "rspec-rails", "1.3.4"
</code></pre>
<ul>
<li>
<p>Remove the file <code>script/spec</code></p>
</li>
<li>
<p>Remove the following lines from the <code>lib/tasks/rspec.rake</code> file:</p>
</li>
</ul>
<pre><code class="language-ruby">gem "test-unit", "1.2.3" if RUBY_VERSION.to_f >= 1.9
rspec_gem_dir = nil
Dir["#{Rails.root}/vendor/gems/*"].each do |subdir|
  rspec_gem_dir = subdir if subdir.gsub("#{Rails.root}/vendor/gems/","") =~ /^(\w+-)?rspec-(\d+)/ &#x26;&#x26; File.exist?("#{subdir}/lib/spec/rake/spectask.rb")
end
rspec_plugin_dir = File.expand_path(File.dirname(__FILE__) + "/../../vendor/plugins/rspec")
if rspec_gem_dir &#x26;&#x26; (test ?d, rspec_plugin_dir)
  raise "\n#{'*'*50}\nYou have rspec installed in both vendor/gems and vendor/plugins\nPlease pick one and dispose of the other.\n#{'*'*50}\n\n"
end
if rspec_gem_dir
  $LOAD_PATH.unshift("#{rspec_gem_dir}/lib")
elsif File.exist?(rspec_plugin_dir)
  $LOAD_PATH.unshift("#{rspec_plugin_dir}/lib")
end
</code></pre>
<h2>Ruby syntax</h2>
<ul>
<li>Ruby syntax has changed a bit, especially from <code>1.8.x</code> to <code>1.9.x</code>.</li>
</ul>
<pre><code class="language-ruby"># Replace:
when "foo": bar
# with:
when "foo" then bar
</code></pre>
<hr>
<p>The behaviour for <code>protected</code> methods in new Ruby versions is a little bit different.
See more in <a href="https://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html">this post</a>.</p>
<pre><code class="language-ruby"># In some cases, you might need to replace:
respond_to?(:foobar)
# with:
respond_to?(:foobar, true)
</code></pre>
<hr>
<pre><code class="language-ruby"># Replace:
order: [:day, :month, :year]
# with:
order:
  - :year
  - :month
  - :day
</code></pre>
<h2>Ruby changes</h2>
<ul>
<li>The default encoding for <code>Ruby 2.0</code> (or higher) is <code>UTF-8</code></li>
</ul>
<p>Remove all the code similar to:</p>
<pre><code class="language-ruby"># encoding: utf-8
</code></pre>
<p>Or:</p>
<pre><code class="language-ruby">$KCODE = "UTF-8"
</code></pre>
<h2>Update on July 27th, 2014</h2>
<p>Check out the insightful comments below by Gabriel Sobrinho, Kyle Ries, and Greg. They offer valuable insights!</p>
<h2>Conclusion</h2>
<p>Different project might have different issues, but I hope this little guide helps you to use new Ruby versions on your legacy Rails applications!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" />
    </entry>

    <entry>
      <title><![CDATA[Meu comentário no artigo "E se você pudesse mudar de país?"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2014/01/18/meu-comentario-no-artigo-e-se-voce-pudesse-mudar-de-pais?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2014-01-17T21:00:00.000Z</published>
      <updated>2014-01-17T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2014/01/18/meu-comentario-no-artigo-e-se-voce-pudesse-mudar-de-pais</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2014/01/18/meu-comentario-no-artigo-e-se-voce-pudesse-mudar-de-pais">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2014/01/photo-of-boats-parked-on-river-2031706.jpg" alt="Barcos estacionados em um rio"></p>
<p>Acabei de escrever um comentário em um post chamado
<a href="https://chickenorpasta.com.br/2014/e-se-voce-pudesse-mudar-de-pais">"E se você pudesse mudar de país?"</a>
(o qual recomendo muito a leitura):</p>
<blockquote>
<p>Sensacional seu artigo, Paula!</p>
<p>Estou morando na Austrália com minha esposa há 5 meses e estamos adorando. É realmente uma
experiência incrível, a qual recomendo a todos, mesmo que seja apenas por alguns poucos anos.</p>
<p>Idioma, leis, costumes e pessoas diferentes podem assustar um pouco até os menos conservadores,
mas raramente se torna um problema real. E algumas lendas como “gringos não são receptivos e
amigáveis como os brasileiros” são rapidamente desmentidas.</p>
<p>Claro que ficar longe da família e dos amigos — como você disse — não é fácil, mas nada que não
seja resolvido fazendo (ou recebendo) uma visita de vez em quando.</p>
<p>Sucesso e felicidades para vocês!</p>
</blockquote>
<p>E a resposta dela:</p>
<blockquote>
<p>Obrigada, Lucas! Realmente ouvi muitas histórias sobre a hostilidade holandesa, vim pra cá
morrendo de medo… e todos que encontrei foram muito acolhedores e simpáticos, inclusive dispostos
a ajudar quando necessário. Boa sorte pra você e sua família na Austrália, deve ser incrível morar
aí! *-*</p>
</blockquote>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" />
    </entry>

    <entry>
      <title><![CDATA[Por que eu voltei a usar iOS/iPhone]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/12/20/por-que-eu-voltei-a-usar-ios-iphone?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-12-20T13:01:35.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/12/20/por-que-eu-voltei-a-usar-ios-iphone</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/12/20/por-que-eu-voltei-a-usar-ios-iphone">
        <![CDATA[<div xml:lang="pt-BR"><p>Em agosto desse ano, eu escrevi sobre <a href="https://www.lucascaton.com/2013/09/28/ha-um-mes-eu-troquei-o-ios-pelo-android">como estava sendo minha experiência com o Android</a>.
Quatro meses depois, voltei a usar iOS. Vamos aos fatos: eu pretendia ficar mais um tempo com ele, mas o derrubei e a tela parou de funcionar completamente.
Como eu já estava bastante ansioso pra voltar a usar o iOS/iPhone, aproveitei a oportunidade e comprei um iPhone 5s.</p>
<p><img src="/images/posts/2013/12/hero_start__posterframe.jpg" alt="hero_start__posterframe"></p>
<h2>Mas o Android estava tão ruim assim?</h2>
<p>Não. Antes de mais nada, vou ser sincero:</p>
<p><strong>Android é sim um excelente sistema!</strong></p>
<p><img src="/images/posts/2013/09/android.png" alt="android-300x300"></p>
<p>Conforme <a href="https://www.lucascaton.com/2013/09/28/ha-um-mes-eu-troquei-o-ios-pelo-android">escrevi nesse post</a>, eu tinha um Samsung S4 e o Android estava me atendendo perfeitamente bem no começo, mas depois de um tempo comecei a ter alguns problemas com a ROM original (da Samsung): lentidão, o fato de eu não poder atualizar, etc. Essa imagem que mostra bem claramente o problema das atualizações do Android:</p>
<p><img src="/images/posts/2013/12/03-ios-android.png" alt="03-ios-android"></p>
<p>Antes que o <a href="https://twitter.com/jonas_alves">Jonas</a> me xingue, algo que deve ficar claro: não devemos resumir a experiência de usar Android somente se baseando na experiência de usar um Samsung. Mas o fato é que o Samsung S4 é um dos aparelhos mais utilizados atualmente, por isso achei que eu não fosse ter esse tipo de problema.</p>
<p>Resolvi então colocar uma versão pura do Android (vale ressaltar que essa ROM não era oficial). Ficou bom no começo, mas depois de um tempo, ficou pior: as apps davam crash toda hora e o sistema como um todo ficou lento. Tentei voltar para a ROM da Samsung (ou até alguma outra - exemplo: Cyanogenmod), mas era tanta gambiarra que desisti.</p>
<h2>O que eu ganhei voltando para o iOS/iPhone?</h2>
<p><img src="/images/posts/2013/12/ios.jpg" alt="ios"></p>
<ul>
<li><strong>Podcasts</strong> - uma app decente para o que mais faço com o meu celular: escutar podcasts. Não encontrei nenhuma app (free ou pago) que me atendesse 100% no Android. E isso o <a href="https://itunes.apple.com/us/app/podcasts/id525463029?ls=1&#x26;mt=8"><strong>Podcasts</strong></a> da Apple faz muitíssimo bem. A propósito, aproveite para conhecer o <a href="https://www.lucascaton.com/podcast"><strong>meu podcast</strong></a>;</li>
<li><strong>iOS 7</strong> - o novo sistema está muito estável e muito bonito. O que mais eu posso querer? 🙌</li>
<li><strong>Gerenciamento de arquivos</strong> - Não tenho mais que me preocupar em que diretório os arquivos estão (e não saber se estou desperdiçando espaço);</li>
<li><strong>Find my friends</strong> - as opções do Android não eram muito boas (Testei o "Life360" e alguns outros);</li>
<li><strong>Calandários perfeitamente sincronizados</strong> - Várias items do meu calendário estavam no iCloud. Agora calendários do iCloud, do Google e do Facebook estão perfeitamente sincronizados;</li>
<li><strong>Sensação de controle do que está realmente acontecendo no aparelho</strong> - Em vários momentos você tem a noção de perder esse controle no Android;</li>
<li><strong>Fluidez</strong> - Somando o processador A7 (64 bits 🤩) e a boa integração entre hardware e software, a fluidez / estabilidade do sistema como um todo ficam fantásticas;</li>
<li><strong>Camera com suporte à 120fps (slow motion)</strong> - simplesmente sensacional;</li>
<li><strong>Earpods</strong> - os novos fones são ótimos;</li>
<li><strong>Touch ID</strong> - Sem muito o que falar, é sensacional também.</li>
</ul>
<p><img src="/images/posts/2013/12/touchid_hero.png" alt="touchid_hero-300x135"></p>
<p>Uma coisa interessante e que antes era exclusivo do Android é o relatório de consumo da banda 4G separado por app, o qual agora está disponível também no iOS 7.</p>
<p><img src="/images/posts/2013/12/4g_usage.png" alt="4g_usage-576x1024"></p>
<h2>O que eu perdi deixando o Android</h2>
<ul>
<li><strong>Notificações</strong> - O LED, os mini-ícones perto do relógio e a sincronia perfeita com as apps - tudo isso somados fazem as notificações do Android serem melhores que as do iOS;</li>
<li><strong>Relatório de consumo da bateria</strong> - Isso simplesmenete não existe no iOS;</li>
<li><strong>Instalar apps via web</strong> - sinto falta disso, funciona muito bem no Android;</li>
<li><strong>Teclado swipe</strong> - fiquei mal acostumado com esse teclado também. Mais um ponto pro Android.</li>
</ul>
<h2>Conclusão</h2>
<p><img src="/images/posts/2013/12/ios_hero.png" alt="ios_hero-300x253"></p>
<p>Das principais opções atuais, iOS/iPhone é o que me atende melhor.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="apple" /><category term="iphone" /><category term="iOS" /><category term="android" />
    </entry>

    <entry>
      <title><![CDATA[RHOK Brisbane 2013]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/12/08/rhok-brisbane-2013?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-12-07T14:44:22.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/12/08/rhok-brisbane-2013</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/12/08/rhok-brisbane-2013">
        <![CDATA[<div xml:lang="pt-BR"><p>"Random hacks of kindness" - ou simplesmente "RHOK" - que pode ser traduzido como "Hacks aleatórios de bondade" é um evento (aka. "hackathon") sem fins lucrativos que acontece no mundo inteiro, onde profissionais de tecnologia ajudam a criar projetos e solucionar problemas de organizações que trabalham para um mundo melhor.</p>
<p>Quem participa não recebe nada por isso, é uma contribuição voluntária, como forma de boa ação.</p>
<p>Esse ano estou participando do evento de Brisbane (Austrália) e estamos ajudando a <a href="http://www.queenslandkids.org.au/">QueenslandKids</a>, uma organização que ajuda crianças carentes e especiais.</p>
<p>Para saber mais sobre o evento: <a href="http://rhokbrisbane.org/">rhokbrisbane.org</a>.</p>
<p>Fotos:</p>
<p><img src="/images/posts/2013/12/2013-12-07-09.41.32.jpg" alt="2013-12-07-09.41.32"></p>
<p><img src="/images/posts/2013/12/2013-12-07-09.30.00.jpg" alt="2013-12-07-09.30.00"></p>
<p><img src="/images/posts/2013/12/2013-12-07-09.35.53.jpg" alt="2013-12-07-09.35.53"></p>
<p><img src="/images/posts/2013/12/2013-12-07-09.21.13.jpg" alt="2013-12-07-09.21.13"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="eventos" /><category term="hackathon" /><category term="rhok" />
    </entry>

    <entry>
      <title><![CDATA[Movember (Novembro Azul)]]></title>
      <summary><![CDATA[Campanha do bigodão]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/11/10/movember-novembro-azul?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-11-09T21:00:00.000Z</published>
      <updated>2013-11-09T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/11/10/movember-novembro-azul</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/11/10/movember-novembro-azul">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2013/11/movember.png" alt="image_description"></p>
<p>"Movember" — conhecido como "Novembro azul" no Brasil — é uma campanha realizada todo mês de
novembro para a conscientização sobre a importância da prevenção e do diagnóstico precoce do câncer
de próstata e outras doenças masculinas.</p>
<p>Para participar da campanha, você pode fazer duas coisas:</p>
<ol>
<li>Deixar o bigode crescer;</li>
<li>Fazer doações para uma instituição.</li>
</ol>
<p>Aqui na Austrália é uma tradição forte! Muita gente está usando um bigodão! :)</p>
<p>E esse é o time que eu estou participando (pessoal da empresa):
<a href="http://moteam.co/netengine">http://moteam.co/netengine</a>!</p>
<p>Você pode ler mais a respeito na <a href="https://pt.wikipedia.org/wiki/Novembro_Azul">Wikipedia</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="movember" />
    </entry>

    <entry>
      <title><![CDATA[Troquei o iOS pelo Android]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/09/28/ha-um-mes-eu-troquei-o-ios-pelo-android?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-09-27T16:50:01.000Z</published>
      <updated>2020-11-15T04:30:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/09/28/ha-um-mes-eu-troquei-o-ios-pelo-android</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/09/28/ha-um-mes-eu-troquei-o-ios-pelo-android">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2013/09/android.png" alt="android"></p>
<p>Gostaria de começar esse post dizendo que vou tentar ser o mais imparcial possível, não sendo fanboy de nenhuma empresa / aparelho / sistema operacional.</p>
<p>Eu não vou comparar somente os sistemas operacionais, mas sim a experiência do hardware com software, ou seja, a integração com o aparelho também.</p>
<h1>Motivação</h1>
<p>Eu parei de usar Windows quando o Vista foi lançado. Essa versão tinha muitos problemas e eu resolvi dar uma chance ao pinguim (aka. Linux), principalmente pelo fato de nunca ter usado ele full-time antes. Muitas coisas eram diferentes (hoje em dia essa diferença é menor), tive que aprender coisas novas e largar velhos costumes para trás. Mas depois de algum tempo, notei que valeu muito a pena e que eu não voltaria atrás. Alguns anos mais tarde, mudei novamente para o <del>OS X</del> macOS (o qual continuo usando até hoje) e vejo que essa experiência de ter usado os 3 sistemas diferentes só me trouxe benefícios.</p>
<p>Eu expliquei tudo isso para demonstrar que essa motivação foi basicamente a mesma com os sistemas operacionais móveis. Depois de quase 3 anos usando iOS e perto da versão 7 ser lançada, decidi que era hora de experimentar um outro mundo. E como eu nunca tinha usado Android full-time antes (apenas havia brincado com aparelhos de amigos), então era hora de mudar.</p>
<h1>Hora de mudar</h1>
<p>Decidi então comprar um <strong>Samsung Galaxy S4</strong>.</p>
<p><img src="/images/posts/2013/09/s4.png" alt="s4"></p>
<p>Procurei pela versão com o Android puro (aka. "Google Play Edition"), mas como ela ainda não estava a venda aqui, comprei a versão com a rom da Samsung mas pouco tempo depois desisti e segui <a href="http://www.goodgearguide.com.au/article/523049/how_update_your_samsung_galaxy_s4_android_4_3_google_edition/">esse tutorial</a> para instalar a rom pura do Google. A vantagem é que o sistema fica mais fluído (mais rápido, dá menos "travadas") e não vem com vários aplicativos inúteis que a Samsung e a operadora do celular te obrigam a ter (uma vez que você não pode apagá-los).</p>
<hr>
<h1>O que eu gostei</h1>
<h3>1. Notificações + LED + atalhos rápidos</h3>
<p>Vou começar com algo que eu uso muito em ambos os sistemas: notificações. Conheço pessoas que simplesmente não se importam muito com elas, mas esse definitivamente não é o meu caso. Esse é um ponto forte no Android: as notificações são muito boas. No iOS você pensa que isso funciona bem até ver como isso funciona no Android, principalmente porque as notificações e as aplicações são bem sincronizadas.</p>
<p>Para cada item você pode ter alguns botões de funções rápidas (exemplo: ao receber um email, você pode clicar nos botões "responder" ou "arquivar") ou ainda pode ver mais detalhes sobre aquele item específico, tocando e deslizando o dedo para baixo naquele item. Outro exemplo legal é quando você tira um screenshot e recebe uma notificação, na qual você pode apenas tocar para já abrir a nova imagem.</p>
<p>Uma diferença muito boa são os ícones na barra superior, com um resumo das notificações:</p>
<p><img src="/images/posts/2013/09/2013-09-27-12.30.05.png" alt="2013-09-27-12.30.05"></p>
<p>Outra coisa bem bacana é o "Pulse notification light". Acredito que nem todo aparelho tenha isso, mas o S4 tem e faz muita diferença. Ao chegar uma nova notificação, ao invés de a tela ligar e mostrar o que chegou, você pode configurar seu aparelho para ele simplesmente piscar o LED. O mais legal é que você pode configurar o LED pra ficar de uma cor para cada tipo de notificação: chamada perdida, SMS, Email, Hangouts, Facebook, Twitter, WhatsApp, etc.</p>
<p><img src="/images/posts/2013/09/led.jpg" alt="led"></p>
<p>Algo bem últil e que agora o iOS 7 também tem (embora falte um atalho para o "Settings") são os atalhos rápidos, que ficam na área de notificações:</p>
<p><img src="/images/posts/2013/09/notifications-atalhos.png" alt="notifications-atalhos"></p>
<h3>2. Tela grande (5") Full HD</h3>
<p>Segundo a Apple, a vantagem de um aparelho um pouco menor é poder tocar todos os cantos da tela com a mesma mão que segura o aparelho. Sim, isso faz sentido, mas a vantagem de ter uma tela grande (5 polegadas) e com boa qualidade é ainda maior. E a adaptação é relativamente rápida.</p>
<h3>3. Teclado swipe</h3>
<p>Assunto polêmico: há quem ame, há que nem ligue. Apesar de eu não achar ele tão mais rápido assim, é mais prático e confortável digitar apenas deslizando o dedo. Mesmo você errando algumas letras, ele tem um algorítimo inteligente e corrige. Gostei muito!</p>
<p><img src="/images/posts/2013/09/swipe.png" alt="swipe"></p>
<h3>4. Lookout</h3>
<p>Uma app que faz toda a diferença: <a href="https://play.google.com/store/apps/details?id=com.lookout">Lookout</a>. Ele tem vários recursos: localizar seu celular (similar ao "Find my iPhone"), se alguém errar 3 vezes a senha de desbloqueio, ele tira uma foto da pessoa e manda no seu email (ele também faz isso quando sua bateria está quase acabando, só que usa o GPS pra saber sua localização e te manda essa informação também), faz backup de contatos, fotos, etc, é anti-virus. Ah, e sim, é free.</p>
<h3>5. Botões "menu" e "voltar"</h3>
<p>Antes eu achava besteira, mas usando diariamente você nota que os botões "menu" e "voltar" são bem práticos (principalmente o último). No S4 eles ficam melhor ainda, porque são dois sensores capacitivos, não botões físicos. E eles ficam apagados até que você toque neles, o que deixa o design do aparelho mais clean.</p>
<p><img src="/images/posts/2013/09/buttons.jpg" alt="buttons"></p>
<h3>6. Customização, flexibilidade e liberdade</h3>
<p>O Android é extremamente personalizável (às vezes mais do que deveria). Pra começar, a possibilidade de instalar launchers diferentes é sensacional. Launcher basicamente é a tela inicial do seu aparelho, o gerenciador de widgets, temas, etc. Estou usando o <a href="https://play.google.com/store/apps/details?id=com.anddoes.launcher&#x26;hl=en">Apex</a> e gostando muito.</p>
<p>É sempre bom poder customizar, embora minha tela inicial seja bem parecida com a default:</p>
<p><img src="/images/posts/2013/09/apex.png" alt="apex"></p>
<p>Você também pode instalar gerenciadores de torrents, emuladores, terminal com acesso root (esse dá um pouco de trabalho, mas dá pra fazer), entre outras coisas. Isso é liberdade!</p>
<p><img src="/images/posts/2013/09/files.png" alt="files"></p>
<center>(Gerenciador de arquivos)</center>
<p><img src="/images/posts/2013/09/screen-lock-options.png" alt="screen-lock-options"></p>
<center>(Formas de desbloquear a tela)</center>
<p><img src="/images/posts/2013/09/utorrent.png" alt="utorrent"></p>
<center>(uTorrent e emuladores são apps facilmente encontradas na Play Store)</center>
<h3>7. Relatório de uso da bateria</h3>
<p>No Android você pode configurar para receber notificações quando a bateria estiver totalmente carregada ou quando estiver acabando. Você também pode facilmente ver o que está consumindo mais bateria:</p>
<p><img src="/images/posts/2013/09/bateria.png" alt="bateria"></p>
<h3>8. Relatório de uso do 3G / 4G</h3>
<p>É possível ver quanto cada app está gastando na sua rede de dados 3G ou 4G. Essa funcionalidade é bastante flexível, permitindo configurar um limite de uso, configurar uma notificação quando você estiver perto de atingir limite, configurar em que dia a sua operadora vai recomeçar a contagem de uso e até mesmo ver quanto cada app gasta em "foreground" e em "background", ou seja, quanto cada app usou enquanto você estava com ela aberta e quanto ela gastou enquanto ela estava fechada (usando "pull notifications", por exemplo), respectivamente.</p>
<p><img src="/images/posts/2013/09/data_usage.png" alt="data_usage"></p>
<h3>9. Instalar apps remotamente</h3>
<p>Você pode entrar no site do <a href="https://play.google.com/">Google play</a> (aka. App Store do Google) usando seu computador, buscar e escolher o aplicativo que quer instalar, selecionar o device no qual você quer instalar o app (no caso de você ter mais de um), clicar em "Instalar" e pronto. Depois de 3 segundos, o device começa a baixar e instalar a app sozinho. Muito útil.</p>
<p><img src="/images/posts/2013/09/instalar-app-remotamente.png" alt="instalar-app-remotamente"></p>
<p>Depois, no device:</p>
<p><img src="/images/posts/2013/09/app-instalada.png" alt="app-instalada"></p>
<h3>10. Google Now</h3>
<p>Ok, o Google mantém uma versão do Google Now pro iOS, mas é diferente. Digo isso porque no Android o Google Now é mais integrado e no geral funciona melhor.</p>
<p><img src="/images/posts/2013/09/google-now.png" alt="google-now"></p>
<h3>11. Quantidade de apps gratuitas</h3>
<p>Até hoje, todas as apps que eu instalei foram gratuitas. Não vejo problema nenhum em pagar por apps, mas ao contrário do iOS, a maioria das apps não custam nada.</p>
<h3>12. SD card</h3>
<p>Não é algo imprescindivel, mas é interessante. Principalmente porque você configurar coisas como: todas as fotos e vídeo que você tirar podem ir automaticamente para o cartão SD e não para o armazenamento interno do aparelho.</p>
<h3>13. Câmera</h3>
<p>As duas câmeras (frontal e traseira) do S4 são muito boas. E o software nativo do Android também é bem bacana, contando com algumas opções avançadas na hora de tirar foto e modos interessantes, como fotos 360º e panorâmicas.</p>
<p><img src="/images/posts/2013/09/camera.png" alt="camera"></p>
<h3>14. Sistema inteligente</h3>
<p>De vez em quando eu ainda me surpreendo com o Android. No geral, o sistema é muito inteligente e facilita algumas coisas. Um exemplo disso é: eu configurei meu device para subir todas as fotos que eu tiro automaticamente para minha conta do Dropbox. Mas quando ele nota que sua bateria está baixa, ele para de de fazer essas coisas para evitar que sua bateria acabe de vez.</p>
<p><img src="/images/posts/2013/09/sistema-inteligente.png" alt="sistema-inteligente"></p>
<h3>15. Alguns detalhes interessantes</h3>
<p>Para finalizar a lista de coisas que eu gostei, o Android é mais detalhista que o iOS:</p>
<ul>
<li>Você pode configurar apps padrões: Chrome é meu navegador padrão, Gmail é meu cliente de email padrão e VLC é meu player de vídeo padrão, etc;</li>
<li>Exibição de detalhes de arquivos: extensão, tamanho, resolução de fotos, duração de vídeos, etc;</li>
<li>Exibição de quanto de memória cada app está usando de ram;</li>
<li>Exibição de quanto de memória cada app está usando de cache;</li>
<li>Gráfico de armazenamento interno / SD card: que tipo de arquivos está gastando mais espaço no seu device;</li>
<li>Etc.</li>
</ul>
<p><img src="/images/posts/2013/09/apps-manager.png" alt="apps-manager"></p>
<center>(Quanto cada app gasta de memória ram)</center>
<p><img src="/images/posts/2013/09/apps-abertas.png" alt="apps-abertas"></p>
<center>(Tela para visualizar e fechar apps que estão rodando)</center>
<p><img src="/images/posts/2013/09/app-info.png" alt="app-info"></p>
<center>(Detalhes de um app específico)</center>
<p><img src="/images/posts/2013/09/storage.png" alt="storage"></p>
<center>(Gráfico do armazenamento interno)</center>
<hr>
<h1>O que eu não gostei</h1>
<h3>1. Fluidez</h3>
<p>Apesar de ter um hardware supostamente superior, o S4 perde no fator "fluidez" para o iPhone. Todas as animações, efeitos e o tempo de resposta dos iPhones são melhores na maioria dos casos. O pior de tudo é o rotação da tela: você vira o device e várias vezes a tela não vira junto. Aí você chacoalha um pouco e a tela vira. Isso chega a ser irritante às vezes.</p>
<h3>2. Fones</h3>
<p>Os fones que vem com o S4 são horríveis. Claro que isso é apenas a minha opnião. Acabei comprando um fone da Sony. A desvantagem é que você perde os controles de volume e play / pause que existem no fone que acompanha o S4. Pensei em comprar um da Apple, mas já os testei e tais controles também não funcionam.</p>
<h3>3. Podcasts</h3>
<p>Escutar podcasts no smartphone é uma das coisas que mais faço diariamente. Testei os 3 aplicativos mais famosos de podcasts no Android e nenhum é grande coisa. O único que é razoavelmente usável é o <a href="https://play.google.com/store/apps/details?id=com.bambuna.podcastaddict">Podcast Addict</a>. Ele tem dois problemas: o primeiro - não tão grave - é que ele oferece muitas opções e você tem que ver uma lista gigante de configurações para deixar do jeito que você gosta (convention over configuration - deveria ser o contrário). O segundo problema é pior: quando você está escutando um episódio, o áudio começa a falhar e às vezes para do nada. Isso é bem frequente, infelizmente.</p>
<h3>4. Google Play - uma loja muito liberal</h3>
<p>A Apple é burocrática e demora um pouco para autorizar a entrada de apps na sua loja. Mas isso tem o lado bom: raramente entram apps realmente ruins. Já na Google Play, tem muita porcaria, incluindo malwares. No geral não chega a ser um problema, mas você deve ser cuidadoso.</p>
<h3>5. Updates</h3>
<p>Como falei no começo do post, instalei uma rom com o Android puro e não estou usando a que a Samsung manda de fábrica. Isso significa que eu não posso simplesmente instalar as atualizações do Google quando elas saem. Pra ser sincero, eu não sei nem quando vou poder (não pesquisei como isso funciona). Mesmo se eu estivesse usando a rom da Samsung, ela demora (às vezes muito) pra liberar o update, como por exemplo agora que o Android 4.3 já foi lançado há mais de um mês e ainda não está disponível para quem usa a rom que já vem no device.</p>
<h3>6. Apps no geral são mais feias e com UX mal pensadas</h3>
<p>Notem que estou generalizando. Já considerando as apps que eu mais uso, isso não chega a incomodar.</p>
<h1>Coisas que não estão nas listas acima</h1>
<p>Coisas que eu não comentei nas duas listas acima foi - ou porque são similares ao iOS / iPhone - ou não fazem diferença para mim.</p>
<hr>
<h1>Mitos</h1>
<p>Alguns mitos sobre ambos os sistemas:</p>
<h3>O Android não se integra tão bem com o Mac quanto o iPhone</h3>
<p>Ok, essa integração pode não ser tão boa quando comparado com o iPhone, principalmente pelo fato de não ter iCloud, mas isso definitivamente foi um problema pequeno. Para tudo tem uma boa alternativa (sendo que maioria eu já usava). Nesse <a href="http://paulstamatiou.com/android-is-better">artigo</a>, tem uma sessão chamada "Apple Lock-in?" que explica o que ele usa pra melhorar essa integração.</p>
<h3>No Android, as apps fecham sozinhas frequentemente (crash)</h3>
<p>Ouvi muita gente falando isso antes de eu começar a usar. Definitivamente não é verdade, é bem raro acontecer.</p>
<h3>No iPhone / iOS você não tem liberdade</h3>
<p>Ok, agora no Android você tem, inclusive tem acesso root ao sistema (que por baixo dos panos é um Linux). Grande coisa! O que você vai fazer agora? Basicamente nada demais :)</p>
<h3>Uma câmera com 90 megapixels é melhor que uma que tem 85</h3>
<p>Obviamente é um mito. A câmera do novo iPhone 5S continua com os mesmos 8 megapixels do iPhone 5 mas é bem superior! E eu não acho que ela fica devendo pra nenhum smartphone que tenha 13 ou 20. Sério!</p>
<h1>Conclusão</h1>
<p>Já estou usando Android há pouco mais de um mês, o que foi suficiente para notar as vantagens e desvantagens. Gostei muito do iOS 7 (minha esposa tem um iPhone 5 e eu uso ele de vez em quando), mas por enquanto não pretendo voltar a usar iOS / iPhone; estou satisfeito com o meu Android.</p>
<p><img src="/images/posts/2013/09/Samsung-Galaxy-S4-vs-Apple-iPhone-5-01.jpg" alt="Samsung-Galaxy-S4-vs-Apple-iPhone-5-01"></p>
<center>(Galaxy S4 e iPhone 5)</center>
<p>Nesse post, eu basicamente listei o que gostei mais e menos em relação ao sistema operacional da Apple e no final das contas, ambos tem excelentes ecosistemas: conjunto de ferramentas, loja de aplicativos e design.</p>
<p>Então fica a dica: não tenha medo de experimentar o que você ainda não usou :)</p>
<hr>
<h2>Atualização</h2>
<p>Em dezembro de 2013, eu acabei voltando a usar iOS/iPhone e também escrevi um post explicando o motivo:</p>
<p><a href="https://www.lucascaton.com/2013/12/20/por-que-eu-voltei-a-usar-ios-iphone">"Por que eu voltei a usar iOS/iPhone"</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="apple" /><category term="iphone" /><category term="iOS" /><category term="android" /><category term="samsung-galaxy-s4" />
    </entry>

    <entry>
      <title><![CDATA[Iniciando uma vida completamente nova]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/08/25/iniciando-uma-vida-completamente-nova?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-08-25T09:15:41.000Z</published>
      <updated>2020-11-15T04:30:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/08/25/iniciando-uma-vida-completamente-nova</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/08/25/iniciando-uma-vida-completamente-nova">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2013/08/australia.jpg" alt="Pessoas escrevendo Austrália no ar com faíscas"></p>
<p>Estou iniciando uma novíssima fase em minha vida.
Acabei de me mudar para <strong>Brisbane, Austrália</strong>!</p>
<p>Vim com minha esposa Aline, que topou o desafio de viver em um país maravilhoso,
mas que fala inglês, com uma cultura ligeiramente diferente, sem conhecer nada
nem ninguém.</p>
<p>Eu escrevi <a href="https://www.lucascaton.com/2013/08/13/australia-uma-nova-vida">um post</a>
agradecendo àqueles que nos ajudaram e também algumas fotos daqui.</p>
<p>Além disso, conforme
<a href="https://twitter.com/cassiuspacheco_/status/348184707432849409">prometido ao @cassiuspacheco</a>,
escrevi um post mais completo, contando como foi o meu processo
de imigração: <a href="https://www.lucascaton.com/2014/07/21/como-e-o-processo-de-imigracao-para-a-australia">clique aqui para ler</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" /><category term="carreira" />
    </entry>

    <entry>
      <title><![CDATA[Austrália: uma nova vida]]></title>
      <summary><![CDATA[Estamos nos mudando para a Austrália!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/08/12/australia-uma-nova-vida?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-08-12T18:15:45.000Z</published>
      <updated>2018-12-01T06:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/08/12/australia-uma-nova-vida</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/08/12/australia-uma-nova-vida">
        <![CDATA[<div xml:lang="pt-BR"><p><figure><img src="https://www.lucascaton.com/images/posts/2013/08/18_australia.jpg" alt="Canguru na praia" width="1500" height="843" /><figcaption>Canguru na praia</figcaption></figure></p>
<p>Finalmente chegou a hora: eu e Aline (minha esposa) estamos nos mudando para a Austrália.
Embarcaremos amanhã à noite. Mas antes de viajar, eu gostaria de agradecer à algumas pessoas:</p>
<p>Primeiramente à <strong>Aline</strong>, minha esposa e companheira, por sempre me apoiar,
por me fazer tão feliz e por topar mudar para o outro lado do mundo;</p>
<p>Ao <strong>Vitor Pellegrino</strong> e ao <strong>Xis (Thiago Aléssio)</strong>, por servirem como exemplo
e me motivarem a correr atrás desse meu sonho;</p>
<p>Ao <strong>Ricardo Bernardeli</strong> e à <strong>Raissa Mantovani</strong>, pelas dicas de como conseguir um emprego fora,
pela ajuda com a burocracia do visto e por todo amparo que estão nos dando nesse novíssimo mundo;</p>
<p>À <strong>minha família</strong> e à <strong>família da Aline</strong>,
por todo apoio, mesmo sabendo que ficaremos mais longe;</p>
<p>Aos <strong>amigos</strong> e <strong>colegas de trabalho</strong>, pelo apoio nessa decisão
e por serem pessoas tão especiais para mim, mesmo quando distantes.</p>
<hr>
<p><figure><img src="https://www.lucascaton.com/images/posts/2013/08/1-uluru.jpg" alt="Uluru, o segundo maior monólito do mundo" width="1600" height="900" /><figcaption>Uluru, o segundo maior monólito do mundo</figcaption></figure></p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2013/08/2-sydney.jpg" alt="Opera House e Harbour Bridge, em Sydney" width="1600" height="1070" /><figcaption>Opera House e Harbour Bridge, em Sydney</figcaption></figure></p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2013/08/3-brisbane.jpg" alt="Cidade de Brisbane" width="1600" height="1000" /><figcaption>Brisbane</figcaption></figure></p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2013/08/4-melbourne.jpg" alt="Cidade de Melbourne" width="1024" height="768" /><figcaption>Melbourne</figcaption></figure></p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2013/08/5-cangurus.jpg" alt="Cangurus em um bosque" width="990" height="742" /><figcaption>Cangurus</figcaption></figure></p>
<p><figure><img src="https://www.lucascaton.com/images/posts/2013/08/6-sydney.jpg" alt="Harbour Bridge à noite, em Sydney" width="1280" height="1024" /><figcaption>Harbour Bridge à noite, em Sydney</figcaption></figure></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="australia" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Draw my life]]></title>
      <summary><![CDATA[Entrei na brincadeira e desenhei minha vida!]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/07/31/video-draw-my-life?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-07-30T21:00:00.000Z</published>
      <updated>2013-07-30T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/07/31/video-draw-my-life</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/07/31/video-draw-my-life">
        <![CDATA[<div xml:lang="pt-BR"><p>Entrei na brincadeira e desenhei minha vida:</p>
<p><a href="https://www.youtube.com/watch?v=YUaFqqp-Yc4"><img src="https://i.ytimg.com/vi_webp/YUaFqqp-Yc4/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="lucas-caton" />
    </entry>

    <entry>
      <title><![CDATA[Webinar sobre as novidades do Rails 4]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/07/02/apresentacao-online-sobre-as-novidades-do-rails-4?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-07-02T12:21:30.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/07/02/apresentacao-online-sobre-as-novidades-do-rails-4</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/07/02/apresentacao-online-sobre-as-novidades-do-rails-4">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2013/07/Screen-Shot-2013-07-02-at-10.22.18-PM.png" alt="Screen-Shot-2013-07-02-at-10.22.18-PM"></p>
<blockquote>
<p>O Rails 4 acabou de ser lançado e tem várias novidades bacanas!
Aprenda o que mudou, o que são Strong Parameters, turbolinks, etags, requests com streaming e outras coisas interessantes.</p>
</blockquote>
<p>Apresentei um webinar sobre as novidades do <strong>Rails 4</strong>. A apresentação foi gravada e está
<a href="https://www.eventials.com/pt-br/locaweb/o-que-ha-de-novo-no-rails-4-com-lucas-caton/">disponível no site da Eventials</a>.</p>
<p>Seguem os slides:</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/bnoeZ2zkppqunD" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen></iframe>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="palestra" /><category term="apresentacoes" /><category term="webinar" /><category term="tech-talk" />
    </entry>

    <entry>
      <title><![CDATA[Contar a frequência de objetos em um array usando Ruby]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/06/26/contar-a-frequencia-de-objetos-em-um-array-usando-ruby?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-06-26T03:32:05.000Z</published>
      <updated>2019-12-29T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/06/26/contar-a-frequencia-de-objetos-em-um-array-usando-ruby</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/06/26/contar-a-frequencia-de-objetos-em-um-array-usando-ruby">
        <![CDATA[<div xml:lang="pt-BR"><p>Às vezes precisamos contabilizar qual a frequência de objetos em um array usando Ruby.</p>
<p>Por exemplo, um array <code>["dog", "dog", "cat"]</code> tem dois elementos <code>"dog"</code> e um <code>"cat"</code>.
Para transformar isso em um hash com os totais, existem as seguintes alternativas, dependendo da versão do Ruby que você esteja utilizando:</p>
<h3>Ruby 2.7 ou superior</h3>
<pre><code class="language-ruby">["dog", "dog", "cat"].tally
# => { "dog" => 2, "cat" => 1 }
</code></pre>
<h3>Ruby 2.2 até 2.6</h3>
<pre><code class="language-ruby">words = ["dog", "dog", "cat"]
Hash[words.group_by(&#x26;:itself).map { |word, words| [word, words.size] }]
# => { "dog" => 2, "cat" => 1 }
</code></pre>
<h3>Ruby 2.1 ou mais antigo</h3>
<pre><code class="language-ruby">Hash[words.group_by { |w| w }.map { |word, words| [word, words.size] }]
# => { "dog" => 2, "cat" => 1 }
</code></pre>
<p>Se você achou isso útil, deixe um comentário abaixo me contanto! 😉</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Ruby on Rails para iniciantes]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/05/21/screencasts-de-ruby-on-rails-para-iniciantes?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-05-21T04:01:37.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/05/21/screencasts-de-ruby-on-rails-para-iniciantes</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/05/21/screencasts-de-ruby-on-rails-para-iniciantes">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2013/01/ruby_rails.png" alt="ruby_rails"></p>
<p>No ano passado, eu comecei a gravar alguns vídeos pra ajudar quem gostaria de começar a programar com Ruby on Rails.
Por enquanto são 3 screencasts apenas, mas já é o suficiente pra quem gostaria de começar.</p>
<p><a href="https://www.youtube.com/watch?v=PBTop8vWuz0"><img src="https://i.ytimg.com/vi_webp/PBTop8vWuz0/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><a href="https://www.youtube.com/watch?v=pMYPHL4kdBo"><img src="https://i.ytimg.com/vi_webp/pMYPHL4kdBo/maxresdefault.webp" alt="YouTube video" /></a></p>
<p><a href="https://www.youtube.com/watch?v=PbuGbLUt6RM"><img src="https://i.ytimg.com/vi_webp/PbuGbLUt6RM/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Mandem feedback, com sugestões, críticas ou até mesmo dúvidas.</p>
<p>Espero que tenham gostado :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="videos" /><category term="ruby" /><category term="rails" />
    </entry>

    <entry>
      <title><![CDATA[15º Encontro Locaweb de Profissionais de Internet]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/05/08/15o-encontro-locaweb-de-profissionais-de-internet?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-05-08T12:34:05.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/05/08/15o-encontro-locaweb-de-profissionais-de-internet</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/05/08/15o-encontro-locaweb-de-profissionais-de-internet">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2013/05/Screen-Shot-2013-05-08-at-10.12.49-PM.png" alt="Screen-Shot-2013-05-08-at-10.12.49-PM"></p>
<p>Ontem participei do <a href="http://www.encontrolocaweb.com.br/">15º Encontro Locaweb</a> em Curitiba-PR.
O evento foi interessante e bem organizado e não estou dizendo isso só porque trabalho aqui :)</p>
<p>Assisti as seguintes palestras:</p>
<ul>
<li>Fábio Ricotta - "Usando SEO para alavancar suas visitas e negócios"</li>
<li>Diego Eis - "Guia de Sobrevivência"</li>
<li>Murilo Gun - "O segredo do fracasso"</li>
<li>Silvio Meira - "Empreendedorismo Digital"</li>
<li>Luli Radfahrer - "Internet das coisas, computação em nuvem e tendências 2013"</li>
</ul>
<p>Todas foram boas, mas as apresentações do Ricotta, do Eis e do Luli me surpreenderam, foram muito boas mesmo!</p>
<p>Tiramos essa foto aí na hora do almoço, no Jardim Botânico. Da esquerda pra direita: Ítalo Oliveira, Diego Eis, eu, Bruno Batalha e Marcos Oliveira:</p>
<p><img src="/images/posts/2013/05/jardim-botanico-curitiba.jpg" alt="jardim-botanico-curitiba"></p>
<p>Que venha o 16º encontro! :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="eventos" /><category term="locaweb" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: Interessante plugin "vim-abolish"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/04/29/screencast-2-interessante-plugin-vim-abolish?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-04-29T01:28:12.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/04/29/screencast-2-interessante-plugin-vim-abolish</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/04/29/screencast-2-interessante-plugin-vim-abolish">
        <![CDATA[<div xml:lang="pt-BR"><p>Esse é o segundo <em>screencast</em> que eu faço para o blog e novamente é sobre <strong>Vim</strong>
(<a href="https://www.lucascaton.com/2011/12/13/screencast-1-17-dicas-para-o-vim">assista ao primeiro aqui</a>).</p>
<p>Esse ficou bem mais curto (tem apenas 5 minutos) e vai direto ao ponto. Espero que gostem!</p>
<p><a href="https://www.youtube.com/watch?v=OWC3KsXcOCU"><img src="https://i.ytimg.com/vi_webp/OWC3KsXcOCU/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Links relevantes:</p>
<ul>
<li><a href="https://github.com/tpope/vim-abolish">vim-abolish</a></li>
<li><a href="https://github.com/lucascaton/vimfiles">Meus vimfiles</a></li>
</ul>
<p>Por favor, mandem feedback sobre o que acharam!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="vim" /><category term="videos" />
    </entry>

    <entry>
      <title><![CDATA[Projeto "MyPodcasts.info"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/04/21/projeto-mypodcasts-info?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-04-21T08:56:48.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/04/21/projeto-mypodcasts-info</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/04/21/projeto-mypodcasts-info">
        <![CDATA[<div xml:lang="pt-BR"><p>Eu gosto muito de escutar podcasts. Escuto muitos, sobre variados temas, alguns em português, outros em inglês, alguns sobre áreas totalmente diferentes da que eu trabalho, alguns nostálgicos, alguns pra melhorar meu inglês e por aí vai.</p>
<p><aside>Aproveite para conhecer também o <a href="https://www.lucascaton.com/podcast"><strong>meu podcast</strong></a>!</aside></p>
<p>Sempre que encontro com alguém que também gosta/escuta, rola as perguntas sobre qual cada um escuta, sobre o que se trata, quais amigos em comum escutam, qual o nível de qualidade, entre outras dúvidas.</p>
<p>Foi aí que surgiu a idéia de criar o site <a href="http://mypodcasts.info/">MyPodcasts.info</a>, um site onde você pode cadastrar tudo isso e no final ter uma URL publica para passar para os interessados nos podcasts que você escuta.</p>
<p>Há 2 meses atrás eu o coloquei no ar e logo em seguida o liberei como open-source: <a href="https://github.com/lucascaton/mypodcasts.info">github.com/lucascaton/mypodcasts.info</a>. Então, sintam-se a vontade para usar o site e contribuir com ele.</p>
<p>Seguem alguns screenshots:</p>
<p><img src="/images/posts/2013/04/Screen-Shot-2013-04-21-at-6.38.43-PM.png" alt="Screen-Shot-2013-04-21-at-6.38.43-PM"></p>
<p><img src="/images/posts/2013/04/Screen-Shot-2013-04-21-at-6.44.15-PM.png" alt="Screen-Shot-2013-04-21-at-6.44.15-PM"></p>
<p><img src="/images/posts/2013/04/Screen-Shot-2013-04-21-at-6.44.50-PM.png" alt="Screen-Shot-2013-04-21-at-6.44.50-PM"></p>
<p>Ah sim! O site é responsivo:</p>
<p><img src="/images/posts/2013/04/Screen-Shot-2013-04-21-at-6.48.11-PM.png" alt="Screen-Shot-2013-04-21-at-6.48.11-PM"></p>
<hr>
<blockquote>
<h3>Atualização em Fev/2014:</h3>
<p>O site <a href="http://mypodcasts.info/">mypodcasts.info</a> chegou ao fim, apesar de eu ainda ter planos de reativá-lo um dia.
No momento, infelizmente não tenho tempo pra mantê-lo.</p>
<p>Ele sempre foi e continuará sendo open-source. Encontre o código-fonte em <a href="https://github.com/lucascaton/mypodcasts.info">github.com/lucascaton/mypodcasts.info</a>.
Se tiver interesse em manter o projeto, envie um comentário no final desse post.</p>
<p>Obrigado a todos que usaram o site e mandaram feedbacks.</p>
</blockquote>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="rails" /><category term="open-source" /><category term="meus-projetos" /><category term="podcasts" />
    </entry>

    <entry>
      <title><![CDATA[Interesting script written in Ruby: "The Globe"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2013/04/19/interesting-script-written-in-ruby-the-globe?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-04-19T10:35:03.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2013/04/19/interesting-script-written-in-ruby-the-globe</id>
      <content type="html" xml:base="https://www.lucascaton.com/2013/04/19/interesting-script-written-in-ruby-the-globe">
        <![CDATA[<div xml:lang="en"><p><img src="/images/posts/2013/04/the-globe.gif" alt="The Globe"></p>
<p>I've just found this amazing Ruby script!</p>
<p>In order to run it yourself, just create a Ruby file called <code>a.rb</code> with the following content:</p>
<pre><code class="language-ruby">v=0000;eval$s=%q~d=%!^Lcf&#x3C;LK8,                  _@7gj*LJ=c5nM)Tp1g0%Xv.,S[&#x3C;>YoP
4ZojjV)O>qIH1/n[|2yE[>:ieC       "%.#%  :::##"       97N-A&#x26;Kj_K_>&#x3C;wS5rtWk@*a+Y5
yH?b[F^e7C/56j|pmRe+:)B     "##%      ::##########"     O98(Zh)'Iof*nm.,$C5Nyt=
PPu01Avw^&#x3C;IiQ=5$'D-y?    "##:         ###############"    g6`YT+qLw9k^ch|K'),tc
6ygIL8xI#LNz3v}T=4W    "#            #.   .####:#######"    lL27FZ0ij)7TQCI)P7u
}RT5-iJbbG5P-DHB&#x3C;.   "              ##### # :############"   R,YvZ_rnv6ky-G+4U'
$*are@b4U351Q-ug5   "              #######################"   00x8RR%`Om7VDp4M5
PFixrPvl&#x26;&#x3C;p[]1IJ   "              ############:####  %#####"   EGgDt8Lm#;bc4zS^
y]0`_PstfUxOC(q   "              .#############:##%   .##  ."   /,}.YOIFj(k&#x26;q_V
zcaAi?]^lCVYp!;  " %%            .################.     #.   "  ;s="v=%04o;ev"%
(;v=(v-($*+[45,  ":####:          :##############%       :   "  ])[n=0].to_i;)%
360)+"al$s=%q#{  "%######.              #########            "  ;;"%c"%126+$s&#x3C;&#x3C;
126}";d.gsub!(/  "##########.           #######%             "  |\s|".*"/,"");;
require"zlib"||  "###########           :######.             "  ;d=d.unpack"C*"
d.map{|c|n=(n||  ":#########:           .######: .           "  )*90+(c-2)%91};
e=["%x"%n].pack   " :#######%           :###### #:          "   &#x26;&#x26;"H*";e=Zlib::
Inflate.inflate(   "  ######%           .####% ::          "   &#x26;&#x26;e).unpack("b*"
)[0];22.times{|y|   "  ####%             %###             "   ;w=(Math.sqrt(1-(
(y*2.0-21)/22)**(;   " .###:             .#%             "   ;2))*23).floor;(w*
2-1).times{|x|u=(e+    " %##                           "    )[y*z=360,z]*2;u=u[
90*x/w+v+90,90/w];s[(    " #.                        "    ;y*80)+120-w+x]=(""&#x3C;&#x3C;
32&#x3C;&#x3C;".:%#")[4*u.count((     " .                   "     ;"0"))/u.size]}};;puts\
s+";_ The Qlobe#{" "*18+ (       "#  :#######"       ;"Copyright(C).Yusuke End\
oh, 2010")}";exit~;_ The Qlobe                  Copyright(C).Yusuke Endoh, 2010
</code></pre>
<p>Then, run the following line on your terminal:</p>
<pre><code class="language-bash">while true; do clear; ruby a.rb | tee b.rb; sleep 0.2; mv -f b.rb a.rb; done
</code></pre>
<hr>
<p>Via <a href="https://mametter.hatenablog.com/entry/20100905/p1">Hatena</a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[Projeto "time_clock"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/03/16/projeto-time_clock?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-03-16T08:24:46.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/03/16/projeto-time_clock</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/03/16/projeto-time_clock">
        <![CDATA[<div xml:lang="pt-BR"><p>É comum na maioria das consultorias brasileiras de software, principalmente as que contratam funcionários através de regime PJ, solicitarem o relatório de horas trabalhadas mês a mês. Como esse era o meu caso no ano passado, eu criei um pequeno sistema para facilitar esse controle.</p>
<p>Eu havia criando essa funcionalidade dentro do próprio código do meu site, mas como várias pessoas gostaram e me pediram o código, eu o extraí para um projeto a parte e o liberei como open-source:</p>
<p><a href="https://github.com/lucascaton/time_clock">https://github.com/lucascaton/time_clock</a></p>
<h3>Screenshots</h3>
<p><img src="/images/posts/2013/03/screenshot_browser.png" alt="screenshot_browser"></p>
<p><img src="/images/posts/2013/03/screenshot_iphone.png" alt="screenshot_iphone"></p>
<p>Sinta-se à vontade para usar, melhorar e divulgar.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="rails" /><category term="open-source" /><category term="meus-projetos" />
    </entry>

    <entry>
      <title><![CDATA[Hello, I am a compiler]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2013/02/23/hello-i-am-a-compiler?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-02-23T01:37:55.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2013/02/23/hello-i-am-a-compiler</id>
      <content type="html" xml:base="https://www.lucascaton.com/2013/02/23/hello-i-am-a-compiler">
        <![CDATA[<div xml:lang="en"><p><img src="/images/posts/2013/02/robot.jpg" alt="robot"></p>
<p>I've found the following text <a href="http://stackoverflow.com/questions/2684364/why-arent-programs-written-in-assembly-more-often/2685541#2685541">here</a>
and thought it'd be nice to share it with you. Hope you enjoy it as much as I did :)</p>
<blockquote>
<p>Hello, I am a compiler.</p>
<p>I just scanned thousands of lines of code while you were reading this sentence. I browsed through millions of possibilities of optimizing a single line of yours using hundreds of different optimization techniques based on a vast amount of academic research that you would spend years getting at. I won't feel any embarrassment, not even a slight ick, when I convert a three-line loop to thousands of instructions just to make it faster. I have no shame to go to great lengths of optimization or to do the dirtiest tricks. And if you don't want me to, maybe for a day or two, I'll behave and do it the way you like. I can transform the methods I'm using whenever you want, without even changing a single line of your code. I can even show you how your code would look in assembly, on different processor architectures and different operating systems and in different assembly conventions if you'd like. Yes, all in seconds. Because, you know, I can; and you know, you can't.</p>
<p>P.S. Oh, by the way you weren't using half of the code you wrote. I did you a favor and threw it away.</p>
</blockquote>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="compiler" />
    </entry>

    <entry>
      <title><![CDATA[Getting root permission to change a file without leaving Vim]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2013/02/22/getting-root-permissions-on-a-file-inside-of-vim?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-02-22T05:33:41.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2013/02/22/getting-root-permissions-on-a-file-inside-of-vim</id>
      <content type="html" xml:base="https://www.lucascaton.com/2013/02/22/getting-root-permissions-on-a-file-inside-of-vim">
        <![CDATA[<div xml:lang="en"><p>You know when you open a file on <strong>Vim</strong> and after making changes and trying to save the file, Vim
tells you that you need <code>root</code> permission to do so?</p>
<p>This is what most people do to solve it:</p>
<ul>
<li>Copy the content of the file to my clipboard</li>
<li>Close Vim</li>
<li>Re-open it with <code>sudo</code></li>
<li>Paste it and try to save it again</li>
</ul>
<p>Well, turns out there's an easier way to achieve the same thing:</p>
<pre><code class="language-vim">:w !sudo tee %
</code></pre>
<p>Thanks to my friend <a href="https://twitter.com/dlisboa">Diogo Lisboa</a> for teaching me this!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="vim" />
    </entry>

    <entry>
      <title><![CDATA[A simple way to deploy your Rails applications]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2013/01/25/a-simple-way-to-deploy-your-rails-applications?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-01-25T09:24:40.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2013/01/25/a-simple-way-to-deploy-your-rails-applications</id>
      <content type="html" xml:base="https://www.lucascaton.com/2013/01/25/a-simple-way-to-deploy-your-rails-applications">
        <![CDATA[<div xml:lang="en"><p>When I have a very simple Rails app, I avoid adding <a href="https://github.com/capistrano/capistrano">Capistrano</a> or any other complex tool to deploy it.</p>
<p>Instead, I use a simple shell script, which access the server via SHH and do what needs to be done:</p>
<pre><code class="language-bash">#! /bin/bash
# script/deploy.sh
TAG=deployed_at_$(date +"%F_%H-%M")
git tag -m '' -a $TAG
git push --tags
ssh user@your_domain.com &#x3C;&#x3C; 'SSH'
  cd /var/rails_apps/my_app
  rm -rf public/assets
  git pull
  bundle install --without development test
  bundle exec rake db:migrate db:seed assets:clean assets:precompile
  touch tmp/restart.txt
  git describe > public/version
SSH
</code></pre>
<p>After that, a tag will be created in the git repository.
Now, you know exactly the date and time when it was deployed.</p>
<p>Also, you can find out which version (tag from git) is in production by accessing the URL http://your_domain.com/version.</p>
<p><img src="/images/posts/2013/01/your_domain.png" alt="your_domain"></p>
<hr>
<h3>Update from March 8, 2013:</h3>
<p>I've created another script which accepts a <code>-q</code> (quick) flag:</p>
<pre><code class="language-bash">#! /bin/bash
# script/deploy.sh
create_tag(){
  TAG=deployed_at_$(date +"%F_%H-%M")
  git tag -m '' -a $TAG
  git push --tags
}
quick_deploy(){
  echo 'Starting quick deploy...'
  create_tag
  ssh yourserver.com &#x3C;&#x3C; 'SSH'
    cd /var/rails_apps/app_name
    git pull
    bundle install --without development test
    touch tmp/restart.txt
    git describe > public/version
SSH
}
complete_deploy(){
  echo 'Starting complete deploy...'
  create_tag
  ssh yourserver.com &#x3C;&#x3C; 'SSH'
    cd /var/rails_apps/app_name
    rm -rf public/assets
    git pull
    bundle install --without development test
    bundle exec rake db:migrate db:seed assets:clean assets:precompile
    touch tmp/restart.txt
    git describe > public/version
SSH
}
if [ $1 ]; then
  if [ "$1" == '-q' ] || [ "$1" == '--quick' ]; then
    quick_deploy
  else
    echo -e 'Usage: script/deploy [OPTIONS]\n\nOptions:\n-q --quick: Deploy without running migrations nor re-precompiling assets.\n'
  fi
else
  complete_deploy
fi
</code></pre>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="deploy" />
    </entry>

    <entry>
      <title><![CDATA[Evento "Start on Rails" em SP]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2013/01/22/start-on-rails-em-sp-como-foi?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-01-22T03:34:35.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2013/01/22/start-on-rails-em-sp-como-foi</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2013/01/22/start-on-rails-em-sp-como-foi">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2013/01/0.jpg" alt="0"></p>
<p>No dia 19/01/2013 aconteceu o <strong>Start on Rails</strong> em São Paulo-SP.</p>
<p>É um evento que deu aquele ponta pé inicial para o pessoal que está interessado em começar a trabalhar / estudar <strong>Ruby on Rails</strong>,
parecido parecido com o <a href="https://www.lucascaton.com/2012/09/12/rails-girls-sp-2012">Rails Girls que rolou ano passado</a>.
E eu participei como coach novamente! \o/</p>
<p><img src="/images/posts/2013/01/1.jpg" alt="1"></p>
<p><img src="/images/posts/2013/01/2.jpg" alt="2"></p>
<p><img src="/images/posts/2013/01/3.jpg" alt="3"></p>
<p><img src="/images/posts/2013/01/4.jpg" alt="4"></p>
<p><img src="/images/posts/2013/01/5.jpg" alt="5"></p>
<p><img src="/images/posts/2013/01/6.jpg" alt="6"></p>
<p><img src="/images/posts/2013/01/7.jpg" alt="7"></p>
<p><img src="/images/posts/2013/01/8.jpg" alt="8"></p>
<p><img src="/images/posts/2013/01/774352_10151352654644837_1237966537_o.jpg" alt="774352_10151352654644837_1237966537_o"></p>
<p><img src="/images/posts/2013/01/774919_10151352655484837_446777557_o.jpg" alt="774919_10151352655484837_446777557_o"></p>
<p><img src="/images/posts/2013/01/774903_10151352655779837_1531556738_o.jpg" alt="774903_10151352655779837_1531556738_o"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="eventos" />
    </entry>

    <entry>
      <title><![CDATA[An easy way to split windows in Vim]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2013/01/03/an-easy-way-to-split-windows-in-vim?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2013-01-03T01:22:32.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2013/01/03/an-easy-way-to-split-windows-in-vim</id>
      <content type="html" xml:base="https://www.lucascaton.com/2013/01/03/an-easy-way-to-split-windows-in-vim">
        <![CDATA[<div xml:lang="en"><p>There are several ways to split windows in <strong>Vim</strong>.</p>
<p>This one is now my favorite:</p>
<p><img src="/images/posts/2013/01/cell-division.png" alt="cell-division"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="vim" />
    </entry>

    <entry>
      <title><![CDATA[Transformando um Array em um Enumerator no Ruby]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/12/29/transformando-um-array-em-um-enumerator-no-ruby?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-12-28T22:53:32.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/12/29/transformando-um-array-em-um-enumerator-no-ruby</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/12/29/transformando-um-array-em-um-enumerator-no-ruby">
        <![CDATA[<div xml:lang="pt-BR"><p>Existem alguns casos em que você precisa modificar um array (aumentá-lo por exemplo) repetindo os
valores presentes no array original.</p>
<p>Uma forma bem interessante de fazer isso é convertendo tal array para um objeto Enumerator.
Para isso, existe o método <strong>Enumerator#cycle</strong>. Imagine o seguinte array:</p>
<pre><code class="language-ruby">array = [1, 3, 5, 7]
</code></pre>
<p>Ao rodar o método <code>cycle</code>, veja o que acontece:</p>
<pre><code class="language-ruby">array.cycle # => #&#x3C;Enumerator: [1, 3, 5, 7]:cycle>
</code></pre>
<p>Podemos agora usar o método <code>Enumerator#take</code> e modificar o array original como quisermos.
Por exemplo, vamos dobrar o seu tamanho:</p>
<pre><code class="language-ruby">array.cycle.take(8) # => [1, 3, 5, 7, 1, 3, 5, 7]
</code></pre>
<p>Foi criado um array do tamanho especificado no parametro do método <code>take</code>.</p>
<p>Isso é útil - por exemplo - em casos similares à
<a href="https://github.com/tomas-stefano/boleto_bancario/commit/967503d35ac1f9c250aa7438fa22670cb947afef">esse código</a>
da gem <code>boleto_bancario</code>. Em algoritmos de IA também é bastante comum precisar desse tipo de
modificação em arrays.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" />
    </entry>

    <entry>
      <title><![CDATA[Novo trabalho, nova fase]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/10/15/novo-trabalho-nova-fase?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-10-15T13:15:38.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/10/15/novo-trabalho-nova-fase</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/10/15/novo-trabalho-nova-fase">
        <![CDATA[<div xml:lang="pt-BR"><p>Depois de quase um ano <a href="https://www.lucascaton.com/2012/03/05/novos-desafios">trabalhando na Codeminer 42</a>, posso dizer que tive o prazer de trabalhar com equipes sensacionais, com as quais aprendi muitas coisas, sendo recompensado ao ver a realização de bons trabalhos e também fazendo grandes amigos. <strong>Obrigado Codeminer 42!</strong></p>
<p>Começo hoje uma nova fase da minha vida, trabalhando na <strong>Locaweb</strong>! E como eu já conheço a equipe, o ambiente de trabalho e os projetos, me sinto honrado de estar começando nessa empresa, onde pretendo dar o meu melhor, como sempre tentei fazer. Obrigado a todos pela ótima recepção!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="carreira" />
    </entry>

    <entry>
      <title><![CDATA[New blog layout]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2012/10/02/new-blog-layout?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-10-02T04:08:09.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2012/10/02/new-blog-layout</id>
      <content type="html" xml:base="https://www.lucascaton.com/2012/10/02/new-blog-layout">
        <![CDATA[<div xml:lang="en"><p>I've just updated my blog with a fresh, cleaner theme. I hope y'all like it! 🙂</p>
<p>Here's a screenshot for posterity:</p>
<p><img src="/images/posts/2012/10/new-blog-layout-browser.png" alt="screenshot"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="site" /><category term="blog" />
    </entry>

    <entry>
      <title><![CDATA[Rails Girls SP 2012]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/09/12/rails-girls-sp-2012?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-09-12T00:59:59.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/09/12/rails-girls-sp-2012</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/09/12/rails-girls-sp-2012">
        <![CDATA[<div xml:lang="pt-BR"><p>Nos dias 7 e 8 de setembro, aconteceu o evento "Rails Girls" aqui em São Paulo.</p>
<p>O evento é uma iniciativa para fazer com que mais mulheres se interessem pela área de desenvolvimento de software.
O evento é gratuito e acontece em vários lugares do mundo. Aqui no Brasil já aconteceu em Porto Alegre e agora em São Paulo (realizado na Locaweb).</p>
<p>Nos dois dias do evento, foram apresentadas algumas lighting talks muito boas (a maioria apresentadas por mulheres) e um curso básico de programação para web, usando Ruby on Rails.</p>
<p>Durante o mini-curso, foi mostrado às alunas uma visão geral sobre desenvolvimento web (HTML, CSS, javascript), MVC e banco de dados.
Elas tiveram que criar um projeto real, começando do zero e terminando com a aplicação rodando no Heroku, apresentando o que fizeram para todos no final.</p>
<p>Eu participei como coach e valeu muito a pena. Foi sensacional ver os projetos finalizados!</p>
<p>Segue o link do evento e algumas fotos:</p>
<ul>
<li><a href="http://railsgirls.com/saopaulo">http://railsgirls.com/saopaulo</a></li>
<li><a href="http://www.flickr.com/photos/64572237@N00/sets/72157631520431773/">http://www.flickr.com/photos/64572237@N00/sets/72157631520431773/</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="railsgirls" /><category term="eventos" /><category term="ruby" /><category term="rails" />
    </entry>

    <entry>
      <title><![CDATA[How to test Elasticsearch in a Rails application]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2012/08/01/how-to-test-elasticsearch-in-a-rails-application?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-08-01T00:50:11.000Z</published>
      <updated>2025-01-12T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2012/08/01/how-to-test-elasticsearch-in-a-rails-application</id>
      <content type="html" xml:base="https://www.lucascaton.com/2012/08/01/how-to-test-elasticsearch-in-a-rails-application">
        <![CDATA[<div xml:lang="en"><p>When I started using Elasticsearch in my Rails applications, I had a problem creating separate indexes for the automated tests.</p>
<p>The problem was that there was no way to create more than one database in Elasticsearch.
You can create different indexes, but no different databases.</p>
<p>Even creating indexes with different names won't solve the problem:
it's necessary to configure our Rails models in order to work with a different index name when the tests are running.</p>
<p>I'm using both <a href="https://github.com/karmi/tire">tire</a> and <a href="http://relishapp.com/rspec">RSpec</a> gems.
In this post, I'll explain how to separate indexes for <code>development</code> and <code>test</code> environments.</p>
<p>First of all, I've included the code below in file <code>config/initializers/tire.rb</code>:</p>
<pre><code class="language-ruby">if Rails.env.test?
  prefix = "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}_"
  Tire::Model::Search.index_prefix(prefix)
end
</code></pre>
<p>And I've manually set the index name in the model (assuming there is a <code>Movie</code> model):</p>
<pre><code class="language-ruby">index_name "#{Tire::Model::Search.index_prefix}movies"
</code></pre>
<p>Done! With that, the index name will be <code>movies</code> in <code>development</code> environment and <code>appname_test_movies</code> in <code>test</code> environment.</p>
<h2>Deleting test indexes</h2>
<p>In order to delete the test indexes after the suite has finished running, just add the following code to file <code>spec/integration_helper.rb</code> (or similar):</p>
<pre><code class="language-ruby">RSpec.configure do |config|
  config.after(:all, type: :request) { delete_movie_index }
end
</code></pre>
<p>And create a custom macro, which will delete the indexes:</p>
<pre><code class="language-ruby">def delete_movie_index
  Movie.index.delete
end
</code></pre>
<h2>Demo app</h2>
<p>I created a small application to demonstrate the technique explained in this post:</p>
<p><a href="https://github.com/lucascaton/elasticsearch_app_example">https://github.com/lucascaton/elasticsearch_app_example</a></p>
<p>I hope it helps!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="rspec" /><category term="bdd" /><category term="elasticsearch" />
    </entry>

    <entry>
      <title><![CDATA[[Apresentação] "Elastic Search" - Guru SP / Tech talk da Codeminer42]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/07/23/apresentacao-elastic-search-tech-talk-da-codeminer-42?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-07-23T05:56:18.000Z</published>
      <updated>2023-08-19T05:23:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/07/23/apresentacao-elastic-search-tech-talk-da-codeminer-42</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/07/23/apresentacao-elastic-search-tech-talk-da-codeminer-42">
        <![CDATA[<div xml:lang="pt-BR"><p>Ontem apresentei uma tech talk na Codeminer42 sobre <strong>Elastic Search</strong>.
Alguns dias depois, fiz a mesma apresentação no <strong>GuruSP</strong> e essa foi filmada pelo grande <a href="http://blip.tv/agaelebe/">Agaelebe</a>):</p>
<p><a href="https://www.youtube.com/watch?v=7U-4bllp63k"><img src="https://i.ytimg.com/vi_webp/7U-4bllp63k/maxresdefault.webp" alt="YouTube video" /></a></p>
<h2>Slides</h2>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/I0pxllmFqTaSpy" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen></iframe>
<h2>Fotos da Tech Talk (Codeminer42):</h2>
<p><img src="/images/posts/2012/06/IMG_20120628_201007.jpeg" alt="IMG_20120628_201007"></p>
<p><img src="/images/posts/2012/06/IMG_20120628_200404.jpeg" alt="IMG_20120628_200404"></p>
<p><img src="/images/posts/2012/06/IMG_20120628_195328.jpeg" alt="IMG_20120628_195328"></p>
<p><img src="/images/posts/2012/06/IMG_20120628_195317.jpeg" alt="IMG_20120628_195317"></p>
<p><img src="/images/posts/2012/06/IMG_20120628_195305.jpeg" alt="IMG_20120628_195305"></p>
<p><img src="/images/posts/2012/06/1340923908514.jpeg" alt="1340923908514"></p>
<h2>Fotos do 25º encontro do Guru-SP</h2>
<p><img src="/images/posts/2012/06/GuruSP-1.jpg" alt="GuruSP-1"></p>
<p><img src="/images/posts/2012/06/GuruSP-2.jpg" alt="GuruSP-2"></p>
<p>Obrigado ao <a href="https://twitter.com/jonas_alves">Jonas</a> e à minha noiva <a href="https://twitter.com/alinecaton">Aline</a> pelas fotos! :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="elasticsearch" /><category term="palestra" /><category term="apresentacoes" /><category term="tech-talks" />
    </entry>

    <entry>
      <title><![CDATA[Pair programming with tmux]]></title>
      <summary><![CDATA[Set up tmux for pair programming in a remote environment]]></summary>
      <link href="https://www.lucascaton.com/2012/07/11/pair-programming-with-tmux?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-07-11T07:39:00.000Z</published>
      <updated>2025-03-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2012/07/11/pair-programming-with-tmux</id>
      <content type="html" xml:base="https://www.lucascaton.com/2012/07/11/pair-programming-with-tmux">
        <![CDATA[<div xml:lang="en"><p>Pair programming is a technique where two developers work together on the same task.
One is the "driver", typing and interacting with the code, while the other is the "navigator",
reviewing the code and suggesting improvements.
This method can significantly improve code quality and encourage learning.</p>
<p>When working remotely, keeping both developers on the same page can be challenging.
However, <strong>tmux</strong> - a terminal multiplexer - makes this easier by allowing
multiple users to share a session, even across different locations.</p>
<p><img src="/images/posts/2012/07/tmux.jpg" alt="tmux"></p>
<p>I'll explore how to set up tmux for pair programming, which involves two steps:</p>
<ul>
<li>Both users accessing the same server or system</li>
<li>The server setup (for the driver) and the client setup (for the navigator)</li>
</ul>
<h3>Server setup</h3>
<p>First, the "driver" needs to set up the tmux session.
This requires access to a shared system or server where both developers can connect.
On the server, run the following commands:</p>
<pre><code class="language-bash"># -2` flag ensures that tmux uses 256-color support
# `-S` specifies a UNIX socket, so others can connect to this session
tmux -2 -S /tmp/pair new-session -s PairProgramming
# Ensure the correct permissions for other users to connect:
chmod 777 /tmp/pair
</code></pre>
<p>This command creates a new tmux session called <code>PairProgramming</code>
but you can call it whatever you'd like.</p>
<h3>Client setup</h3>
<p>On the client (the "navigator"), run this command to attach to the tmux session:</p>
<pre><code class="language-bash">tmux -2 -S /tmp/pair attach-session -t PairProgramming
</code></pre>
<p>The navigator will now be able to see the same terminal session as the driver.
Both users can interact with the session in real-time.</p>
<h3>Alternatives to consider</h3>
<p>If you're working in different environments or need more advanced features
(like a graphical interface or more robust collaborative tools), consider using other solutions
such as <a href="https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare">VS Code's Live Share</a>
feature or cloud-based IDEs.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="xp" /><category term="pair-programming" /><category term="tmux" />
    </entry>

    <entry>
      <title><![CDATA[Replacing Selenium with Poltergeist]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2012/06/14/replacing-selenium-by-poltergeist?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-06-14T12:13:15.000Z</published>
      <updated>2026-03-20T08:30:00.000Z</updated>
      <id>https://www.lucascaton.com/2012/06/14/replacing-selenium-by-poltergeist</id>
      <content type="html" xml:base="https://www.lucascaton.com/2012/06/14/replacing-selenium-by-poltergeist">
        <![CDATA[<div xml:lang="en"><p><figure><img src="https://www.lucascaton.com/images/posts/2012/06/Poltergeist.jpg" alt="Poltergeist movie poster" width="362" height="488" /><figcaption>Poltergeist movie poster</figcaption></figure></p>
<p>My friend <a href="https://twitter.com/pellegrino">@pellegrino</a> gave me an awesome tip: replace <a href="http://seleniumhq.org/">Selenium</a> with <a href="https://github.com/jonleighton/poltergeist">Poltergeist</a>. For those who don't know, <strong>Poltergeist</strong> is a <a href="http://phantomjs.org/">PhantomJS</a> driver for Capybara. I've done it in a few projects and it works very well!</p>
<p><aside>NOTE: Poltergeist project has been discontinued in 2020.</aside></p>
<p>In order to do it, include the gem to your <code>Gemfile</code>:</p>
<pre><code class="language-ruby">gem "poltergeist"
</code></pre>
<p>Update your Capybara configuration:</p>
<pre><code class="language-ruby">Capybara.configure do |config|
  # config.javascript_driver = :selenium
  config.javascript_driver = :poltergeist
end
</code></pre>
<p>Run the specs!</p>
<p>If you are testing some <code>confirm()</code> JavaScript method and you have a code similar to <code>page.driver.browser.switch_to.alert.accept</code>, you'll get this error:</p>
<pre><code class="language-ruby">undefined method `switch_to`
</code></pre>
<p>While I was trying to fix it, I <a href="https://github.com/jonleighton/poltergeist/issues/80#issuecomment-6237980">found out</a> that Poltergeist always returns <code>true</code> from <code>window.confirm</code>.
There's no way (at the moment) to make it return <code>false</code>, but at least it won't prevent your test from passing: all I had to do was to remove that particular line and it solved the issue.</p>
<p>This is the results from the first project I've migrated:</p>
<ul>
<li>Before: <code>Finished in 1 minute 35.45 seconds</code></li>
<li>After: <code>Finished in 41.03 seconds</code></li>
</ul>
<p>Hope you find it helpful as I did!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="tdd" /><category term="bdd" /><category term="selenium" /><category term="poltergeist" /><category term="capybara" />
    </entry>

    <entry>
      <title><![CDATA[[Off-topic] O grande problema e a grande solução da OpenEnglish]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/05/22/off-topic-o-grande-problema-e-a-grande-solucao-da-openenglish?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-05-22T13:54:35.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/05/22/off-topic-o-grande-problema-e-a-grande-solucao-da-openenglish</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/05/22/off-topic-o-grande-problema-e-a-grande-solucao-da-openenglish">
        <![CDATA[<div xml:lang="pt-BR"><p><img src="/images/posts/2012/05/book_guide_hero_books.png" alt="book_guide_hero_books-284x300"></p>
<p>Não costumo escrever posts "off-topic" no meu blog, mas esse assunto mereceu um.</p>
<p>Eu estava há um tempo procurando um curso de inglês que me possuísse um horário flexível. Atualmente, existem vários cursos on-line que resolvem este problema. A OpenEnglish - uma empresa da Venezuela que chegou há poucos meses no Brasil - aparentemente cumpria bem essa tarefa. Resolvi experimentar!</p>
<p>Fiz minha matrícula ontem e de cara fiquei decepcionado, enfrentando 3 problemas complicados, os quais me fizeram desacreditar do curso na mesma hora. A matrícula foi absurdamente simples: em menos de 5 minutos eles me explicaram tudo, passei meus dados, incluindo cartão de crédito, do qual foi devidamente cobrado e a transação aprovada.</p>
<p>Antes da atendente desligar, ela me informou que um consultor pessoal iria entrar em contato no mesmo dia para me explicar algumas coisas. Eu podia optar a forma que ele entraria em contato: telefone ou e-mail. Escolhi telefone e fiquei aguardando. Recebi uns 4 e-mails, dois deles contendo praticamente a mesma informação, o que foi meio confuso. E aí veio o primeiro problema:</p>
<p><strong>O consultor não ligou!</strong> Pois é. Depois que eles cobram parece que deixam você de lado. Como estava muito ocupado durante o dia todo, não me esquentei muito com isso, uma vez que achei que não fosse precisar dele. Pensei: "Amanhã eu eu mesmo ligo lá pra procurar o tal consultor".</p>
<p>Mas como eu queria começar ontem mesmo o curso, tentei entrar no site e o segundo problema apareceu: <strong>eu não consegui completar o cadastro inicial.</strong> No formulário inicial, quando eu clicava no botão de submit, meu telefone não era considerado válido. Simplemente aparecia o erro: <em>"Phone number is required"</em>. O mais bizarro é que pra entrar nesse formulário, eu clicava em um link que eles haviam me mandado por e-mail, e o campo de telefone já vinha preenchido. Testei dois browsers: 'Google Chrome' e o 'Mozilla Firefox'. Fail nos dois navegadores :(</p>
<p>Como cada aula começa em hora inteira (21h00, 22h00, etc) e eu pretendia fazer a aula das 23h00, acabei perdendo esta primeira aula. Inadmissível perder a aula por um motivo idiota desses, não?! :(</p>
<p>Pra tentar resolver isso, <strong>tentei ligar no suporte, mas aí a coisa ficou pior</strong>. Ligando lá, essas eram as opções da URA:</p>
<ul>
<li>[1] Venda de cursos</li>
<li>[2] Atendimento ao cliente</li>
<li>[3] Consultor pessoal</li>
<li>[4] Departamento de cobrança</li>
<li>[5] Suporte técnico</li>
<li>[6] Outras informações</li>
</ul>
<p>Selecionando as opções 2, 5 ou 6, escutava uma gravação exatamente assim: <em>"Nosso horário de atendimento é de segunda à sábado, das 10h da manhã às 12h da noite"</em>.</p>
<p>Primeiro erro que me incomodou: 12h da noite? WTF? Mas o pior problema mesmo é que eram 23h, ou seja, deveria ter alguém lá pra me atender.
Selecionei a opção 3, mas a URA solicita um código de 3 dígitos do consultor pessoal.</p>
<p>Como NENHUM consultor ainda havia entrado em contato, eu não possuia o tal código.
Selecionei a opção 4 pra ver no que dava. Escutei uma música de espera com informações em espanhol (WTF?) por alguns minutos e notei que não estava sendo transferido pra lugar algum.</p>
<p>Por último, tentei ainda selecionar a opção 1, que é a de vendas, mas a gravação dizia que essa opção só está disponível até às 21h.
Tive que esperar até o dia seguinte (hoje) pelas soluções. <strong>Mas me sinto mais que na obrigação de comentar como eles me surpreenderam!</strong></p>
<p>Hoje de manhã minha consultora pessoal ligou e explicou que o prazo de ligação do consultor é de 24 horas e não no mesmo dia que eu fiz a matrícula.
Ela foi super atenciosa, pediu pra eu abrir o site e me mostrou cada ferramenta disponível lá, tirando todas as minhas dúvidas. Explicou que o formulário inicial realmente estava com problema, mas que já haviam resolvido.</p>
<p>E sobre o horário do suporte, ela disse que era até às 21h e que a URA provavelmente seria atualizada em breve com o novo horário de atendimento.</p>
<p><strong>Fiquei super satisfeito. Eles conseguiram melhorar a péssima imagem que criei deles ontem!</strong></p>
<p>Às 22h, resolvi tentar uma "Live Session", que são aulas ao vivo, com professores nativos, os quais <strong>não</strong> falam português se você estiver no nível intermediário ou superior.</p>
<p>O sistema deles é de fato muito bom, são conferências em audio, com slides interativos, onde os professores vão fazendo anotações nos slides em tempo real.</p>
<p>Além disso, cada aula tem no máximo 5 alunos, o que considero excelente. O sistema usado para a conferência, durante os 50 minutos de aula, funcionou perfeitamente.</p>
<p>Vale citar que tanto o sistema quanto o site funcionam em qualquer Sistema Operacional (Windows, Linux e <del>OS X</del> macOS) e em qualquer browser.</p>
<p>No final de cada aula, existe uma lista de apostilas, artigos, vídeos, podcasts, entre outras atividades relacionadas à esta aula específica. Então o professor recomenda as atividades mais adequadas para cada aluno, de acordo com a dificuldade que ele teve durante a aula.</p>
<p>Sensacional, estou bastante satisfeito.
E seria injusto eu não contar essa história depois de reclamar tanto ontem :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="off-topic" /><category term="ingles" /><category term="english" /><category term="cursos" />
    </entry>

    <entry>
      <title><![CDATA[My dotfiles]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2012/04/29/my-dotfiles?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-04-29T12:11:02.000Z</published>
      <updated>2026-03-20T09:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2012/04/29/my-dotfiles</id>
      <content type="html" xml:base="https://www.lucascaton.com/2012/04/29/my-dotfiles">
        <![CDATA[<div xml:lang="en"><p><figure><img src="https://www.lucascaton.com/images/posts/2012/04/my-dotfiles.jpg" alt="" width="1280" height="720" /><figcaption></figcaption></figure></p>
<p><strong>Dotfiles</strong> are configuration files that live in your home directory (<code>~/</code>), usually prefixed with a dot (making them hidden by default). They control how your shell, editor, Git, and countless other tools behave.</p>
<p>Over the years, I've built up a collection of mine into a single, open-source repository. It covers everything from shell customization and Git configuration to editor settings, language version management, custom scripts, and more. The specific tools evolve over time, but the goal stays the same: <strong>have a reproducible, portable development environment that I can set up on any machine with a single command.</strong></p>
<p>The repository is open source - feel free to browse it, fork it, or cherry-pick anything useful for your own setup:</p>
<p><a href="https://github.com/lucascaton/dotfiles" target="_blank" rel="noopener noreferrer">github.com/lucascaton/dotfiles</a></p>
<p>Keeping dotfiles in version control has been one of the best decisions I've made as a developer. It means I never lose a configuration tweak, I can experiment freely knowing I can always roll back, and spinning up a new machine goes from hours of setup to minutes.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="dotfiles" />
    </entry>

    <entry>
      <title><![CDATA[Regex to match YouTube URLs (using Ruby)]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2012/04/10/regex-to-match-youtube-urls-using-ruby?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-04-10T01:19:34.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2012/04/10/regex-to-match-youtube-urls-using-ruby</id>
      <content type="html" xml:base="https://www.lucascaton.com/2012/04/10/regex-to-match-youtube-urls-using-ruby">
        <![CDATA[<div xml:lang="en"><p>I've created a regular expression to match YouTube URLs.
As YouTube URLs start with <code>https://youtube.com</code> and <code>https://youtu.be</code>, the following regex solves the problem:</p>
<pre><code class="language-ruby">/^(?:https?:\/\/)?(?:www\.)?youtu(?:\.be|be\.com)\/(?:watch\?v=)?([\w-]{10,})/
</code></pre>
<p>This regex will match:</p>
<ul>
<li><code>http://youtube.com/watch?v=1234567890</code></li>
<li><code>https://youtube.com/watch?v=1234567890</code></li>
<li><code>http://www.youtube.com/watch?v=1234567890</code></li>
<li><code>http://www.youtube.com/watch?v=12345-67890</code></li>
<li><code>https://www.youtube.com/watch?v=1234567890</code></li>
<li><code>http://youtu.be/1234567890</code></li>
<li><code>https://youtu.be/1234567890</code></li>
<li><code>http://www.youtu.be/1234567890</code></li>
<li><code>https://www.youtu.be/1234567890</code></li>
<li><code>http://www.youtube.com/watch?v=1234567890&#x26;feature=context&#x26;context=G2de15aaFAAAAAAAAAAA</code></li>
<li><code>www.youtube.com/watch?v=1234567890</code></li>
<li><code>youtube.com/watch?v=1234567890</code></li>
<li><code>youtu.be/1234567890</code></li>
</ul>
<p>But it won't match:</p>
<ul>
<li><code>youtube.com</code></li>
<li><code>youtube.com/</code></li>
<li><code>youtube.com/watch</code></li>
<li><code>youtube.com/watch/</code></li>
<li><code>youtu.be</code></li>
<li><code>youtu.be/</code></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="regex" /><category term="youtube" /><category term="regexp" />
    </entry>

    <entry>
      <title><![CDATA[Novos desafios]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/03/05/novos-desafios?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-03-05T01:06:49.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/03/05/novos-desafios</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/03/05/novos-desafios">
        <![CDATA[<div xml:lang="pt-BR"><p>Próximo de completar um ano que me mudei pra São Paulo, recebi um convite que acabou mudando as coisas mais uma vez. Passei quase um ano trabalhando na <strong>Bio Ritmo</strong>, onde tive uma experiência única de trabalhar com toda a equipe de tecnologia, onde fiz grandes amigos e onde aprendi muito.</p>
<p>Há mais ou menos um mês, recebi um convite para trabalhar em um tipo de empresa que até então eu não havia trabalhado: uma empresa de consultoria. Foi um convite que acompanhou uma decisão bastante difícil. Mas eu acreditava que era hora de mudar algumas coisas. E foi assim que eu comecei a trabalhar na <a href="http://www.codeminer42.com/"><strong>Codeminer 42</strong></a>.</p>
<p>Hoje completa uma semana que comecei a trabalhar lá. E acredito ter tomado a decisão correta. Os desafios são grandes, os projetos são bacanas, o ambiente é descontraído e a equipe é muito boa e unida. Uma ótima forma de você aprender bastante é trabalhando com pessoas melhores que você e lá estou tendo esta oportunidade.</p>
<p>Uma coisa interessante é que em uma consultoria você trabalha em vários projetos (não necessariamente em paralelo) e isso permite que você use diferentes ferramentas e aprenda qual a melhor para cada tipo de problema (<em>"there is no silver bullet"</em>). Ou ainda, testar diferentes ferramentas para uma mesma solução.</p>
<p>Um obrigado especial ao <a href="https://twitter.com/rinaldifonseca">Rinaldi Fonseca</a>, que me convidou para trabalhar com esse ótimo time!</p>
<p><strong>Hora de seguir em frente nessa nova empreitada!</strong></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="carreira" />
    </entry>

    <entry>
      <title><![CDATA[Como aprendi a fazer Dojo com o pessoal da Lambda3]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/02/15/como-aprendi-a-fazer-dojo-com-o-pessoal-da-lambda3?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-02-15T08:22:56.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/02/15/como-aprendi-a-fazer-dojo-com-o-pessoal-da-lambda3</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/02/15/como-aprendi-a-fazer-dojo-com-o-pessoal-da-lambda3">
        <![CDATA[<div xml:lang="pt-BR"><p>Tive o prazer de participar em janeiro de um Coding-Dojo com o pessoal da empresa <a href="http://www.lambda3.com.br/"><strong>Lambda3</strong></a>, organizada pelo grande <a href="https://twitter.com/rafaelrosafu"><strong>Rafael Rosa Fu</strong></a>!</p>
<p>Embora exista mais de uma forma de fazer, acho que o jeito que fizemos funcionou muito bem. Vou explicar como fizemos:</p>
<h2>Seleção de problemas</h2>
<p>O organizador seleciona 3~5 problemas de alguma lista de problemas de programação (como o <a href="http://www.rubyquiz.com/"><strong>Ruby Quiz</strong></a>, por exemplo). Quando começar o Dojo, ele apresenta um resumo dos problemas e faz uma votação para escolher um problema.</p>
<h2>Foco!</h2>
<p>Apenas um computador é necessário, isso ajuda a manter todos focados no problema. A pessoa mais próxima do computador começa sendo o "piloto", escrevendo o código inicial. A pessoa à esquerda do "piloto" será o "co-piloto" e sua função é ajudar o "piloto".</p>
<h2>Troca de posições</h2>
<p>A cada 7 minutos (ou algum outro tempo pré-determinado que for adequado), todos trocam de lugar: a pessoa à esquerda do "co-piloto" se torna o novo "co-piloto", o "co-piloto" agora começa a "pilotar" (programar) e o atual "piloto" entra no final da fila. Isso se repete até o final do Dojo.</p>
<h2>TDD / BDD</h2>
<p>Todo o desenvolvimento é orientado à testes, avançando através de baby steps. Quando testes estiverem falhando ("fase vermelha"), ninguém pode comentar nem sugerir nada, exceto o "co-piloto". Obviamente, quando os testes estiverem passando ("fase verde") todos podem comentar e sugerir implementações e refatorações.</p>
<h2>Retrospectiva</h2>
<p>No final, é interessante fazer uma retrospectiva, onde todos os desenvolvedores escrevem em post-its verdes coisas boas que aconteceram durante o Dojo e coisas ruins em post-its vermelhos.</p>
<p>O organizador recolhe os post-its e os cola num quadro, separado por tipo/cor. Depois de ler em voz alta todos os post-its, é interessante reservar uma área "Discussões" no quadro, para anotar discussões que ocorrerem durante e no final do Dojo.</p>
<p>Isso tudo é importante para não repetir os erros do Dojo atual no próximo e deixar claro o que foi acertado.</p>
<h2>Referências</h2>
<p>Segue um link dos slides do Serge Rehen sobre Coding-Dojo: <a href="http://www.slideshare.net/serge_rehem/coding-dojo-em-5-minutos">http://www.slideshare.net/serge_rehem/coding-dojo-em-5-minutos</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="dojo" />
    </entry>

    <entry>
      <title><![CDATA[Minha palestra sobre Ruby on Rails no "Café com Java"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/02/12/minha-palestra-sobre-ruby-on-rails-no-cafe-com-java?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-02-12T11:01:13.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/02/12/minha-palestra-sobre-ruby-on-rails-no-cafe-com-java</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/02/12/minha-palestra-sobre-ruby-on-rails-no-cafe-com-java">
        <![CDATA[<div xml:lang="pt-BR"><p>Ontem aconteceu mais um <a href="http://www.guj.com.br/t/cafe-com-java/255200">encontro do evento "Café com Java"</a>,
organizado pelo <a href="https://twitter.com/bregaida">Eduardo Bregaida</a>,
que foi inclusive quem me convidou para palestrar :)</p>
<p>Eu falei sobre as vantagens de usar <strong>Ruby on Rails</strong> em comparação com o Java:</p>
<p><a href="https://www.youtube.com/watch?v=BsJkkAxoXWE"><img src="https://i.ytimg.com/vi_webp/BsJkkAxoXWE/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Um obrigado especial à minha namorada <a href="https://twitter.com/alinecaton">Aline</a>, por filmar minha apresentação! :)</p>
<h2>Slides</h2>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/JrS5YTABbeqRQE" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen></iframe>
<h2>Fotos</h2>
<p><img src="/images/posts/2012/02/img1.png" alt=""></p>
<p><img src="/images/posts/2012/02/img2.png" alt=""></p>
<p><img src="/images/posts/2012/02/6859865873_e6d67f33ca_b.jpg" alt=""></p>
<p><img src="/images/posts/2012/02/6859857577_c93affc816_b.jpg" alt=""></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="palestra" /><category term="apresentacoes" />
    </entry>

    <entry>
      <title><![CDATA[O 1º encontro oficial do [self SP]; foi um sucesso!]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/01/25/o-1o-encontro-oficial-do-self-sp-foi-um-sucesso?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-01-25T06:03:34.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/01/25/o-1o-encontro-oficial-do-self-sp-foi-um-sucesso</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/01/25/o-1o-encontro-oficial-do-self-sp-foi-um-sucesso">
        <![CDATA[<div xml:lang="pt-BR"><p>Depois de 4 meses que criamos o <strong>[self SP]</strong> (grupos de usuários de Objective C), conseguimos realizar o seu primeiro encontro oficial, graças ao <a href="https://twitter.com/fer_bass">@fer_bass</a> (que organizou quase tudo), à <a href="http://poisonlabs.com/">PoisonLabs</a> (que patrocinou o CoffeBreak), à <a href="http://www.caelum.com.br/">Caelum</a> (que liberou o auditório para o evento) e ao <a href="http://www.agaelebe.com.br/">Hugo Borges</a> (que gravou o evento).</p>
<p>Obrigado a todos os palestrantes e aos participantes, foi realmente muito bacana!</p>
<p><img src="/images/posts/2012/01/IMG_1324.jpg" alt="IMG_1324"></p>
<p><img src="/images/posts/2012/01/IMG_1325.jpg" alt="IMG_1325"></p>
<h2>Palestras</h2>
<h4>"OpenGL com GLKit" (xissburg)</h4>
<p><img src="/images/posts/2012/01/IMG_1329.jpg" alt="IMG_1329"></p>
<h4>"CoreGraphics Performance" (Glenn Marcus)</h4>
<p><img src="/images/posts/2012/01/IMG_1331.jpg" alt="IMG_1331"></p>
<h4>"Conhecendo e entendo o ARC" (Ferbass)</h4>
<p><img src="/images/posts/2012/01/IMG_1333.jpg" alt="IMG_1333"></p>
<h4>"Testes automatizados para sua aplicação iOS" (Ricardo Valeriano)</h4>
<p><img src="/images/posts/2012/01/IMG_1335.jpg" alt="IMG_1335"></p>
<h4>"Funcionalidades dinamicas do Objective-C" (Diego Chohfi)</h4>
<p><img src="/images/posts/2012/01/IMG_1341.jpg" alt="IMG_1341"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="eventos" /><category term="ios" /><category term="self-sp" />
    </entry>

    <entry>
      <title><![CDATA[Como acelerar a exibição das suas rotas no Rails]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2012/01/02/como-acelerar-a-exibicao-das-suas-rotas-no-rails?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2012-01-02T01:28:48.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2012/01/02/como-acelerar-a-exibicao-das-suas-rotas-no-rails</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2012/01/02/como-acelerar-a-exibicao-das-suas-rotas-no-rails">
        <![CDATA[<div xml:lang="pt-BR"><p>Procurando uma forma de acelerar o comando <code>rake routes</code>, encontrei uma gem interessante: <a href="https://github.com/bcaccinolo/routes">routes</a>.</p>
<p>Ela cria um cache da saída do comando e renova o conteúdo automaticamente quando você atualiza o arquivo <code>config/routes.rb</code>.</p>
<p>Não é necessário incluir a gem no <code>Gemfile</code> do projeto, basta incluir o diretório oculto <code>/.routes</code> no <code>.gitignore</code>.</p>
<p>Como sempre, rode <code>gem install routes</code> para instalar e apenas <code>routes</code> para vê-lo em ação.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="rails" /><category term="routes" />
    </entry>

    <entry>
      <title><![CDATA[4 coisas que eu gostaria que a Apple implementasse no iOS]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/12/26/4-coisas-que-eu-gostaria-que-a-apple-implementasse-no-ios?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-12-26T00:24:48.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/12/26/4-coisas-que-eu-gostaria-que-a-apple-implementasse-no-ios</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/12/26/4-coisas-que-eu-gostaria-que-a-apple-implementasse-no-ios">
        <![CDATA[<div xml:lang="pt-BR"><ul>
<li>Permitir mais de uma <strong>assinatura</strong> para e-mails (atualmente só é possível criar uma única
assinatura);</li>
<li>Tranferência de fotos e vídeos via <strong>bluetooth</strong> (qualquer celular atualmente faz isso);</li>
<li>Permitir a inclusão de imagens ou vídeos dentro do app <strong>Mail</strong> (atualmente você precisa abrir a
foto ou vídeo e selecionar a opção que manda por e-mail);</li>
<li>Acessar de forma mais prática algumas <strong>configurações</strong>, como por exemplo ativar/desativar o 3G.</li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="apple" /><category term="iOS" />
    </entry>

    <entry>
      <title><![CDATA[Vídeo: 17 dicas para o Vim]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/12/13/screencast-1-17-dicas-para-o-vim?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-12-13T01:00:00.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/12/13/screencast-1-17-dicas-para-o-vim</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/12/13/screencast-1-17-dicas-para-o-vim">
        <![CDATA[<div xml:lang="pt-BR"><p>Finalmente terminei o primeiro <em>screencast</em> do meu site. Espero que gostem! :)</p>
<p><a href="https://www.youtube.com/watch?v=DyUq81mXCVA"><img src="https://i.ytimg.com/vi_webp/DyUq81mXCVA/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Por favor, mandem feedback do que acharam!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="vim" /><category term="videos" />
    </entry>

    <entry>
      <title><![CDATA[Como ordenar linhas no Vim]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/12/03/como-ordernar-linhas-no-vim?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-12-03T01:51:05.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/12/03/como-ordernar-linhas-no-vim</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/12/03/como-ordernar-linhas-no-vim">
        <![CDATA[<div xml:lang="pt-BR"><h2>Comando sort - ordenar linhas</h2>
<p>Algo que todo mundo que usa o editor Vim provavelmente conhece é o comando <code>sort</code>.
Ele ordena alfabeticamente as linhas de seu texto/código.</p>
<p>Você também pode selecionar algumas linhas e ordenar apenas essas.
Para isso, pressione <strong>shift</strong> + <strong>v</strong> para entrar no modo de seleção por linha, depois rode <code>:'&#x3C;,'>sort</code>.</p>
<h2>Comando sort u - ordenar linhas excluindo as repeditas</h2>
<p>Algo que também uso muito é o parâmetro <code>u</code>, que permite ordenar as linhas, mas excluindo as repetidas:</p>
<p>Antes:</p>
<pre><code>Lucas
Lucas
Lucas
Caton
Caton
</code></pre>
<p>Depois de rodar o comando <code>:sort u</code>:</p>
<pre><code>Caton
Lucas
</code></pre>
<h2>Comando sort /regex/ - ordenar linhas utilizando alguma coluna</h2>
<p>E hoje aprendi mais uma coisa realmente interessante ao ordenar um arquivo: como ordenar um texto usando alguma coluna:</p>
<p>Imagine o seguinte texto:</p>
<pre><code>36993 vim 26M
39140 ssh 10M
34551 bash 17M
</code></pre>
<p>Nosso objetivo é ordenar pela terceira coluna. Para isto, basta rodar o comando <code>sort</code> passando uma expressão regular como parâmetro, a qual representará o que será ignorado pelo vim até começar a ordenação, ou seja, a partir da coluna que a expressão regular não "casar" mais, ele começará a ordenar. Sendo assim:</p>
<pre><code>:sort /.\+\s.\+\s/
</code></pre>
<p>Essa expressão regular casa com <code>qualquer caracter em qualquer quantidade</code> + <code>um espaço</code> + <code>qualquer caracter em qualquer quantidade</code> + <code>um espaço</code>, conforme representado pela parte destacada abaixo:</p>
<pre><code>36993 vim 26M
39140 ssh 10M
34551 bash 17M
</code></pre>
<p>O conteúdo <strong>depois</strong> disso será a chave para a ordenação.</p>
<p>Resultado:</p>
<pre><code>39140 ssh 10M
34551 bash 17M
36993 vim 26M
</code></pre>
<p>Se quiséssemos ainda ordenar pela segunda coluna:</p>
<pre><code>sort /\d\{5\}\s/
</code></pre>
<p>Bom, é isso! Qualquer dúvida, postem nos comentários!</p>
<p>E se quiserem aprender mais sobre expressões regulares, confira essa <a href="https://www.lucascaton.com/2011/11/12/minha-apresentacao-sobre-expressoes-regulares">minha apresentação</a> sobre o assunto! :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="vim" />
    </entry>

    <entry>
      <title><![CDATA[O que eu uso pra me organizar]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/11/14/o-que-eu-uso-pra-me-organizar?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-11-14T00:11:36.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/11/14/o-que-eu-uso-pra-me-organizar</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/11/14/o-que-eu-uso-pra-me-organizar">
        <![CDATA[<div xml:lang="pt-BR"><p>Vou listar as ferramentas que uso diariamente pra me organizar e proteger meus dados.</p>
<p>Confesso que eu já perdi dados importantes no passado (com quem nunca aconteceu?) e isso acabou me deixando neurótico com <em>backups</em>.</p>
<h1>Agenda de contatos</h1>
<p>Pra começar, como minha agenda de contatos não ficava na nuvem e já perdi ela quando trocava / perdia celular, acabei usando por muito tempo uma agenda de papel. Eu sei, é muito estranho, mas eu me sentia seguro. De um tempo pra cá, a substituí pela <strong>agenda de contatos da Apple</strong> (presente no <del>OS X</del> macOS e no meu iPod Touch), sincronizados pelo iCloud (e backup lá também). òbvio que armazenar essas informações eletrônicamente é infinitamente mais vantajoso. Guardo fotos dos contatos, vários e-mails, telefones, usuário do twitter, endereço, etc.</p>
<p><img src="/images/posts/2011/11/contacts.png" alt="contacts"></p>
<h1>Agenda de compromissos</h1>
<p>Assim como minha agenda de contatos, eu também usei por muitos anos uma agenda de papel. Mas finalmente me desapeguei e não comprei uma agenda 2012. Substitui esta por dois softwares, os quais estão me atendendo muito bem:</p>
<p><strong>iCal</strong>: Onde anoto todas os compromissos, os importantes com avisos sonoros e avisos por e-mail, também sincronizados entre o Mac e o iPod Touch via iCloud; e <strong>Wunderlist</strong>: que é um software para listar as coisas que você precisa fazer em determinado dia, no estilo "TO-DO list". Ele possui versão web, versão pra macOS e versão para iOS. Outra coisa que me fez gostar ainda mais é a possibilidade de editar / criar tudo offline no iPod Touch (já que eu não tenho 3G) e sincronizar tudo depois, quando estiver numa rede wi-fi.</p>
<p><img src="/images/posts/2011/11/ical.png" alt="ical"></p>
<p><img src="/images/posts/2011/11/wunderlist.png" alt="wunderlist"></p>
<p>Algumas tarefas ainda estão no <strong>Google Calendar</strong> (como aniversários e tarefas recorrentes, ambos com avisos por e-mail). Estou migrando estas aos poucos para o <strong>iCal</strong>.</p>
<h1>Leitor de feeds RSS</h1>
<p>Uso o <strong>Google Reader</strong> desde 2005 e funciona perfeitamente bem, nunca tive nenhum tipo de problema com ele. Atualmente tenho 175 subscriptions e leio aproximadamente 70% dos items de lá (dependendo se o título me interessar ou não). Uso bastante o recurso "starred" para selecionar os item que quero ler depois, quando não posso ler no momento. Uso bastante o recurso de envio de post por e-mail, pra comparilhar com quem possa interesar.</p>
<p><img src="/images/posts/2011/11/greader.png" alt="greader"></p>
<h1>Bookmarks</h1>
<p>Depois de muito tempo usando o <strong>Delicious</strong>, o abandonei e comecei a usar o <strong>Google bookmarks</strong>. Uso uma extension do Google Chrome pra adicionar item lá e uso com frequência pra me lembrar de páginas que já visitei e eram úteis em potencial.</p>
<p><img src="/images/posts/2011/11/google-bookmarks.png" alt="google-bookmarks"></p>
<h1>Anotações em geral</h1>
<p>Em 90% dos casos, uso o <strong>Evernote</strong>, software para o macOS e iOS. Nos outros 10%, uso papel e caneta apenas, o que às vezes é insubstituível.</p>
<p><img src="/images/posts/2011/11/evernote.png" alt="evernote"></p>
<h1>Armazenamento de senhas</h1>
<p>Utilizo o <strong>LastPass</strong>, que possui uma extension pra todos os browsers atuais e em geral funciona bem. Uma vez tive um problema com ele, mas o pessoal do LastPass entrou em contato comigo em poucos minutos pra resolver meu problema (e olha que eu uso a versão free!).</p>
<p><img src="/images/posts/2011/11/lastpass.png" alt="lastpass"></p>
<h1>Repositório de projetos</h1>
<p>Meus projetos open-source ficam no <strong>Github</strong>, o qual tem ótimos recursos e boa usabilidade. Já meus projetos fechados ficam no <strong>Codebase</strong>, o qual gosto bastante, uma vez que além de servir como repositório git, também consigo gerenciar o projeto de forma integrada, criando tickets, milestones, atribuindo tarefas para usuários, configurando prioridades, etc.</p>
<p><img src="/images/posts/2011/11/github.png" alt="github"></p>
<p><img src="/images/posts/2011/11/codebase.png" alt="codebase"></p>
<h1>Controle de contas ($)</h1>
<p><del>Até hoje não achei um software que me atendesse 100%, o que me obriga até hoje a usar uma planílha salva no <strong>Google Docs</strong>.</del></p>
<p><a href="https://www.easybills.io/?locale=pt-BR">Easy Bills</a> \o/</p>
<h1>Redes sociais</h1>
<p>Uso <strong>Facebook</strong>, <strong>Google+</strong> e <strong>Twitter</strong>, mas não me comprometo a ler tudo que aparece por lá. O que mais uso, sem dúvidas, é o Twitter, e como a maior parte das pessoas que eu sigo são programadores, uso com o objetivo de me atualizar, descobrir e compartilhar coisas relacionadas à desenvolvimento de software.</p>
<h1>Lembretes rápidos</h1>
<p>Não tem como fugir. Vez ou outra, mando um e-mail pra mim mesmo com alguma tarefa rápida pra lembrar depois. A propósito, uso o <strong>Gmail</strong> desde 2004 e organizo com os labels e filtros que o serviço oferece, além da Priority Inbox (Caixa de entraga prioritária).</p>
<h1>Backups</h1>
<p>Como eu já falei, sou meio neurótico com backups:</p>
<p><img src="/images/posts/2011/11/hd.png" alt="hd"></p>
<ul>
<li>Faço um backup dirário de todo conteúdo do meu Mac em um HD externo. Como trabalho com o Mac, levando ele diáriamente para o escritório, fiz seguro deste também!</li>
<li>A cada 6 meses faço um backup das coisas mais importantes em DVDs (uso aproximadamente 6 discos) e pra eu não esquecer, o Google Calendar me manda um e-mail semestral avisando: <code>Você precisa fazer um backup semestral em DVDs :)</code>.</li>
</ul>
<p>Mensalmente, faço backups dos seguintes items:</p>
<ul>
<li>Subscribes do Google Reader</li>
<li>Address Book da Apple (além de já ter um backup no iCloud)</li>
<li>LastPass</li>
<li>iCal (além de também já ter um backup no iCloud)</li>
</ul>
<p>Compartilhem o que vocês usam também!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="softwares" /><category term="ferramentas" /><category term="organizacao-pessoal" />
    </entry>

    <entry>
      <title><![CDATA[Minha apresentação sobre Expressões Regulares]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/11/12/minha-apresentacao-sobre-expressoes-regulares?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-11-12T12:15:21.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/11/12/minha-apresentacao-sobre-expressoes-regulares</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/11/12/minha-apresentacao-sobre-expressoes-regulares">
        <![CDATA[<div xml:lang="pt-BR"><p>Aproximadamente 5 meses depois da <a href="https://www.lucascaton.com/2011/06/01/slides-bio-labs-1-por-que-testar-e-importante-e-algumas-boas-praticas">minha primeira apresentação no Bio Labs</a>, realizei recentemente outra, sobre <strong>Expressões Regulares</strong>.</p>
<p><img src="/images/posts/2011/11/post.jpg" alt="post"></p>
<p>Nessa <em>tech talk</em>, eu falei sobre alguns mitos relacionados à <strong>Expressões Regulares</strong>, ensinei o básico de como ler e escrever <em>regex</em>, para que servem os metacaracteres, onde posso usar, em que caso pode me ser útil, etc.</p>
<p>Dessa vez foi filmado, embora a qualidade não tenha ficado muito boa (a iluminação fica ruim às vezes).
Segue o vídeo da apresentação e os slides:</p>
<p><a href="https://www.youtube.com/watch?v=VAaRjIbE09g"><img src="https://i.ytimg.com/vi_webp/VAaRjIbE09g/maxresdefault.webp" alt="YouTube video" /></a></p>
<hr>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/fFazBM1FP2ejZu" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen></iframe>
<p>Me mandem feedback comentando o que acharam!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="palestras" /><category term="apresentacoes" /><category term="tech-talks" /><category term="slides" /><category term="regex" /><category term="biolabs" />
    </entry>

    <entry>
      <title><![CDATA[RubyConfBR 2011]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/11/06/rubyconfbr-2011?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-11-06T08:46:56.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/11/06/rubyconfbr-2011</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/11/06/rubyconfbr-2011">
        <![CDATA[<div xml:lang="pt-BR"><p>O evento foi sensacional. Além de ótimas palestras (nacionais e internacionais), rolou um stand-up com <strong>Danilo Gentili</strong> e um reencontro muito bacana com vários amigos da comunidade Ruby!</p>
<p>Mais uma vez parabéns ao <a href="http://akitaonrails.com/">Fábio Akita</a> e um obrigado especial à <a href="http://www.bioritmo.com.br">Bio Ritmo</a> por apoiar os desenvolvedores, não apenas nos liberando nos dois dias do evento como também bancando nossa inscrição :)</p>
<p>E que venha a <strong>RubyConfBR 2012</strong>!</p>
<p><img src="/images/posts/2011/11/Screen-Shot-2011-11-06-at-7.42.14-PM.png" alt="RubyConfBR logo"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="eventos" /><category term="rubyconf" /><category term="rubyconfbr" />
    </entry>

    <entry>
      <title><![CDATA[Como editar queries SQL com um editor de textos no console do PostgreSQL]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/10/16/como-editar-queries-sql-com-um-editor-de-textos-no-console-do-postgresql?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-10-16T01:02:36.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/10/16/como-editar-queries-sql-com-um-editor-de-textos-no-console-do-postgresql</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/10/16/como-editar-queries-sql-com-um-editor-de-textos-no-console-do-postgresql">
        <![CDATA[<div xml:lang="pt-BR"><p>Essa dica é pra quem usa <strong>PostgreSQL</strong> e quer editar suas queries dentro de algum editor de texto sem sair do console do banco de dados.
Isso é especialmente útil quando você precisa rodar uma query complexa diretamente no console.</p>
<p>Primeiramente, verique qual é o seu editor de textos configurado na variável de ambiente <code>EDITOR</code>:</p>
<pre><code class="language-bash">$ echo $EDITOR
# vim
</code></pre>
<p>No meu caso, meu editor padrão é o <strong>Vim</strong>.
Se você não tiver nenhum editor configurado, basta inclur a seguinte linha no seu arquivo <code>~/bash_profile</code>:</p>
<pre><code class="language-bash">export EDITOR=vim
</code></pre>
<p>Depois, abra o console do PostgreSQL (<code>psql</code>) e digite <code>\e</code> para que você possa digitar as queries SQL de forma mais confiante e organizada no seu editor preferido:</p>
<pre><code class="language-bash">$ psql
# psql (9.0.4)
# Type "help" for help.
database_name=# \e
</code></pre>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="postgresql" /><category term="vim" /><category term="database" />
    </entry>

    <entry>
      <title><![CDATA[pushd e popd]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/09/19/pushd-e-popd?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-09-18T23:21:19.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/09/19/pushd-e-popd</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/09/19/pushd-e-popd">
        <![CDATA[<div xml:lang="pt-BR"><p>Estava lendo <a href="http://cokencode.com/configurando-profile-para-rvm">esse post</a> do <a href="https://twitter.com/rafaelsachetto">Rafael Sachetto</a>, quando encontrei dois comandos que não conhecia: <code>pushd</code> e <code>popd</code>.</p>
<p>Fui pesquisar o que era e descobri dois substitutos para o comando <code>cd</code> (quem diria?!).
Ao ir usando o comando <code>pushd &#x3C;directory></code>, ele vai montando uma pilha (aka. estrutura de dados do tipo pilha) com todos os diretórios pelos quais vocês vai "passando".</p>
<p>Depois, à medida que você digita o comando <code>popd</code>, ele vai retornando a todos os diretórios, usando essa pilha como guia.</p>
<p>Seria algo como um <code>cd -</code> (que volta ao diretório anterior), só que sem limites para retorno.</p>
<p>Por exemplo:</p>
<pre><code class="language-bash">cd ~
$ pwd # ~
$ pushd Pictures
$ pwd # ~/Pictures
$ pushd PSD
$ pwd # ~/Pictures/PSD
$ popd
$ pwd # ~/Pictures
$ popd
$ pwd # ~
</code></pre>
<p>Se quiser ver todos os diretórios da pilha, use o comando <code>dirs</code>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="pushd" /><category term="popd" /><category term="dirs" />
    </entry>

    <entry>
      <title><![CDATA[Windows Store - mais uma coisa que a M$ copiou]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/09/14/windows-store-mais-uma-coisa-que-a-m-copiou?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-09-14T04:07:18.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/09/14/windows-store-mais-uma-coisa-que-a-m-copiou</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/09/14/windows-store-mais-uma-coisa-que-a-m-copiou">
        <![CDATA[<div xml:lang="pt-BR"><p>Depois de ler <a href="http://meiobit.com/91521/windows-store-microsoft-far-proposta-que-desenvolvedores-no-podero-recusar-build-2011/">essa matéria do Meio Bit</a>, fiquei indignado. Além de copiar a Apple (mais uma vez), a Micro$oft ainda se diz melhor só porque não irá cobrar comissão nos apps vendidas na loja dela.</p>
<p>A Apple cobra um valor que julgo justo, um valor pelo trabalho que ela faz pensando no desenvolvedor e principalmente no usuário final, tanto para apps para o <del>OS X</del> macOS como pro iOS:</p>
<ul>
<li>Verificação geral do software (se existe memory leaks, se a performance está legal, se o design está adequado, etc.);</li>
<li>Se a app não causa danos à sua máquina ou ao seu dispositivo;</li>
<li>Libera os servidores para você armazenar seu app lá (evitando que você gaste com hosting);</li>
<li>Divulga seu app (reduzingo seus custos com divulgação);</li>
<li>Disponibiliza uma interface pra você gerenciar suas vendas.</li>
</ul>
<hr>
<p>Além disso:</p>
<p>Custo do XCode: US$ 0,00. Documentação online (muito boa): US$ 0,00. Screencasts oficiais (muito bons também): US$ 0,00.
Agora, quanto custa mesmo o Visual Studio? O Windows Server? MSSQL Server?
Então não me venham falar que desenvolver para a Apple é caro.</p>
<p>A menos que você não pague por todas as licenças que a M$ cobra, porque daí a história é outra...</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="opiniao" /><category term="apple" /><category term="microsoft" /><category term="windows-store" /><category term="app-store" />
    </entry>

    <entry>
      <title><![CDATA[[self SP];]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/09/11/self-sp?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-09-11T10:34:22.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/09/11/self-sp</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/09/11/self-sp">
        <![CDATA[<div xml:lang="pt-BR"><p>Depois de alguns dias conversando com o <a href="http://ferbass.com">Ferbass</a> e com o <a href="https://twitter.com/talesp">Tales Pinheiro</a>, finalmente tiramos a idéia do papel e criamos o <a href="http://selfsp.org/">[self SP];</a>, um grupo de usuários da linguagem Objective C, tanto para desenvolvimento para a plataforma iOS quanto para a plataforma <del>OS X</del> macOS.</p>
<p>O objetivo do grupo é agrupar informações relevantes, facilitar o encontro dos usuários e incentivar discussões (saudáveis) sobre o assunto.</p>
<p><strong><a href="http://selfsp.org/">http://selfsp.org/</a></strong></p>
<p>Participe do grupo e nos ajude a divulgar!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ios" /><category term="self-sp" /><category term="objective-c" />
    </entry>

    <entry>
      <title><![CDATA[How to remove several lines in the Vim editor using regex]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2011/09/06/how-to-remove-several-lines-in-the-vim-editor-using-regex?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-09-06T00:31:28.000Z</published>
      <updated>2026-04-03T05:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2011/09/06/how-to-remove-several-lines-in-the-vim-editor-using-regex</id>
      <content type="html" xml:base="https://www.lucascaton.com/2011/09/06/how-to-remove-several-lines-in-the-vim-editor-using-regex">
        <![CDATA[<div xml:lang="en"><p>A quick tip for those who use Vim: if you need to remove several lines that match a regular expression, you can achieve that by running:</p>
<pre><code class="language-vim">:g /pattern/d
</code></pre>
<p>Let's say you want to remove the commented lines from the following file:</p>
<pre><code class="language-ruby"># This is a comment
def foo
end
# This is another comment
def bar
end
</code></pre>
<p>Run <code>:g /^#.*/d</code>, and your code will become:</p>
<pre><code class="language-ruby">def foo
end
def bar
end
</code></pre>
<p>Simple, right? :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="vim" /><category term="regex" />
    </entry>

    <entry>
      <title><![CDATA[Palestra do Cássio Marques no 16º encontro do GuruSP]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/06/25/16-palestra-do-cassio-marques-no-16o-encontro-do-gurusp?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-06-25T01:32:41.000Z</published>
      <updated>2021-07-04T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/06/25/16-palestra-do-cassio-marques-no-16o-encontro-do-gurusp</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/06/25/16-palestra-do-cassio-marques-no-16o-encontro-do-gurusp">
        <![CDATA[<div xml:lang="pt-BR"><p>No começo do mês, aconteceu o 16º encontro do <strong>Grupo de Usuários Ruby de SP</strong> (aka. Guru SP).</p>
<p>Como o <a href="http://www.agaelebe.com/">Agaelebe (Hugo Borges)</a> não ia poder participar, me oferecei para
filmar as apresentações.
Segue o primeiro vídeo que gravei/editei, da palestra do
<a href="https://cassiomarques.wordpress.com">Cássio Marques</a>):</p>
<iframe src='https://player.vimeo.com/video/25419576' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<hr>
<p>Outros vídeos, slides e links interessantes do evento estão no
<a href="https://gurusp.org/encontros/decimo-sexto-encontro-do-guru-sp">site oficial do grupo</a>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="gurusp" />
    </entry>

    <entry>
      <title><![CDATA[My new gem "code2pdf"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2011/06/02/my-new-gem-code2pdf?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-06-02T06:11:18.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2011/06/02/my-new-gem-code2pdf</id>
      <content type="html" xml:base="https://www.lucascaton.com/2011/06/02/my-new-gem-code2pdf">
        <![CDATA[<div xml:lang="en"><p>I've created a gem called <a href="https://github.com/lucascaton/code2pdf"><strong>code2pdf</strong></a>,
which is a simple and open-source tool to convert your codebase to a PDF file.
It might be especially useful in case you need to register you software.</p>
<p>In order to install it, just run:</p>
<pre><code class="language-bash">gem install code2pdf
</code></pre>
<p>Then, open a terminal and run:</p>
<pre><code class="language-bash">code2pdf [project path] [blacklist file]
</code></pre>
<p>The blacklist file is optional and must be a YML file, similar to the following:</p>
<pre><code class="language-yaml">:directories:
  - .git
  - log
  - public/system
  - spec
  - tmp
  - vendor
:files:
  - .DS_Store
  - .gitignore
  - database.yml
  - favicon.ico
</code></pre>
<p>You can find more information (including a <a href="https://github.com/lucascaton/code2pdf/raw/master/examples/example.pdf">PDF output example</a> in the repository:</p>
<p><a href="https://github.com/lucascaton/code2pdf">github.com/lucascaton/code2pdf</a></p>
<p>Please, let me know in the comments if you like it :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="gem" /><category term="code2pdf" />
    </entry>

    <entry>
      <title><![CDATA[Slides da minha apresentação no Bio Labs #1: "Por que testar é importante e algumas boas práticas"]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/06/01/slides-bio-labs-1-por-que-testar-e-importante-e-algumas-boas-praticas?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-06-01T10:55:19.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/06/01/slides-bio-labs-1-por-que-testar-e-importante-e-algumas-boas-praticas</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/06/01/slides-bio-labs-1-por-que-testar-e-importante-e-algumas-boas-praticas">
        <![CDATA[<div xml:lang="pt-BR"><p>Hoje tive a honra de realizar a primeira apresentação do <strong>Bio Labs</strong>, que é uma série de apresentações (tech talks) que faremos na empresa onde eu trabalho, <strong>Bio Ritmo</strong>.</p>
<p>Eis os slides da minha apresentação:</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/1JAANrXOrHGJKS" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen></iframe>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="slides" /><category term="palestras" /><category term="apresentacoes" /><category term="biolabs" /><category term="tech-talks" /><category term="tests" /><category term="testes" />
    </entry>

    <entry>
      <title><![CDATA[Palestra "Building Chrome Apps with HTML5" com Boris Smus (desenvolvedor front-end do Google)]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/05/26/palestra-building-chrome-apps-with-html5-com-boris-smus-do-google?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-05-25T15:09:31.000Z</published>
      <updated>2025-03-28T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/05/26/palestra-building-chrome-apps-with-html5-com-boris-smus-do-google</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/05/26/palestra-building-chrome-apps-with-html5-com-boris-smus-do-google">
        <![CDATA[<div xml:lang="pt-BR"><p>Acabei de chegar da palestra <a href="http://www.sp-gtug.org/wp/?p=320">"Building Chrome Apps with HTML5"</a> com <a href="https://twitter.com/borismus">Boris Smus</a> (que aconteceu na <strong>Caelum</strong>). O cara é desenvovedor front-end do <strong>Google</strong> e fã de open source.</p>
<p><img src="/images/posts/2011/05/wr8de.jpg" alt="wr8de2"></p>
<p>Você pode baixar <a href="https://github.com/borismus/Chrome-Brazil/zipball/master">aqui</a> os slides da palestra.
Ele explicou coisas interessante, como por exemplo fazer uma tag <code>input</code> apta à reconhecer sua voz:</p>
<pre><code class="language-html">&#x3C;input type="text" x-webkit-speech />
</code></pre>
<p><img src="/images/posts/2011/05/5236057085_0533715202.jpg" alt="5236057085_0533715202"></p>
<p>Entre várias outras coisas, vale a pena conferir os slides e também o blog do cara: <a href="http://smus.com/">http://smus.com/</a>.</p>
<p><img src="/images/posts/2011/05/Untitled-1.jpg" alt="Untitled-1"></p>
<p>Pra fechar com chave de outro, ganhei uma camiseta nos brindes no final da palestra :)</p>
<p><img src="/images/posts/2011/05/IMG_0580.jpg" alt="IMG_0580"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="google" /><category term="palestras" /><category term="apresentacoes" /><category term="spgtug" />
    </entry>

    <entry>
      <title><![CDATA[Por que parei de usar os gemsets do RVM]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/05/25/por-que-parei-de-usar-os-gemsets-do-rvm?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-05-25T03:22:17.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/05/25/por-que-parei-de-usar-os-gemsets-do-rvm</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/05/25/por-que-parei-de-usar-os-gemsets-do-rvm">
        <![CDATA[<div xml:lang="pt-BR"><p>Uso <a href="https://rvm.io/">RVM (Ruby Version Manager)</a> desde que este foi lançado e pretendo continuar utilizando, dada a facilidade para utilizar diferentes implementações/versões do Ruby em uma mesma máquina.</p>
<p>Algo muito interessante que ele traz são os <code>gemsets</code>, ferramenta para separar suas gems em contextos, geralmente um para cada projeto.</p>
<p>Isso fazia total sentido antes do Rails chegar em sua versão 3, quando Bundler foi incluído por padrão para realizar o gerenciamento das gems.</p>
<p>Ou seja, na teoria apenas projetos rodando Rails 2 teriam o problema de versões diferentes das gems. Porém na prática, <a href="http://gembundler.com/rails23.html">é possível usar o Bundler em projetos Rails 2</a>, tornando os <code>gemsets</code> meio inúteis.</p>
<p>Juntei todas as minhas gems no gemset <code>global</code>, que já vem criado por default e há 2 meses tenho usado desta forma, onde tudo tem funcionado perfeitamente.</p>
<p>O único detalhe, é que se você tiver duas ou mais versões de alguma gem que inclui um executável (<code>rspec</code> por exemplo) você precisa chamá-lo da seguinte maneira:</p>
<pre><code>bundle exec rspec
</code></pre>
<p>Dessa forma, o <strong>Bundler</strong> sabe qual dos executáveis usar, baseado no seu arquivo <code>Gemfile</code>.
Para facilitar, eu criei alguns <em>aliases</em>:</p>
<pre><code class="language-bash">alias rails='bundle exec rails'
alias rake='bundle exec rake'
alias rspec='bundle exec rspec'
</code></pre>
<p>Como vocês estão fazendo? Alguma sugestão ou crítica?</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rvm" /><category term="gemsets" />
    </entry>

    <entry>
      <title><![CDATA[My Vimfiles]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2011/05/24/my-vimfiles?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-05-24T10:36:18.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2011/05/24/my-vimfiles</id>
      <content type="html" xml:base="https://www.lucascaton.com/2011/05/24/my-vimfiles">
        <![CDATA[<div xml:lang="en"><p><strong>Vimfiles</strong> are configuration files for the <strong>Vim</strong> editor.
It includes the <strong>editor preferences</strong>, <strong>theme</strong> (color scheme), <strong>fonts</strong>, <strong>plugins</strong>, <strong>custom functions</strong>, and more.</p>
<p>I've finally created my own from scrach, which you can find here:</p>
<p><a href="https://github.com/lucascaton/vimfiles">github.com/lucascaton/vimfiles</a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="vim" /><category term="vimfiles" />
    </entry>

    <entry>
      <title><![CDATA[Criando um log com detalhes de erros]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/05/23/criando-um-log-com-detalhes-de-erros?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-05-23T01:30:22.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/05/23/criando-um-log-com-detalhes-de-erros</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/05/23/criando-um-log-com-detalhes-de-erros">
        <![CDATA[<div xml:lang="pt-BR"><p>Quando rodamos algum script em sistemas Unix, existem 3 tipos de mensagens de entrada e saída:</p>
<ul>
<li><code>STDIN</code> - Standard in (código 0)</li>
<li><code>STDOUT</code> - Standard out (código 1)</li>
<li><code>STDERR</code> - Standard error (código 2)</li>
</ul>
<p>Se você precisar salvar um log contendo não só as mensagens da saída padrão, mas também as mensagens de erro, use o sufixo <code>2>&#x26;1</code>:</p>
<pre><code class="language-bash">ls -lR / > /tmp/file.log 2>&#x26;1
</code></pre>
<p>O que estamos fazendo aí é pegando tudo que é da saída 2 (<code>STDERR</code>) e jogando pra saída 1 (<code>STDOUT</code>), fazendo com que o log contenha tudo :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="linux" /><category term="shell" /><category term="unix" /><category term="bash" /><category term="stderr" />
    </entry>

    <entry>
      <title><![CDATA[Porque voltei a usar o WordPress]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/05/19/porque-voltei-a-usar-o-wordpress?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-05-19T02:30:03.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/05/19/porque-voltei-a-usar-o-wordpress</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/05/19/porque-voltei-a-usar-o-wordpress">
        <![CDATA[<div xml:lang="pt-BR"><p>Esse blog foi criado em 2009 e estava hospedado na <strong>Locaweb</strong>, onde toda a configuração para aplicações <strong>PHP</strong> já estava pronta: <strong>Apache</strong>, o <strong>PHP</strong> própriamente dito e <strong>MySQL</strong> (infelizmente <strong>WordPress</strong> não suporta <strong>PostgreSQL</strong>). Tudo funcionava muito bem.</p>
<p>Pouco mais de um ano depois, mudei de hospedagem, agora uso um servidor da <strong>WebbyNode</strong>, o qual tem sido excelente. Porém, sempre uso um server-deploy semi-pronto, ou seja, que já vem com algumas ferramentas do mundo Ruby.</p>
<p>Como queria continuar com o <strong>WordPress</strong>, tive que instalar o PHP na mão. Até aí sem problemas: <strong>Nginx</strong> + <strong>PHP</strong> + <strong>WordPress</strong> + <strong>MySQL</strong> foi moleza. Lembro que quando migrei de servidor tive problemas <strong>FastCGI</strong>, mas acabei resolvendo.</p>
<p>Meus problemas reais começaram quando fiz um novo server-deploy, repeti os passos e notei que o blog estava muito lento e que havia algo errado. Pesquisei sobre isso e descobri que o meu server não estava usando <strong>FastCGI</strong>, essencial para aplicações que rodam em <strong>PHP</strong>. Passei um tempão tentando fazer isso funcionar, sem sucesso.</p>
<p>Foi aí que decidi usar o <a href="https://github.com/xaviershay/enki"><strong>Enki</strong></a>, um <em>blog manager</em> open-source feito em <strong>Rails</strong>. Gostei muito dele assim que comecei a usar. Logo de cara fiz um <a href="https://github.com/lucascaton/enki">fork</a> e fiz <a href="https://github.com/lucascaton/enki/commits/master">algumas modificações</a> pra me atender melhor.</p>
<p>Mas ainda haviam algumas coisas que realmente não estavam me agradando. Primeiro que migrar <strong>todos os posts</strong>, <strong>páginas</strong>, <strong>comentários</strong> e <strong>imagens</strong> não seria nada fácil. Depois, as páginas não estavam cacheadas (até onde eu vi), as views eram escritas em ERB (e eu gostaria de migrar para <a href="http://haml-lang.com/">HAML</a>) e tinha bastante coisa que eu teria que mudar. Além disso, não haviam muito <em>themes</em>, como no <strong>WordPress</strong>.</p>
<p>Por fim, depois de 2 semanas, decidi que ficaria com o <strong>WordPress</strong> mesmo. Meu amigo <a href="https://twitter.com/duderamos">Dude</a> me ajudou a configurar o <strong>FastGCI</strong> (usando <a href="http://php-fpm.org/"><code>php-fpm</code></a>) e voltei o blog pro bom e velho <strong>WordPress</strong>.</p>
<p>Embora o código dele torne difícil algumas moficações, acho que não vou mudar ele por um bom tempo. E confesso que fiquei feliz de ter voltado :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="wordpress" /><category term="site" /><category term="blog" /><category term="nginx" /><category term="php-fpm" /><category term="php" /><category term="enki" /><category term="ruby" /><category term="rails" />
    </entry>

    <entry>
      <title><![CDATA[Empreendedorismo]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2011/02/22/empreendedorismo?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2011-02-22T12:45:48.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2011/02/22/empreendedorismo</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2011/02/22/empreendedorismo">
        <![CDATA[<div xml:lang="pt-BR"><p>Fugindo um pouco de assuntos técnicos, vou postar um resumo sobre algumas coisas que ando ouvindo e lendo sobre empreendedorismo:</p>
<h2>Podcasts</h2>
<h3>Grok Podcast - Rework</h3>
<p>Carlos Brando e Rafael Rosa comentam o interessantíssimo livro "Rework", da empresa 37 signals. Vale <strong>muito</strong> a pena ouvir, fantástico!</p>
<ul>
<li><a href="http://grokpodcast.com/2011/01/27/episodio-16-rework-parte-1/">Parte 1</a></li>
<li><a href="http://grokpodcast.com/2011/02/03/episodio-17-rework-parte-2/">Parte 2</a></li>
<li><a href="http://grokpodcast.com/2011/02/10/episodio-18-rework-parte-3/">Parte 3</a></li>
</ul>
<h3>Nerdcast - Expresso Empreendedor</h3>
<p>Pessoal do Jovem Nerd com muitas dicas bacanas, humor e convidados experientes.</p>
<ul>
<li><a href="http://jovemnerd.ig.com.br/nerdcast/nerdcast-203-expresso-empreendedor/">Parte 1</a></li>
<li><a href="http://jovemnerd.ig.com.br/nerdcast/nerdcast-243-expresso-empreendedor-2/">Parte 2</a></li>
</ul>
<h3>GuanaCast - Como criar sua Empresa</h3>
<p>Não costumo escutar esse podcast, mas como o assunto me interessou, acabei ouvindo.
Guanabara conversa com o pessoal do Sebrae e discutem sobre Startups, incubadoras, sociedades, entre outras coisas.</p>
<ul>
<li><a href="http://www.guanabara.info/2011/02/como-criar-sua-empresa-sebrae/">Parte única</a></li>
</ul>
<h2>Livros</h2>
<ul>
<li><a href="http://www.saiadolugar.com.br/2010/05/28/desenvolvimento-de-produtos-sem-enrolacao-lancamento-do-e-book/">Desenvolvimento de produtos sem enrolação</a></li>
<li><a href="http://gettingreal.37signals.com/">Getting Real</a> (<a href="http://gettingreal.37signals.com/GR_por.php">Caindo na Real</a> (versão em português) (37 Signals)</li>
<li><a href="http://37signals.com/rework/">Rework</a> (37 Signals)</li>
<li>"Pai rico pai pobre" (Robert Kiyosaki e Sharon Lechter)</li>
<li>"Os segredos dos campeões" (Roberto Shinyashiki)</li>
</ul>
<h2>Próximos livros</h2>
<ul>
<li><a href="http://lucasteixeira.com/ztd">ZTD - Zen To Done (Leo Babauta)</a></li>
<li><a href="http://www.startupolivro.com.br/">Startup (Jessica Livingston)</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="empreendedorismo" />
    </entry>

    <entry>
      <title><![CDATA[Meu ambiente de trabalho]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/12/28/meu-ambiente-de-trabalho?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-12-27T21:35:56.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/12/28/meu-ambiente-de-trabalho</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/12/28/meu-ambiente-de-trabalho">
        <![CDATA[<div xml:lang="pt-BR"><p>O <a href="http://duodra.co/"><strong>Anderson Casimiro</strong></a> e o <strong>Augusto Pascutti</strong> criaram um meme sobre ambientes de trabalho. As regras são simples:</p>
<ul>
<li>Escreva sobre seu ambiente de trabalho - fale sobre qualquer ponto que quiser;</li>
<li>Indique de 3 à 5 pessoas para que possivelmente façam um artigo sobre seu ambiente.</li>
</ul>
<p>Fui convidado pelo <strong>Bruno Codeman</strong> para montar minha lista!</p>
<h3>1. OS: Ubuntu 10.10</h3>
<p>Atualmente, a mais popular distriuição Linux. Como é baseada no Debian, herdou o apt pra gereciar os pacotes. Todo o meu hardware funciona bem e raramente o sistema fica lento ou trava. Ultimamente tem ficado até mais bonito...</p>
<h3>2. IDE/Editor: Vim</h3>
<p>Rápido, flexível, snippets, atalhos produtivos e ainda conta com excelentes plugins. Desenvolvo em Ruby e Ruby on Rails utilizando somente ele e sempre dá conta do recado.</p>
<h3>3. Browser: Google Chrome</h3>
<p>Há um ano, eu comecei a <a href="https://www.lucascaton.com/2009/12/18/5-dias-testando-google-chrome-4-beta-no-linux">experimentar o browser do Google</a> e este substituiu o meu querido Firefox. Com todas as extensions disponíveis hoje, quase não preciso de outro browser, embora exporadiamente use o Firefox pra usar os add-ons WebDeveloper e Firebug.</p>
<h3>4. Versionamento: Git</h3>
<p>Git ganhou meu respeito. O utilizo há 1 ano e meio e definitivamente me atendeu melhor que o SVN. Não dá pau e é muito eficiente. É atualmente um dos softwares que mais me orgulho de usar.</p>
<h3>5. Linguagem de programação: Ruby</h3>
<p>Já desenvolvi em PHP, Delphi, Java e até brinquei um pouco com .Net e Python. Mas nada, nada me faz mais feliz que programar em Ruby. A sintaxe é limpa, o suporte à metaprogramação é ótimo, desenvolver usando BDD é muito fácil e a comunidade é fantástica.</p>
<h3>6. Banco de Dados: PostgreSQL</h3>
<p>Usei MySQL por muito tempo e era ok. Mas ano passado tive que começar a trabalhar em alguns projetos que usavam PostgreSQL e seu poder me convenceu e se tornou meu database padrão.</p>
<h3>Indicação de 5 amigos pra continuar o meme:</h3>
<ul>
<li><a href="https://twitter.com/duderamos">Dude</a></li>
<li><a href="https://twitter.com/vhlaube">Vitor Laubé</a></li>
<li><a href="https://twitter.com/thiagoalessio">Thiago Aléssio</a></li>
<li><a href="https://twitter.com/jtadeulopes">Jésus Lopes</a></li>
<li><a href="https://twitter.com/edercosta">Eder Costa</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="web-development" /><category term="ruby" /><category term="java" /><category term="rails" /><category term="web-design" /><category term="browser" /><category term="chrome" /><category term="linux" /><category term="postgresql" /><category term="sistemas-operacionais" /><category term="git" /><category term="mysql" />
    </entry>

    <entry>
      <title><![CDATA[Pequenas soluções usando linha de comandos - parte IV (movendo arquivos)]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/12/01/pequenas-solucoes-usando-linha-de-comandos-parte-iv-movendo-arquivos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-11-30T23:26:02.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/12/01/pequenas-solucoes-usando-linha-de-comandos-parte-iv-movendo-arquivos</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/12/01/pequenas-solucoes-usando-linha-de-comandos-parte-iv-movendo-arquivos">
        <![CDATA[<div xml:lang="pt-BR"><p>O comando <code>mv</code> serve básicamente pra duas coisas: mover arquivos de um diretório pra outro e renomear arquivos.</p>
<p>Algo interessante que aprendi com o <a href="https://twitter.com/duderamos">Dude</a> foi como mover apenas alguns tipos de arquivos.
Exemplo: se eu precisar mover todos os arquivos com extensão <code>.txt</code> e <code>.doc</code> para um diretório chamado <code>docs</code>, bastaria fazer:</p>
<pre><code class="language-bash">mv /home/caton/{*.txt,*.doc} /home/caton/docs
</code></pre>
<p>Enjoy! :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ubuntu" /><category term="linux" /><category term="shell" /><category term="bash" />
    </entry>

    <entry>
      <title><![CDATA[Como foi o evento Agile Vale 2010]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/11/19/como-foi-o-evento-agile-vale-2010-2?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-11-19T13:33:46.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/11/19/como-foi-o-evento-agile-vale-2010-2</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/11/19/como-foi-o-evento-agile-vale-2010-2">
        <![CDATA[<div xml:lang="pt-BR"><p>Aconteceu hoje o evento <a href="http://www.agilevale.com.br/">Agile Vale 2010</a>, no ITA, em São José dos Campos-SP. O evento foi muito bom e também muito bem organizado. No total, foram mais de 440 participantes, sem contar palestrantes, patrocinadores e a equipe que organizou o evento, que a propósito estão de parabéns.</p>
<p><img src="/images/posts/2010/11/2010-11-19-145837.jpg" alt="2010-11-19-145837"></p>
<p>No total foram <a href="http://agilevale.com.br/programacao/">11 palestras, 2 dinâmicas e uma mesa redonda</a> com os palestrantes. Como não haveria tempo para todas as palestras, a solução infelizmente foram apresentações paralelas. Somente a primeira palestra e a mesa redonda não tiveram nada em paralelo, então eu não pude assistir 5 palestras de um total de 11 (as quais pretendo assistir em vídeo depois). As dinâmicas também aconteceram paralelamente às palestras, então não participei de nenhuma das duas.</p>
<p>Ah! O evento ficou devendo uma conexão wireless, embora isso fosse quase impossível levando em consideração a quantidade de participantes.</p>
<h1>Palestras</h1>
<p><img src="/images/posts/2010/11/Fabiano_bigger.jpg" alt="Fabiano_bigger"></p>
<p><strong>"Você sabe o que é Agile? Eu também não!" - Fabiano Milani (AdaptIdeas)</strong></p>
<p>Foram apresentados conceitos básicos de metodologias ágeis. A palestra foi interessante, porém focada em quem nunca aplicou ou estudou metodologias ágeis.</p>
<p><img src="/images/posts/2010/11/profile_bigger.png" alt="profile_bigger"></p>
<p><strong>"O que é Kanban e porque se importar com ele." - Rodrigo Yoshima (Aspercom)</strong></p>
<p>No começo achei os conceitos meio confusos e eu não conseguia entender o objetivo principal do Kanban. Mas no decorrer da apresentação, Yoshima conseguiu demonstrar os benefícios do Kanban e a palestra realmente valeu a pena. Muito boa!</p>
<p><img src="/images/posts/2010/11/avatar_bigger.jpg" alt="avatar_bigger"></p>
<p><strong>"Construindo uma cultura de aprendizagem." - Luiz Faias e André Faria (Bluesoft)</strong></p>
<p>A palestra levanta questões como: "Quanto você está se dedicando pra ser um profissional melhor?", "Você participa de projetos open-source?", "Participa de eventos?", "Lê bons livros?", entre outras. Resumindo, foram dicas de boas práticas para melhorar profissionalmente.</p>
<p><img src="/images/posts/2010/11/paulo_caroli_bigger.jpg" alt="paulo_caroli_bigger"></p>
<p><strong>"A linha de montagem de SW representada como cartões na parede." - Paulo Caroli (ThoughtWorks Brasil)</strong></p>
<p>A palestra falou sobre como cartões na parede tornam conceitos básicos de Kanban, Scrum, Lean e XP visíveis a todo time.</p>
<p><img src="/images/posts/2010/11/4015270661_1d44744ac4_o_bigger.jpg" alt="4015270661_1d44744ac4_o_bigger"></p>
<p><strong>"Entenda Software de Forma Correta" - Fábio Akita (GoNow)</strong></p>
<p>A palestra do Akita - como sempre - foi ótima. Ele falou sobre a evolução de softwares, sobre softwares que mesmo sem documentação e sem controle podem ser bem sucedidos, como é o caso de vários projetos open-source; ele citou o Linux como exemplo. Me fez enchergar software como um conjunto de idéias, como um <a href="https://pt.wikipedia.org/wiki/Meme">meme</a> e repetiu várias vezes pra deixar claro: "não existe bala de prata", já que determinada ferramenta / framework pode funcionar muito bem em um projeto mas raramente funcionará em todos.</p>
<p><img src="/images/posts/2010/11/ceci-bearMountain_bigger.png" alt="ceci-bearMountain_bigger"></p>
<p><strong>"O problema é seu, a solução também" - Cecília Fernandes (Caelum)</strong></p>
<p>Pra mim, foi a melhor palestra do evento. Cecília mandou muito bem e através de uma forma muito simples e eficiente, soube explicar porque e como customizar determinada metodologia ágil de forma que ela se torne a "SUA" metodologia. Explicou porque evitar o uso do famoso "Scrum de caixinha", ou seja, Scrum (ou qualquer outra metodologia) como ferramenta fechada e não como framework.</p>
<h1>Mesa redonda</h1>
<p>A mesa redonda foi muito boa. As discussões se basearam em dois (polemicos) temas: "Se eu estou usando Scrum, mas não uso TDD / BDD, isto está correto?" e "Como deve ser a transformação de um líder de projeto quando se muda de uma metodologia tradicional para uma ágil".</p>
<p><img src="/images/posts/2010/11/mesa_redonda.jpg" alt="mesa_redonda"></p>
<h1>Pra finalizar</h1>
<p>Novamente: a equipe que organizou está de parabéns, tanto pela iniciativa quando pela organização. Espero que a edição 2011 seja ainda melhor :)</p>
<p><img src="/images/posts/2010/11/banner.jpg" alt="banner"></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="eventos" /><category term="agile" />
    </entry>

    <entry>
      <title><![CDATA[How to test Rails mailers using RSpec]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/2010/10/25/how-to-test-mailers-in-rails-with-rspec?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-10-25T09:19:04.000Z</published>
      <updated>2026-03-21T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/2010/10/25/how-to-test-mailers-in-rails-with-rspec</id>
      <content type="html" xml:base="https://www.lucascaton.com/2010/10/25/how-to-test-mailers-in-rails-with-rspec">
        <![CDATA[<div xml:lang="en"><p><strong>ActionMailer</strong> module has been reconstructed in <strong>Rails 3</strong> and mailers have their own subdirectory (<strong>app/mailers</strong>) since then.</p>
<p>This blog post will demostrate how to test them in <strong>Rails</strong> using <strong>RSpec</strong>. Assuming that we have a mailer like the following:</p>
<pre><code class="language-ruby">class Notifier &#x3C; ActionMailer::Base
  default from: 'noreply@company.com'
  def instructions(user)
    @name = user.name
    @confirmation_url = confirmation_url(user)
    mail to: user.email, subject: 'Instructions'
  end
end
</code></pre>
<p>To send an email through a method from <code>User</code> model:</p>
<pre><code class="language-ruby">class User
  def send_instructions
    Notifier.instructions(self).deliver_now
  end
end
</code></pre>
<p>Before testing it, make sure the <strong>config/environments/test.rb</strong> file has the following configuration:</p>
<pre><code class="language-ruby">Rails.application.configure do
  config.action_mailer.delivery_method = :test
end
</code></pre>
<p>It ensures that emails won't be sent, but instead be stored on <strong>ActionMailer::Base.deliveries</strong> array.</p>
<p>So, in order to create the tests:</p>
<pre><code class="language-ruby"># spec/models/user_spec.rb
RSpec.describe User, type: :model do
  subject { create :user }
  it 'sends an email' do
    expect { subject.send_instructions }
      .to change { ActionMailer::Base.deliveries.count }.by(1)
  end
end
</code></pre>
<pre><code class="language-ruby"># spec/mailers/notifier_spec.rb
RSpec.describe Notifier, type: :mailer do
  describe 'instructions' do
    let(:user) { mock_model User, name: 'Lucas', email: 'lucas@email.com' }
    let(:mail) { described_class.instructions(user).deliver_now }
    it 'renders the subject' do
      expect(mail.subject).to eq('Instructions')
    end
    it 'renders the receiver email' do
      expect(mail.to).to eq([user.email])
    end
    it 'renders the sender email' do
      expect(mail.from).to eq(['noreply@company.com'])
    end
    it 'assigns @name' do
      expect(mail.body.encoded).to match(user.name)
    end
    it 'assigns @confirmation_url' do
      expect(mail.body.encoded)
        .to match("http://aplication_url/#{user.id}/confirmation")
    end
  end
end
</code></pre>
<p>Rails allows you to create very comprehensive tests for mailers.</p>
<p>Happy coding!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="mailer" /><category term="rspec" /><category term="test" />
    </entry>

    <entry>
      <title><![CDATA[Como testar mailers no Rails com RSpec]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/10/12/como-testar-mailers-no-rails-3-com-rspec?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-10-12T07:10:03.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/10/12/como-testar-mailers-no-rails-3-com-rspec</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/10/12/como-testar-mailers-no-rails-3-com-rspec">
        <![CDATA[<div xml:lang="pt-BR"><p>O módulo <strong>ActionMailer</strong> foi refeito no <strong>Rails 3</strong> e os mailers ganharam um subdiretório próprio (dentro do <strong>app/</strong>) desde então.
Nesse post vou demonstrar como testá-los no <strong>Rails</strong> using <strong>RSpec</strong>.</p>
<p>Supondo que temos um <strong>mailer</strong> como esse:</p>
<pre><code class="language-ruby">class Notifier &#x3C; ActionMailer::Base
  default from: 'noreply@company.com'
  def instructions(user)
    @name = user.name
    @confirmation_url = confirmation_url(user)
    mail to: user.email, subject: 'Instructions'
  end
end
</code></pre>
<p>Para enviar um email através de um método da classe User:</p>
<pre><code class="language-ruby">class User
  def send_instructions
    Notifier.instructions(self).deliver_now
  end
end
</code></pre>
<p>Antes de testá-lo, garanta que o arquivo <code>config/environments/test.rb</code> esteja configurado assim:</p>
<pre><code class="language-ruby">Rails.application.configure do
  config.action_mailer.delivery_method = :test
end
</code></pre>
<p>Isso garante que os e-mails não serão realmente enviados, e sim armazenamos no array <code>ActionMailer::Base.deliveries</code>.</p>
<p>Verificado isso, basta criar os testes (exemplo: <code>spec/models/user_spec.rb</code>):</p>
<pre><code class="language-ruby">RSpec.describe User, type: :model do
  subject { create :user }
  it 'sends an email' do
    expect { subject.send_instructions }
      .to change { ActionMailer::Base.deliveries.count }.by(1)
  end
end
</code></pre>
<pre><code class="language-ruby"># spec/mailers/notifier_spec.rb
RSpec.describe Notifier, type: :mailer do
  describe 'instructions' do
    let(:user) { mock_model User, name: 'Lucas', email: 'lucas@email.com' }
    let(:mail) { described_class.instructions(user).deliver_now }
    it 'renders the subject' do
      expect(mail.subject).to eq('Instructions')
    end
    it 'renders the receiver email' do
      expect(mail.to).to eq([user.email])
    end
    it 'renders the sender email' do
      expect(mail.from).to eq(['noreply@company.com'])
    end
    it 'assigns @name' do
      expect(mail.body.encoded).to match(user.name)
    end
    it 'assigns @confirmation_url' do
      expect(mail.body.encoded)
        .to match("http://aplication_url/#{user.id}/confirmation")
    end
  end
end
</code></pre>
<p>O Rails nos possibilita criar testes bastante compreensivos para <strong>mailers</strong>.</p>
<p>Happy coding!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="mailer" /><category term="rspec" />
    </entry>

    <entry>
      <title><![CDATA[Lá vem mais um Windows (ou "Motivos pelos quais não volto pra Matrix")]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/09/23/la-vem-mais-um-windows-ou-motivos-pelos-quais-nao-volto-pra-matrix?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-09-23T13:03:38.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/09/23/la-vem-mais-um-windows-ou-motivos-pelos-quais-nao-volto-pra-matrix</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/09/23/la-vem-mais-um-windows-ou-motivos-pelos-quais-nao-volto-pra-matrix">
        <![CDATA[<div xml:lang="pt-BR"><p>Após assistir o vídeo de <em>preview</em> do <strong>Windows 8</strong> (enviado pelo <a href="https://twitter.com/duderamos">Dude</a>), resolvi escrever os motivos pelos quais eu não volto mais para a "Matrix".</p>
<p>Antes que me atirem pedras, quero deixar claro que essa é <strong>a minha opnião</strong>. Você tem todo o direito de não concordar (dê sua opnião nos comentários).</p>
<p>O Windows 7 e 8 tem vários recursos interessantes, mas o que me desagrada é o fato de existirem coisas definitivamente mais importantes do que uma interface "bonitinha" (apesar de ainda estar muito atrás do <del>OS X</del> macOS).</p>
<p>Exitem certas funcionalidades que fazem muita falta e que ninguém dá atenção, como um terminal decente por exemplo. Um através do qual você possa realmente ter controle total sobre sua máquina.</p>
<p>Tinha um comcercial do Windows Vista (ou 7) que dizia: "O Mac é bonitinho, mas você precisa de um S.O. de verdade". Que ironia, hein?!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="sistemas-operacionais" /><category term="windows" />
    </entry>

    <entry>
      <title><![CDATA[Slides da minha apresentação no encontro do Guru-SP #11]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/09/19/slides-da-minha-apresentacao-no-encontro-do-guru-sp-11?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-09-19T04:25:25.000Z</published>
      <updated>2020-11-15T21:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/09/19/slides-da-minha-apresentacao-no-encontro-do-guru-sp-11</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/09/19/slides-da-minha-apresentacao-no-encontro-do-guru-sp-11">
        <![CDATA[<div xml:lang="pt-BR"><p>Mensalmente o "Grupo de Usuários Ruby de SP" (aka. "Guru-SP") <a href="https://gurusp.org/encontros">organiza encontros</a> em São Paulo, nos quais programadores se reunem para discutir tecnologias e novidades do mundo Ruby.</p>
<p>O <a href="https://gurusp.org/encontros/decimo-primeiro-encontro-do-guru-sp">encontro mais recente aconteceu sábado (18/09/2010)</a> com uma série de 17 palestras de 10 minutos. Eu fiz uma pequena apresentação falando sobre gerência de estados de objetos Ruby utilizando a gem <code>state_machine</code>.</p>
<p>Slides da minha apresentação:</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/DToFqbtOUxzwiV" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen></iframe>
<h2>Algumas fotos do evento:</h2>
<p><img src="/images/posts/2010/09/5005938117_6747b9a44b.jpg" alt="5005938117_6747b9a44b"></p>
<p><img src="/images/posts/2010/09/5006556644_924716b86c.jpg" alt="5006556644_924716b86c"></p>
<p><img src="/images/posts/2010/09/IMG_6200.jpg" alt="IMG_6200"></p>
<p><img src="/images/posts/2010/09/IMG_6201.jpg" alt="IMG_6201"></p>
<p><img src="/images/posts/2010/09/IMG_6202.jpg" alt="IMG_6202"></p>
<p><img src="/images/posts/2010/09/IMG_6203.jpg" alt="IMG_6203"></p>
<hr>
<p>Meu brother Thiago Aléssio (aka. "Xis Frango") foi comigo, valeu pela companhia, brother!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="gurusp" /><category term="state-machine" /><category term="palestras" /><category term="apresentacoes" /><category term="tech-talks" />
    </entry>

    <entry>
      <title><![CDATA[Pequenas soluções usando linha de comandos - parte III (script de backup)]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/09/03/pequenas-solucoes-usando-linha-de-comandos-iii-script-de-backup?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-09-03T10:59:27.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/09/03/pequenas-solucoes-usando-linha-de-comandos-iii-script-de-backup</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/09/03/pequenas-solucoes-usando-linha-de-comandos-iii-script-de-backup">
        <![CDATA[<div xml:lang="pt-BR"><p>Nesse post vou compartilhar um script simples e eficiente pra fazer backup no <strong>Linux</strong>, usando o <code>rsync</code>. No exemplo que vou usar, temos dois diretórios: um de "origem" e um de "destino".</p>
<p>O <code>rsync</code> é na realidade um software de sincronização e isso signfica que todas as alterações que você fizer no diretório "origem" vão refletir no diretório "destino", sejam essas alterações a criação, a alteraração ou a exclusão de arquivos e pastas.</p>
<p>Vamos dar uma olhada no script:</p>
<pre><code class="language-bash">#! /bin/bash
SOURCE_DIRECTORY=/home/caton/
DESTINATION_DIRECTORY=caton@10.10.10.2:/home/someuser/bkp
sudo rsync -Cavz --progress --partial --delete \
  --numeric-ids --exclude="*.gvfs" \
  $SOURCE_DIRECTORY $DESTINATION_DIRECTORY
echo Backup realizado com sucesso.
echo
</code></pre>
<p>Explicando: as variáveis <code>SOURCE_DIRECTORY</code> e <code>DESTINATION_DIRECTORY</code> são apenas pra deixar o script mais organizado e fácil pra alterar os diretórios. Note que o segundo diretório que eu coloquei é um diretório remoto, acessado via protocolo ssh. A sintaxe é simples: <code>usuário@ip:diretório</code>.</p>
<p>Sobre os parametros utilizados (<code>progress</code>, <code>partial</code>, etc.), vale a pena pesquisar não só para entender, mas também para customizar, de forma que te atenda melhor.</p>
<p>Se te interessar, é possível salvar um log de cada backup:</p>
<pre><code>#! /bin/bash
SOURCE_DIRECTORY=/home/caton/
DESTINATION_DIRECTORY=caton@10.10.10.2:/home/someuser/bkp
LOG_FILE=~/logs/bkp_"$(date "+%F")".log
touch $LOG_FILE
sudo rsync -Cavz --progress --partial --delete \
  --numeric-ids --exclude="*.gvfs" \
  $SOURCE_DIRECTORY $DESTINATION_DIRECTORY > $LOG_FILE
echo Backup realizado com sucesso.
echo O log encontra-se em: $LOG_FILE
echo
</code></pre>
<p>Outra coisa interessante é colocar esse script no <code>cron</code>. Assim, de tempos em tempos ele será executado automaticamente.</p>
<p>Para finalizar, uma solução alternativa: dependendo do tipo de backup que você precisa, um simples alias no <code>~/.bashrc</code> pode ser suficiente:</p>
<pre><code class="language-bash">alias runrsync='sudo rsync -Cavz --progress --partial \
  --delete --numeric-ids --exclude="*.gvfs"
  /home/caton/ caton@10.10.10.2:/home/someuser/bkp'
</code></pre>
<p>Afinal, "Simplicidade é a sofisticação máxima" (Leonardo da Vinci).</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ubuntu" /><category term="linux" /><category term="macOS" /><category term="shell" /><category term="bash" />
    </entry>

    <entry>
      <title><![CDATA[Pequenas soluções usando linha de comandos - parte II]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/06/01/pequenas-solucoes-usando-linha-de-comandos-ii?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-06-01T08:52:57.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/06/01/pequenas-solucoes-usando-linha-de-comandos-ii</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/06/01/pequenas-solucoes-usando-linha-de-comandos-ii">
        <![CDATA[<div xml:lang="pt-BR"><h2>Desafio</h2>
<p>Escrever um script que rode em <em>daemon</em> (ou seja, em <em>background</em>), executando um ou mais comandos de tempo em tempo.</p>
<p>Há um tempo, eu precisei de um script que fizesse um <em>listening</em> em um determinado diretório e alterasse as permissões dos arquivos que eram movidos para esse diretório por outro software.</p>
<h2>Solução</h2>
<p>O script acabou ficando bastante simples e pode resolver vários tipos de problemas.</p>
<pre><code class="language-bash">#! /bin/bash
while((1)); do
  # Substitua o seguinte comando para fazer a tarefa que você precisa
  chown -R nobody:faturamento /home/faturamento/importacoes;
  sleep 5; # Quantidade de segundos para ficar em pausa antes de rodar novamente
done &#x26; # O `&#x26;` faz o script rodar em background
echo 'Script rodando em daemon...'
</code></pre>
<p>Se você souber outras formas de fazer isso (possivelmente existem maneiras melhores), mande através dos comentários :)</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ubuntu" /><category term="linux" /><category term="macOS" /><category term="shell" />
    </entry>

    <entry>
      <title><![CDATA[Resumo de comandos úteis do PostgreSQL]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/05/23/resumo-de-comandos-uteis-do-postgresql?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-05-23T04:08:40.000Z</published>
      <updated>2018-04-05T07:40:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/05/23/resumo-de-comandos-uteis-do-postgresql</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/05/23/resumo-de-comandos-uteis-do-postgresql">
        <![CDATA[<div xml:lang="pt-BR"><p>Este post é um resumo de comandos úteis para administração de bancos de dados <strong>PostgreSQL</strong>.</p>
<h2>Criar uma senha</h2>
<pre><code class="language-bash">sudo su postgres -c psql postgres
</code></pre>
<p>Quando o console do <strong>PostgreSQL</strong> abrir, rode:</p>
<pre><code class="language-sql">ALTER USER postgres WITH PASSWORD 'sua_senha';
</code></pre>
<h2>Criar um banco de dados pelo terminal</h2>
<pre><code class="language-bash">createdb -U username -E utf8 dbname -h localhost
</code></pre>
<h2>Criar um banco de dados no console do PostgreSQL (<code>psql</code>)</h2>
<pre><code class="language-bash">create database dbname with owner=postgres encoding='utf8';
</code></pre>
<h2>Renomear um banco de dados</h2>
<pre><code class="language-bash">alter database "old_name" rename to "new_name";
</code></pre>
<h2>Apagar um banco de dados</h2>
<pre><code class="language-bash">drop database dbname;
</code></pre>
<h2>Dump (backup) de um banco de dados</h2>
<pre><code class="language-bash">pg_dump dbname -h localhost -U postgres > backup.sql
</code></pre>
<h2>Dump (backup) de uma tabela apenas</h2>
<pre><code class="language-bash">pg_dump dbname -h localhost -U postgres > backup.sql --table=nome_tabela;
</code></pre>
<h2>Dump (backup) de um banco de dados com apenas algumas tabelas</h2>
<pre><code class="language-bash">pg_dump dbname -h localhost -U postgres > backup.sql --table=nome_tabela --table=outra_tabela;
</code></pre>
<h2>Dump (backup) de um banco de dados sem determinada tabela</h2>
<pre><code class="language-bash">pg_dump dbname -h localhost -U postgres > backup.sql --exclude-table=nome_tabela;
</code></pre>
<h2>Dump (backup) de um banco de dados excluindo várias tabelas</h2>
<pre><code class="language-bash">pg_dump dbname -h localhost -U postgres > backup.sql --exclude-table=nome_tabela --exclude-table=outra_tabela;
</code></pre>
<h2>Restauração de um banco de dados (a partir de um arquivo SQL)</h2>
<pre><code class="language-bash">psql dbname -h localhost -U postgres &#x3C; backup.sql
</code></pre>
<h2>Dump (backup) dos usuários de um banco de dados</h2>
<pre><code class="language-bash">pg_dumpall -g -U postgres -h localhost > users.sql
</code></pre>
<h2>Comandos especiais em queries SQL</h2>
<h4>Data</h4>
<pre><code class="language-sql">select (current_date + integer '7') as nome_campo;
</code></pre>
<h2>Erros comuns</h2>
<h4>Duplicate key value violates unique constraint</h4>
<p>Ao migrar um banco de dados para <strong>PostgreSQL</strong> ou fazer alguma coisa errada sem querer, o seguinte erro pode aparecer:</p>
<pre><code class="language-bash">PGError: ERROR: duplicate key value violates unique constraint "tablename_pkey"
</code></pre>
<p>Para resolver:</p>
<pre><code class="language-sql">select setval('entities_id_seq', (select max(id) from entities)+1);
</code></pre>
<h2>Personalizando o <code>psql</code></h2>
<p>Basta criar um arquivo <code>~/.psqlrc</code>
(similar ou igual à <a href="https://github.com/lucascaton/dotfiles/blob/master/files/psqlrc">esse</a>)</p>
<h4>Alterando o pager</h4>
<pre><code class="language-sql">\pset pager off
\pset pager off
\pset pager always
\pset pager occasionally
\pset pager at random`
</code></pre>
<h4>Exibir <code>(null)</code> para campos <code>null</code> (em vez de não exibir nada)</h4>
<pre><code class="language-sql">\pset null '(null)'
</code></pre>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="postgresql" />
    </entry>

    <entry>
      <title><![CDATA[Ubuntu 10.04 + Ruby on Rails + PostgreSQL]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/05/18/ubuntu-10-04-ruby-on-rails-postgresql-8-4?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-05-17T22:32:25.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/05/18/ubuntu-10-04-ruby-on-rails-postgresql-8-4</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/05/18/ubuntu-10-04-ruby-on-rails-postgresql-8-4">
        <![CDATA[<div xml:lang="pt-BR"><blockquote>
<p><strong>Nota:</strong> Esse post é uma cópia do <code>README</code> do repositório <a href="https://github.com/lucascaton/lcaton-setuplinux">github.com/lucascaton/lcaton-setuplinux</a> que foi descontinuado e substituído pelos seguintes repositórios:</p>
<ul>
<li><a href="https://github.com/lucascaton/dotfiles">https://github.com/lucascaton/dotfiles</a></li>
<li><a href="https://github.com/lucascaton/vimfiles">https://github.com/lucascaton/vimfiles</a></li>
</ul>
</blockquote>
<hr>
<h3>Atualizado em 22/07/2011</h3>
<h2>Personalização das configurações após instalação do Ubuntu Linux</h2>
<p><strong>Última versão testada:</strong> Ubuntu 11.04 (desktop edition - 32 bits)</p>
<h1>Instalação básica</h1>
<p>Antes de mais nada, vamos rodar um update :)</p>
<pre><code>sudo apt-get update
</code></pre>
<p>Aptitude (a partir da versão 10.10 do Ubuntu o 'aptitude' não vem instalado por padrão)</p>
<pre><code>sudo apt-get install aptitude
</code></pre>
<p>Open SSH Server</p>
<pre><code>sudo aptitude install openssh-server
</code></pre>
<p>Ubuntu Restricted Extras</p>
<pre><code>sudo aptitude install ubuntu-restricted-extras
</code></pre>
<p>Git &#x26; gitg</p>
<pre><code>sudo aptitude install git-core gitg
</code></pre>
<p>Curl</p>
<pre><code>sudo aptitude install curl
</code></pre>
<p>Suporte à arquivos compactados</p>
<pre><code>sudo aptitude install rar p7zip-full
</code></pre>
<p>GTK Record My Desktop, Mencoder, Mplayer e AcidRip</p>
<pre><code>sudo aptitude install gtk-recordmydesktop mplayer mencoder ffmpeg acidrip
</code></pre>
<p>nmap</p>
<blockquote>
<p><strong>Dica:</strong>
Rode <code>sudo nmap -sS &#x3C;ip></code> pra saber as portas abertas de uma máquina remota.
Ou rode <code>netstat -npl | grep &#x3C;port></code> para saber os processos servindo determinada porta.</p>
</blockquote>
<pre><code>sudo aptitude install nmap
</code></pre>
<p>Criar DVDs e converter vídeos</p>
<pre><code>sudo aptitude install devede
</code></pre>
<p>Gimp</p>
<pre><code>sudo aptitude install gimp
</code></pre>
<p>Cheese</p>
<pre><code>sudo aptitude install cheese
</code></pre>
<p>Fonts true type</p>
<pre><code>sudo aptitude install msttcorefonts
</code></pre>
<p>Wine</p>
<pre><code>sudo aptitude install wine
</code></pre>
<h1>Fonte Monaco</h1>
<pre><code>sudo mkdir /usr/share/fonts/truetype/myfonts
cd /usr/share/fonts/truetype/myfonts
sudo cp ~/.setuplinux/files/Monaco_Linux.ttf .
sudo chown root:root Monaco_Linux.ttf
sudo mkfontdir
cd ..
fc-cache
</code></pre>
<h1>Gvim</h1>
<pre><code>sudo aptitude install vim-gnome ncurses-term exuberant-ctags
</code></pre>
<h1>Gmate</h1>
<pre><code>git clone git://github.com/gmate/gmate.git
cd gmate &#x26;&#x26; sh install.sh &#x26;&#x26; cd .. &#x26;&#x26; rm -rf gmate
</code></pre>
<h1>PostgreSQL</h1>
<pre><code>sudo aptitude install postgresql postgresql-contrib libpq-dev pgadmin3
</code></pre>
<p>Configurar a senha do PostgreSQL</p>
<pre><code>sudo passwd postgres
su - postgres
psql -c "ALTER USER postgres WITH PASSWORD 'sua_senha'" -d template1
</code></pre>
<h1>Sqlite3</h1>
<pre><code>sudo aptitude install sqlite3
</code></pre>
<h1>Ruby on Rails</h1>
<p>Bibliotecas necessárias</p>
<p>Readline headers</p>
<pre><code>sudo aptitude install libreadline5-dev
</code></pre>
<p>C++ compiler (necessário para o Ruby)</p>
<pre><code>sudo aptitude install build-essential
</code></pre>
<p>Sqlite support</p>
<pre><code>sudo aptitude install libsqlite3-dev sqlite-dev libdbd-sqlite3-ruby libsqlite3-ruby libsqlite3-ruby1.8
</code></pre>
<p>Mysql Client (necessário para a gem 'mysql')</p>
<pre><code>sudo aptitude install libmysqlclient15-dev
</code></pre>
<p>libxslt (necessário para a gem 'capybara')</p>
<pre><code>sudo aptitude install libxslt-dev
</code></pre>
<p>Sphinx (necessário para a gem 'thinking-sphinx')</p>
<pre><code>wget http://www.sphinxsearch.com/downloads/sphinx-0.9.9.tar.gz
tar -xzvf sphinx-0.9.9.tar.gz &#x26;&#x26; cd sphinx-0.9.9
./configure --with-pgsql &#x26;&#x26; sudo make &#x26;&#x26; sudo make install
cd .. &#x26;&#x26; rm -rf sphinx-0.9.9
</code></pre>
<p>Image Magick (necessário para a gem 'gruff')</p>
<pre><code>sudo aptitude install imagemagick libmagick9-dev
</code></pre>
<p>Cups Sys (necessário para a gem 'cups')</p>
<pre><code>sudo aptitude install libcupsys2-dev
</code></pre>
<p>Avahi - dnssd (necessário para a gem 'specjour')</p>
<pre><code>sudo aptitude install libavahi-compat-libdnssd-dev
</code></pre>
<p>RVM</p>
<pre><code>curl -sSL https://get.rvm.io | bash -s stable
</code></pre>
<p>Atualizar RVM</p>
<pre><code>rvm reload
rvm get stable
</code></pre>
<p>Ruby</p>
<pre><code>rvm install ruby
</code></pre>
<h1>Outros softwares</h1>
<ul>
<li>Google Chrome</li>
<li>TweetDeck</li>
<li>Skype</li>
<li><a href="http://ubuntu-tweak.com/">Ubuntu Tweak</a></li>
<li><a href="http://www.xmind.net/">XMind</a></li>
<li>TeamViewer</li>
</ul>
<h1>Extensões para Google Chrome</h1>
<ul>
<li><a href="https://chrome.google.com/webstore/detail/fhaicgmeeafgboeobjagfmlcdhbkijhf">Google bookmarks</a></li>
<li><a href="https://chrome.google.com/webstore/detail/kkioiolcacgoihiiekambdciinadbpfk">JSBeautify</a></li>
<li><a href="https://chrome.google.com/webstore/detail/bcjindcccaagfpapjjmafapmmgkkhgoa">JSON formatter</a></li>
<li><a href="https://lastpass.com/misc_download.php">Last Pass</a></li>
<li><a href="code.google.com/speed/page-speed/docs/extension.html">Page Speed</a></li>
<li><a href="https://chrome.google.com/webstore/detail/nlbjncdgjeocebhnmkbbbdekmmmcbfjd">RSS Subscription Extension (by Google)</a></li>
<li><a href="https://chrome.google.com/webstore/detail/gbammbheopgpmaagmckhpjbfgdfkpadb">XML Tree</a></li>
<li><a href="https://chrome.google.com/webstore/detail/pioclpoplcdbaefihamjohnefbikjilc">Evernote</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="ubuntu" /><category term="linux" /><category term="postgresql" />
    </entry>

    <entry>
      <title><![CDATA[Duas pequenas soluções usando linha de comandos]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2010/02/01/duas-pequenas-solucoes-usando-linha-de-comandos?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2010-02-01T08:52:39.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2010/02/01/duas-pequenas-solucoes-usando-linha-de-comandos</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2010/02/01/duas-pequenas-solucoes-usando-linha-de-comandos">
        <![CDATA[<div xml:lang="pt-BR"><p>Bom, este post marca o início de uma série com pequenas soluções interessantes usando a <strong>linha de comandos</strong>, uma quase "bala de prata" pra quem usa Linux e <del>OS X</del> macOS.</p>
<h2>Como deletar vários sub-diretórios de uma só vez</h2>
<p>Eu precisei fazer isso quando queria retirar os sub-diretórios do <a href="https://pt.wikipedia.org/wiki/Subversion"><strong>svn</strong></a> de uma pasta, ou seja, "desversionar" um projeto.
Para clarificar, um projeto versionado pelo <strong>svn</strong> segue uma estrutura de diretórios parecida com essa:</p>
<pre><code>./.svn
./app/.svn
./app/models/.svn
./config/.svn
</code></pre>
<p>E o comando mágico para remover todos os diretórios é:</p>
<pre><code class="language-bash">find -name ".svn" -type d -exec rm -rvf {} \;
</code></pre>
<p>Explicando o comando: procure por tudo que tiver o nome <code>.svn</code> e que for um diretório e quando encontrar, execute um comando <code>rm -rvf</code> nele.</p>
<p>Os parâmetros do <code>rm</code> significam:</p>
<ul>
<li><code>r</code> - recursive (apagar sub-diretórios recursivamente)</li>
<li><code>v</code> - verbose (exibir as pastas que estão sendo apagadas)</li>
<li><code>f</code> - force (não pedir confirmação para apagar)</li>
</ul>
<hr>
<h2>Como extrair uma parte de um arquivo grande e salvá-lo em outro arquivo</h2>
<p>Eu precisei fazer isso porque o arquivo do qual seria extraído uma parte era grande demais (1.5 GB). Ambos os editores Vim e Gedit tiveram dificuldade pra abrir um arquivo de texto tão grande.</p>
<p>Vamos supor então que o tal arquivo se chame <code>banco.dump</code>, que ele tenha 20 milhões de linhas e que eu precise extraír o conteúdo das linhas <code>12.000.000</code> até a linha <code>12.000.500</code> para um outro arquivo que vou chamar de <code>novo.txt</code>.</p>
<p>O comando para fazer isso é:</p>
<pre><code class="language-bash">cat -n banco.dump | head -n 12000500 | tail -n 500 > novo.txt
</code></pre>
<p>Explicando: o parâmetro passado no <code>head</code> é a linha final (<code>12000500</code>) do <em>range</em> desejado.
O parâmetro <code>500</code> passado como parâmetro do comando <code>tail</code> representa quantas linhas "para trás" ele deve pegar. Para finalizar, jogamos tudo dentro do arquivo <code>novo.txt</code>.</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="shell" /><category term="bash" /><category term="ubuntu" /><category term="linux" /><category term="macOS" />
    </entry>

    <entry>
      <title><![CDATA[5 dias testando Google Chrome 4 Beta no Linux]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2009/12/18/5-dias-testando-google-chrome-4-beta-no-linux?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2009-12-18T10:19:49.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2009/12/18/5-dias-testando-google-chrome-4-beta-no-linux</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2009/12/18/5-dias-testando-google-chrome-4-beta-no-linux">
        <![CDATA[<div xml:lang="pt-BR"><p>Há um ano, <a href="http://universofaces.wordpress.com/2008/09/03/o-browser-do-google/">postei no meu antigo blog</a> sobre o <strong>Google Chrome</strong>, quando até então era novidade. Dias depois, como ainda não havia nenhuma versão pra Linux, o abandonei e voltei para o bom e velho panda-vermelho (pois é, <a href="https://pt.wikipedia.org/wiki/Mozilla_Firefox#Nome">o Firefox <strong>não</strong> é uma raposa!</a>). Demorou - bastante a propósito, mas o Google finalmente liberou uma versão estável pro sistema do pinguim e pro <del>OS X</del> macOS.</p>
<p>O primeiro browser que usei foi o <strong>Netscape</strong>, em 1997~1998, até mudar para <strong>Internet Explorer</strong>, o qual deixei quando conheci a versão 1.0 do <strong>Firefox</strong>, o qual revolucionou o mundo dos browsers. Em paralelo com o <strong>Firefox</strong>, acompanhei três versões diferentes do <strong>Opera</strong>, o qual também gosto bastante e atualmente é meu browser secundário. E agora estou (re)experimentando o <strong>Chrome</strong>. Será que é hora de mudar novamente?</p>
<h2>Novidades interessantes</h2>
<p>Há 5 dias estou testando o <strong>Google Chrome</strong> beta (v. 4.0.249.30) para Linux (utilizo Ubuntu 9.04 durante o dia e Ubuntu 9.10 à noite, mas não notei diferença em relação à isso) e as boas notícias são:</p>
<ul>
<li>**Progresso de upload** - Quando você faz o upload de uma imagem ou qualquer arquivo para um site, é informado no rodapé o progresso de upload (em %). Isso realmente fazia muita falta;</li>
<li>**Pin tab** - alguns sites você sempre mantém aberto (aka Gmail) então porque não fixá-los no browser? É pra isso que serve as "pin tabs", abas que ficam no cantinho, discretas e sempre ali disponíveis.</li>
<li>**Abas no lugar do título da janela** - Economia de espaço colocando as abas na barra de título. Isso deixa o layout ainda mais clean;</li>
<li>**Textareas redimensionáveis** - Qualquer textarea pode ser redimensionado, basta clicar no canto inferior direito dele e arrastar. Pode ser útil às vezes;</li>
<li>**Nunca reinicie o browser** - Instalação e desistalação de extensions (aka add-ons) não requerem reinicialização do browser. Aplicação de temas (que a propósito funcionam muito bem) também não.</li>
<li>**Um processo por aba** - O que faz com que se algum site travar, o resto continua funcionando normalmente. Antes que atirem pedras em mim: ok, o Internet Explorer já fazia isso, mas não deixa de ser um diferencial em relação aos outros. É possível também "destacar" uma aba facilmente, transformando-a em uma janela separada. A partir da versão 3.5 do **Firefox** isso também é possível;</li>
<li>**Economia de memória** - Em pequenos testes que fiz, o **Chrome** usou cerca de 15% menos memória que o **Firefox** (v. 3.5.5);</li>
</ul>
<h2>Problemas</h2>
<p>Em 5 dias de uso (média de 10 horas / dia), <strong>Google Chrome</strong> se mostrou bastante estável e não travou nenhuma vez sequer. Um problema que se repetiu duas vezes foi não carregar o Gmail de maneira correta e foi necessário limpar o cache pra fazê-lo voltar ao normal. Fora isso, nenhum outro inconveniente do tipo.
O maior problema de todos é, de longe, a falta de extensions. Perde feito se comparado com o <strong>Firefox</strong> nesse item. Mas acredito que logo isso já não será um problema: já estão surgindo várias extensions, cada vez mais rapidamente.
Ah, vale citar que no Mac alguns recursos ainda não estão disponíveis, como extensions e pin tabs, segundo um amigo que está testando a mesma versão do browser pra Mac.</p>
<h2>Extensions</h2>
<p>Testei 4 extensions:</p>
<ul>
**GMail Checker (v. 1.3)** - mostra emails não lidos na inbox. Funcionou perfeitamente bem;
**Firebug Lite (v. 1.25**) - achei o máximo quando encontrei. Só que simplesmente não funciona (e não fiquei perdendo muito tempo tentando fazê-lo funcionar);
**Gtalk (by marcelozlot)** - Carregou minha lista de amigos, cheguei a ficar online, mas todo mundo ficava off. Tentei três vezes e desisti.
**Google Quick Scroll (v. 0.5.4)** - excelente extension. Quando você busca algo no Google e entra em determinada página, ele te mostra onde os termos da busca foram encontrados nas páginas. Realmente fantástico.
</ul>
<h2>Conclusão</h2>
<p>Embora ainda esteja na versão beta, já está perfeitament estável. Vou continuar usando como browser padrão, mas ainda não é hora de desistalar o <strong>Firefox</strong>. Apaguei o Opera da minha máquina e agora o <strong>Firefox</strong> é o browser secundário. Recomendo que todos testem por alguns dias, como eu fiz e não tirem conclusões precipitadas, afinal... é um browser que promete!</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="browser" /><category term="chrome" /><category term="google" /><category term="linux" />
    </entry>

    <entry>
      <title><![CDATA[Os vídeos de apresentações da Apple]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2009/07/26/os-videos-de-apresentacoes-da-apple?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2009-07-26T07:24:56.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2009/07/26/os-videos-de-apresentacoes-da-apple</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2009/07/26/os-videos-de-apresentacoes-da-apple">
        <![CDATA[<div xml:lang="pt-BR"><p>Estou lendo o livro <strong>"A cabeça de Steve Jobs"</strong>, de <strong>Leander Kahney</strong>. O capítulo 3 é
interessantíssimo e conta em detalhes a preparação perfecionista da apresentação do iMac, que foi
revelado ao mundo por Jobs em 1998.</p>
<p>Fiquei curioso e procurei a tal apresentação no YouTube, a qual recomendo se você se interessa em
apromorar técnicas para suas próprias apresentações ou mesmo se você é apenas entusiastas de
tecnologia:</p>
<p><a href="https://www.youtube.com/watch?v=0BHPtoTctDY"><img src="https://i.ytimg.com/vi_webp/0BHPtoTctDY/maxresdefault.webp" alt="YouTube video" /></a></p>
<p>Acabei assistindo várias apresentações da Apple, mas sem dúvidas a melhor de todas é a apresentação
do primeiro iPhone:</p>
<p><a href="https://www.youtube.com/watch?v=9hUIxyE2Ns8"><img src="https://i.ytimg.com/vi_webp/9hUIxyE2Ns8/maxresdefault.webp" alt="YouTube video" /></a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="apple" /><category term="mac" /><category term="imac" /><category term="macbook" /><category term="iphone" /><category term="steve-jobs" />
    </entry>

    <entry>
      <title><![CDATA[Java vs Ruby on Rails (by Rails Envy) [legendado]]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2009/07/15/java-vs-ruby-on-rails-by-rails-envy-legendado?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2009-07-15T00:08:45.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2009/07/15/java-vs-ruby-on-rails-by-rails-envy-legendado</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2009/07/15/java-vs-ruby-on-rails-by-rails-envy-legendado">
        <![CDATA[<div xml:lang="pt-BR"><p><a href="https://www.youtube.com/watch?v=SsYKd37r26s"><img src="https://i.ytimg.com/vi_webp/SsYKd37r26s/maxresdefault.webp" alt="YouTube video" /></a></p>
<ul>
<li>Tradução: <a href="http://www.loudnheavy.net/?page_id=41">Lucas Borges</a></li>
<li>Adaptação da legenda: <a href="https://twitter.com/lucascaton">Lucas Caton</a></li>
</ul>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="ruby" /><category term="rails" /><category term="java" />
    </entry>

    <entry>
      <title><![CDATA[Entendendo o desenvolvimento web]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2009/07/14/entendendo-o-desenvolvimento-web?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2009-07-14T03:33:35.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2009/07/14/entendendo-o-desenvolvimento-web</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2009/07/14/entendendo-o-desenvolvimento-web">
        <![CDATA[<div xml:lang="pt-BR"><p><del>Eu criei uma coleção de textos para auxiliar iniciantes no desenvolvimento web, ser dar foco em nenhuma tecnologia específica. O objetivo dos textos é mostrar o "caminho das pedras" pra quem está migrando do desenvolvimento desktop ou mesmo pra quem nunca desenvolveu antes.</del></p>
<p><del>Quem quiser colaborar, o projeto está no GitHub:</del>
<del><a href="https://github.com/lucascaton/understanding_the_web_development">https://github.com/lucascaton/understanding_the_web_development</a></del></p>
<hr>
<h3>Atualização - 07/03/2017</h3>
<p>Decidi <a href="https://www.lucascaton.com/2017/03/07/meu-curso-de-programacao">criar um curso</a>
completo sobre programação.
Fique à vontade para ver mais informações na página do curso:</p>
<p><a href="https://www.lucascaton.com/cursos/cplc/">www.lucascaton.com/pt-BR/cursos/cplc</a></p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="desenvolvimento-web" /><category term="web-development" />
    </entry>

    <entry>
      <title><![CDATA[Primeiro post]]></title>
      <summary><![CDATA[null]]></summary>
      <link href="https://www.lucascaton.com/pt-BR/2009/07/14/primeiro-post?utm_source=feed" rel="alternate" type="text/html" title="Lucas Caton" />
      <published>2009-07-14T01:53:09.000Z</published>
      <updated>2017-10-02T00:00:00.000Z</updated>
      <id>https://www.lucascaton.com/pt-BR/2009/07/14/primeiro-post</id>
      <content type="html" xml:base="https://www.lucascaton.com/pt-BR/2009/07/14/primeiro-post">
        <![CDATA[<div xml:lang="pt-BR"><p>Domínio registrado, hospedagem contratada e WordPress instalado: meu blog está pronto! \o/</p>
</div>]]>
      </content>
      <author><name>Lucas Caton</name></author>
      <category term="site" /><category term="blog" />
    </entry>
    </feed>