<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Unix and Me</title>
  <link href="http://blog.dmitrynix.com/atom.xml" rel="self"/>
  <link href="http://blog.dmitrynix.com/"/>
  <updated>2012-04-08T18:06:49+00:00</updated>
  <id>http://blog.dmitrynix.com/</id>
  <author>
    <name>Dmitry Nix</name>
    
  </author>

  
  <entry>
    <title>Bot IRC para Salvar Mensagens</title>
    <link href="http://blog.dmitrynix.com/bot-de-irc-para-salvar-mensagens/"/>
    <updated>2012-02-21T09:15:00+00:00</updated>
    <id>http://blog.dmitrynix.com/bot-de-irc-para-salvar-mensagens</id>
    <content type="html">&lt;p&gt;Usando dos dois últimos posts nós vamos fazer agora com que nosso bot de
irc armazene as mensagens.&lt;/p&gt;

&lt;p&gt;Primeiro um &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source 'http://rubygems.org'

gem 'cinch'
gem 'sqlite3'
gem 'activerecord', :require =&amp;gt; 'active_record'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Seguindo o post sobre &lt;a href=&quot;/activerecord-sem-rails&quot;&gt;ActiveRecord sem Rails&lt;/a&gt; nos
vamos criar os models, as migrations e o nosso arquivo &lt;code&gt;boot.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;boot.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'bundler'

Bundler.require :default

ActiveRecord::Base.establish_connection(
  :adapter =&amp;gt; 'sqlite3',
  :database =&amp;gt; 'development.sqlite3'
)

ActiveRecord::Migrator.migrate('./migrations')
require './quote'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;quote.rb&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Quote &amp;lt; ActiveRecord::Base
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;migrations/01_create_quotes.rb&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class CreateQuote &amp;lt; ActiveRecord::Migration
  def change
    create_table :quotes do |t|
      t.string :added_nick
      t.string :quote
      t.timestamps
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora seguindo o post sobre &lt;a href=&quot;/bot-irc-usando-ruby&quot;&gt;Bot IRC usando Ruby&lt;/a&gt;
vamos criar o &lt;code&gt;bot.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require './boot'
require 'cinch'

DEFAULT_CHANNEL = '#gurupi'

bot = Cinch::Bot.new do
  configure do |c|
    c.server = 'irc.freenode.net'
    c.channels = [DEFAULT_CHANNEL]
  end

  on :message, /^!add (.+)/ do |m, msg|
    Quote.create :added_nick =&amp;gt; m.user.nick, :quote =&amp;gt; msg
    m.reply 'Quote adicionado com sucesso.'
  end

  on :message, /^!quote (.+)/ do |m, nick|
    ch = Channel DEFAULT_CHANNEL
    quotes = Quote.where('quote like ?', &quot;%#{nick}%&quot;).to_a
    ch.send quotes[rand(quotes.count)].quote
  end

  on :message, '!count' do |m|
    m.reply &quot;Quote: #{Quote.count}&quot;
  end
end

bot.start
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora é só iniciar o &lt;code&gt;bot.rb&lt;/code&gt; para que ele entre no canal.&lt;/p&gt;

&lt;p&gt;Como de costume o código do post está em
&lt;a href=&quot;https://github.com/dmitrynix/bot-irc-and-active-record&quot;&gt;https://github.com/dmitrynix/bot-irc-and-active-record&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>ActiveRecord sem Rails</title>
    <link href="http://blog.dmitrynix.com/activerecord-sem-rails/"/>
    <updated>2012-02-19T23:21:00+00:00</updated>
    <id>http://blog.dmitrynix.com/activerecord-sem-rails</id>
    <content type="html">&lt;p&gt;Uma boa ferramenta do Rails é o ActiveRecord, sem dúvida ela pode
ajudar e muito, seja para o rails, para sinatra ou apenas para algum
script simples.&lt;/p&gt;

&lt;p&gt;Neste post nós vamos tentar usar o ActiveRecord apenas com um script bem
simples de Ruby.&lt;/p&gt;

&lt;p&gt;Como de costume um &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source 'http://rubygems.org'

gem 'sqlite3'
gem 'activerecord', :require =&amp;gt; 'active_record'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Vamos criar nosso model de mensagem no arquivo &lt;code&gt;message.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Message &amp;lt; ActiveRecord::Base
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nosso model precisa da base de dados, então vamos escrever uma
migration, para isso coloque o seguinte conteúdo no arquivo
&lt;code&gt;migrations/01_create_messages.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class CreateMessages &amp;lt; ActiveRecord::Migration
  def change
    create_table :messages do |t|
      t.string :text
      t.timestamps
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora vamos criar um arquivo &lt;code&gt;boot.rb&lt;/code&gt; que vai se encarregar de criar a
conexão com a base de dados, de fazer todas as migrações e também de
carregar todos os models:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'bundler'

Bundler.require :default

ActiveRecord::Base.establish_connection(
  :adapter =&amp;gt; 'sqlite3',
  :database =&amp;gt; 'development.sqlite3'
)

ActiveRecord::Migrator.migrate('./migrations')

require './message'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nos podemos testar isso tudo de várias formas, uma delas é usando o irb
como &quot;console&quot;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% irb -r ./boot.rb
==  CreateMessages: migrating
=================================================
-- create_table(:messages)
   -&amp;gt; 0.0014s
==  CreateMessages: migrated (0.0016s)
========================================

1.9.3p0 :001 &amp;gt; Message.create :text =&amp;gt; 'Teste 01'
 =&amp;gt; #&amp;lt;Message id: 1, text: &quot;Teste 01&quot;, created_at: &quot;2012-02-19
23:09:33&quot;, updated_at: &quot;2012-02-19 23:09:33&quot;&amp;gt;
1.9.3p0 :002 &amp;gt; Message.create :text =&amp;gt; 'Outro Teste'
 =&amp;gt; #&amp;lt;Message id: 2, text: &quot;Outro Teste&quot;, created_at: &quot;2012-02-19
23:09:41&quot;, updated_at: &quot;2012-02-19 23:09:41&quot;&amp;gt;
1.9.3p0 :003 &amp;gt; Message.count
 =&amp;gt; 2
1.9.3p0 :004 &amp;gt; Message.find(1).text
 =&amp;gt; &quot;Teste 01&quot;
1.9.3p0 :005 &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note acima que logo que o arquivo &lt;code&gt;boot.rb&lt;/code&gt; foi carregado foi feita
uma migração da base de dados, isso é exatamente o que esperamos que
aconteça.&lt;/p&gt;

&lt;p&gt;Agora vamos remover alguma coluna para testar novamente as migrations,
crie o arquivo &lt;code&gt;migrations/02_remove_messages_updated_at.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class RemoveMessagesUpdatedAt &amp;lt; ActiveRecord::Migration
  def change
    remove_column :messages, :updated_at
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Mais uma vez no console:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% irb -r ./boot.rb
==  RemoveMessagesUpdatedAt: migrating
========================================
-- remove_column(:messages, :updated_at)
   -&amp;gt; 0.0224s
==  RemoveMessagesUpdatedAt: migrated (0.0225s)
===============================

1.9.3p0 :001 &amp;gt; Message.first
 =&amp;gt; #&amp;lt;Message id: 1, text: &quot;Teste 01&quot;, created_at: &quot;2012-02-19
23:09:33&quot;&amp;gt;
1.9.3p0 :002 &amp;gt; Message.first.attributes
 =&amp;gt; {&quot;id&quot;=&amp;gt;1, &quot;text&quot;=&amp;gt;&quot;Teste 01&quot;, &quot;created_at&quot;=&amp;gt;2012-02-19 23:09:33
-0300}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O código está disponível no github em:
&lt;a href=&quot;https://github.com/dmitrynix/ruby-active-record&quot;&gt;https://github.com/dmitrynix/ruby-active-record&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Bot IRC usando Ruby</title>
    <link href="http://blog.dmitrynix.com/bot-irc-usando-ruby/"/>
    <updated>2012-02-17T19:31:00+00:00</updated>
    <id>http://blog.dmitrynix.com/bot-irc-usando-ruby</id>
    <content type="html">&lt;p&gt;Voltei a usar IRC depois de um tempo e como antes eu já ouvi falar muito
de bots em irc resolvi testar por mim mesmo.&lt;/p&gt;

&lt;p&gt;Após pesquisar um pouco achei o &lt;a href=&quot;https://github.com/cinchrb/cinch&quot;&gt;cinch&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The IRC Bot Building Framework&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Ou seja: &quot;Um framework de criação de bot IRC&quot;.&lt;/p&gt;

&lt;h1&gt;Mãos a obra&lt;/h1&gt;

&lt;p&gt;Primeiro instale a gem 'cinch' ou como eu prefiro cria um arquivo
&lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source 'http://rubygems.org'

gem 'cinch'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No nosso primeiro exemplo, vamo fazer o bot responder bom dia para todos
que derem bom dia:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'bundler/setup'

bot = Cinch::Bot.new do
  configure do |c|
    c.server = 'irc.freenode.net'
    c.channels = ['#gurupi']
  end

  on :message, /bom dia/i do |m|
    m.reply &quot;Bom dia, #{m.user.nick}&quot;
  end
end

bot.start
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pronto nosso bot já está ativo, basta usar.&lt;/p&gt;

&lt;p&gt;Note que estou usando expressão regular, ou seja, &lt;em&gt;bom dia&lt;/em&gt;, &lt;em&gt;Bom dia&lt;/em&gt; e
&lt;em&gt;Bom dia!&lt;/em&gt;, vão funcionar sem problemas ;).&lt;/p&gt;

&lt;p&gt;Estou tendo mais ideias para posts sobre IRC, fiquem ligados ;)&lt;/p&gt;

&lt;p&gt;E por falar em ligados entrem na irc.freenode.net na sala &lt;em&gt;##gurupi&lt;/em&gt; (com
dois &lt;code&gt;#&lt;/code&gt;).&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Ordenar Array em Javascript</title>
    <link href="http://blog.dmitrynix.com/ordenar-array-em-javascript/"/>
    <updated>2012-02-14T20:03:00+00:00</updated>
    <id>http://blog.dmitrynix.com/ordenar-array-em-javascript</id>
    <content type="html">&lt;p&gt;Recentemente tive um problema ao ordenar array em javascript, na verdade
o array era ordenado, porém não da &quot;forma padrão&quot; desta forma quando eu
rodava no firefox (entenda: teste de integração com capybara) e com o
webkit (entenda: teste de integração usando o capybara-webkit) retornava
valores diferentes.&lt;/p&gt;

&lt;p&gt;Vou usar o nodejs como console.&lt;/p&gt;

&lt;p&gt;Vamos ao primeiro exemplo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; var nomes = ['Bob', 'Jonh', 'Alice'];
undefined
&amp;gt; nomes.sort();
[ 'Alice', 'Bob', 'Jonh' ]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ordenação normal, mas agora com números:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; var numeros = [ 20, 2010, 300 ];
undefined
&amp;gt; numeros.sort();
[ 20, 2010, 300 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ops… erro. Tenta ordenar como string ao invés de número.&lt;/p&gt;

&lt;p&gt;Para &quot;remediar&quot; podemos passar uma função para a função &lt;code&gt;sort&lt;/code&gt;.
Essa função espera um retorno do tipo &lt;code&gt;-1&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt; ou &lt;code&gt;1&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-1&lt;/code&gt; (ou menor que zero) se o &lt;strong&gt;primeiro&lt;/strong&gt; argumento for menor que o &lt;strong&gt;segundo&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt; se os dois forem iguais;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1&lt;/code&gt; (ou maior que zero) se o &lt;strong&gt;segundo&lt;/strong&gt; argumento for maior que o &lt;strong&gt;primeiro&lt;/strong&gt;;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Uma solução bem verbosa é esta:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; numeros.sort(function(x, y){ return((x &amp;gt; y) ? -1 : ( x &amp;gt; y ? 1 : 0) ) });
[ 20, 300, 2010 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Uma solução &quot;menor&quot; é esta:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; numeros.sort(function(x, y) { return( x - y); });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Basicamente na subtração nos podemos ter os seguintes valores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;quando o x é menor que o y retorna um número negativo;&lt;/li&gt;
&lt;li&gt;quando x é igual a y retorna zero;&lt;/li&gt;
&lt;li&gt;e quando x é maior que y retorna um número positivo;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Meu caso era um pouco mais complicado, pois eu queria ordenar um array
semelhante a este:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; var arr = [[, 'ponto'] , [2, 'ponto e virgua'], [1, 'barra']];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ou seja: um array de array para ordenar pelo primeiro elemento (podendo
ainda este ser vazio).&lt;/p&gt;

&lt;p&gt;A solução:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; arr.sort(function(x, y){ if(!x[0]) { return(1) } else { return (x[0] - y[0]) } });
[ [ 1, 'barra' ],
  [ 2, 'ponto e virgua' ],
  [ , 'ponto' ] ]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sim o &quot;vazio&quot; fica por último, essa é a regra.&lt;/p&gt;

&lt;p&gt;Fonte: &lt;a href=&quot;view-source:http://www.javascriptkit.com/javatutors/arraysort.shtml&quot;&gt;Sorting a JavaScript array using array.sort()&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Eu Sou Um Fracasso</title>
    <link href="http://blog.dmitrynix.com/eu-sou-um-fracasso/"/>
    <updated>2012-02-02T18:10:00+00:00</updated>
    <id>http://blog.dmitrynix.com/eu-sou-um-fracasso</id>
    <content type="html">&lt;p&gt;Eu devia este post a uns 2-3 meses, mas como aconteceu muito neste tempo e
deixei outras jogadas ao relento esse é um bom momento para voltar a
escrever isto.&lt;/p&gt;

&lt;p&gt;Comecei a ser um fracasso na empresa que queria &quot;ver crescer&quot;. Até criei
um post com a lista do que se evitar o fracasso, mas não deu, o que
posso citar como erro é:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Supus que TODOS os &quot;homens de tecnologia&quot; pensassem semelhante a mim.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Só isto, sem apontar o dedo para ninguém. Quem me conhece sabe que não
conseguiria listar defeitos, não assim citando alguém para todos.&lt;/p&gt;

&lt;p&gt;Meu segundo fracasso neste período foi tentando andar sozinho.&lt;/p&gt;

&lt;p&gt;Trabalhei, não terminei o projeto (ainda está em andamento, mas depois
atualizo aqui) e ainda por cima sem receber o pagamento dos meus
trabalhos (para os curiosos é cerca de 1-2 meses de atraso).&lt;/p&gt;

&lt;p&gt;Não sei me impor (estou aprendendo x), não sei negociar, não sei dizer
não.&lt;/p&gt;

&lt;p&gt;O que resta? Resta um imenso #EpicFail para mim e só.&lt;/p&gt;

&lt;p&gt;Estava procurando um motivo de este post não ser um fracasso, e
encontrei, o que me alegra:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Saia da teoria e pratique mais.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;É extremamente fácil abrir uma empresa, muito fácil ser freela, mas eu
falhei nestas duas áreas, o motivo é simples: sei muito bem a teoria,
mas na prática.&lt;/p&gt;

&lt;p&gt;Para não dizer que eu sou um completo fracasso eu estou tentando uma
outra forma de &quot;viver&quot;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Ordem das Migrations?</title>
    <link href="http://blog.dmitrynix.com/ordem-das-migrations/"/>
    <updated>2012-01-22T14:03:00+00:00</updated>
    <id>http://blog.dmitrynix.com/ordem-das-migrations</id>
    <content type="html">&lt;p&gt;Nota: este post está sobre a tag &lt;a href=&quot;/categories/git/&quot;&gt;git&lt;/a&gt;, pois estou simulando um &quot;conflito&quot;
usando git e rails&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% rails g model teams name:string
% rails g model tasks name:string
% rails g model user name:string
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Para ficar melhor para ver mudei as migrations para:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;check_migration_order % ls -1 db/migrate
20100105101918_create_tasks.rb
20110105101832_create_teams.rb
20120105102143_create_users.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O processo normal seria roda uma migration aqui, porém eu &quot;apaguei&quot; a &lt;strong&gt;2011&lt;/strong&gt; e rodei as migrations:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;check_migration_order % rake db:migrate
== CreateTasks: migrating ====================================================
-- create_table(:tasks)
-&amp;gt; 0.0016s
== CreateTasks: migrated (0.0017s) ===========================================

== CreateUsers: migrating ====================================================
-- create_table(:users)
-&amp;gt; 0.0015s
== CreateUsers: migrated (0.0016s) ===========================================
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora eu adicionei a migration &lt;strong&gt;2011&lt;/strong&gt; justamente para simular, por
exemplo, como se alguém tivesse mandado a migration posteriormente via
git.&lt;/p&gt;

&lt;p&gt;Rodando o &lt;code&gt;rake db:migrate&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;check_migration_order % rake db:migrate
== CreateTeams: migrating ====================================================
-- create_table(:teams)
-&amp;gt; 0.0016s
== CreateTeams: migrated (0.0018s) ===========================================
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ou seja, o &lt;em&gt;ActiveRecord&lt;/em&gt; não faz as migrations em ordem e descarta as
que já passou (como muitos pensam E como era até certas versões), ele
verifica as que não foram feitas e, claro, dando preferência para a ordem
no nome.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Sinatra e Capybara</title>
    <link href="http://blog.dmitrynix.com/sinatra-e-capybara/"/>
    <updated>2011-11-13T18:59:00+00:00</updated>
    <id>http://blog.dmitrynix.com/sinatra-e-capybara</id>
    <content type="html">&lt;p&gt;Seguindo nosso projeto anterior sobre Sinatra
&lt;a href=&quot;/hello-sinatra/&quot;&gt;Hello Sinatra&lt;/a&gt; vamos agora usar o
&lt;a href=&quot;https://github.com/jnicklas/capybara&quot;&gt;Capybara&lt;/a&gt; para fazer os &quot;testes de
aceitação&quot;.&lt;/p&gt;

&lt;h1&gt;Adicionar a gem&lt;/h1&gt;

&lt;p&gt;O nosso projeto é baseado no post &lt;a href=&quot;/hello-sinatra/&quot;&gt;Hello Sinatra ;)&lt;/a&gt;,
agora vamos pegar o projeto e adicionar a gem do capybara:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% git clone git://github.com/dmitrynix/sinatra-demo-app-post.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Adicionar a gem no &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source 'http://rubygems.org'

gem 'sinatra'

group :development, :test do
  gem 'rspec'
  gem 'rack-test', :require =&amp;gt; 'rack/test'
  gem 'capybara'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E executar o &lt;code&gt;bundle install&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Primeiro teste&lt;/h2&gt;

&lt;p&gt;Nosso exemplo será de um formulário simples que a pessoa vai escrever uma
mensagem e ela aparecerá após ela enviar para o servidor.&lt;/p&gt;

&lt;p&gt;Como já temos um projeto basta adicionar ao &lt;code&gt;spec_helper.rb&lt;/code&gt; o conteúdo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'capybara/rspec'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Esse require, claro, deve ser depois do require das rubygems ou depois do
require do bundler.&lt;/p&gt;

&lt;p&gt;E dizer ao capybara qual a nossa app rack:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Capybara.app = DemoApp::Application
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora vamos ao nosso primeiro spec:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'spec_helper'

feature 'the message process' do
  it 'expose message' do
    visit '/'

    fill_in 'Message', :with =&amp;gt; 'Hi!'

    click_button 'Message!'

    page.should have_content 'Sua mensagem foi &quot;Hi!&quot;'
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Na sequencia&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visite a url '/' da aplicação;&lt;/li&gt;
&lt;li&gt;Preencha o input do label correspondente com o nome &quot;Message&quot;;&lt;/li&gt;
&lt;li&gt;Click no butão &lt;code&gt;&quot;Message!&quot;&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;No final deste processo deve ter a nossa mensagem.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Certamente ele irá falhar:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% rspec spec/demo_app_spec.rb
F

Failures:

  1) the message process expose message
     Failure/Error: within(&quot;#message&quot;) do
     ArgumentError:
       rack-test requires a rack application, but none was given
     # (eval):2:in `find'
     # ./spec/demo_app_spec.rb:5:in `block (2 levels) in &amp;lt;top (required)&amp;gt;'

Finished in 0.22032 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/demo_app_spec.rb:4 # the message process expose message
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora vamos modificar nossa aplicação para o spec:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module DemoApp
  class Application &amp;lt; Sinatra::Base
    get '/' do
&amp;lt;&amp;lt;END
&amp;lt;form action=&quot;/&quot; method=&quot;post&quot;&amp;gt;
  &amp;lt;label for=&quot;message&quot;&amp;gt;Message&amp;lt;/label&amp;gt;
  &amp;lt;input type=&quot;text&quot; name=&quot;message&quot; id=&quot;message&quot;&amp;gt;
  &amp;lt;button&amp;gt;Message!&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
END
    end

    post '/' do
      &quot;Sua mensagem foi \&quot;#{params[:message]}\&quot;&quot;
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E ele irá passar:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% rspec spec/demo_app_spec.rb
.

Finished in 0.36823 seconds
1 example, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Alguns preferem escrever os specs dentro de &lt;code&gt;spec/integration&lt;/code&gt;, mas eu já
vi também em &lt;code&gt;spec/acceptance&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como de costume o projeto está no github:
&lt;a href=&quot;https://github.com/dmitrynix/sinatra-and-capybara-demo&quot;&gt;sinatra-and-capybara-demo&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>MongoDB e Ruby</title>
    <link href="http://blog.dmitrynix.com/mongodb-e-ruby/"/>
    <updated>2011-10-27T16:12:00+00:00</updated>
    <id>http://blog.dmitrynix.com/mongodb-e-ruby</id>
    <content type="html">&lt;h1&gt;ORM no Rails&lt;/h1&gt;

&lt;p&gt;No Rails eu uso o &lt;a href=&quot;http://mongoid.org&quot;&gt;Mongoid&lt;/a&gt; como ORM.&lt;/p&gt;

&lt;p&gt;Sua configuração é simples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adicionar a gem &lt;em&gt;mongoid&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;Rodar &lt;code&gt;bundle install&lt;/code&gt; e;&lt;/li&gt;
&lt;li&gt;Criar o arquivo de configuração &lt;code&gt;config/mongoid.yml&lt;/code&gt; ou rodar o comando
&lt;code&gt;rails g mongoid:config&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Os models ficariam semelhante a isso:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Customer
  include Mongoid::Document
  include Mongoid::Timestamps

  field :name, :type =&amp;gt; String
  field :active, :type =&amp;gt; Boolean, :default =&amp;gt; false
  field :priority, :type =&amp;gt; Integer, :default =&amp;gt; 1
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Praticamente não há diferença quando substitui o ActiveRecord.&lt;/p&gt;

&lt;p&gt;Uma outra configuração seria tirar o &quot;require all&quot; do arquivo
&lt;code&gt;config/application.rb&lt;/code&gt; e usar:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'action_controller/railtie'
require 'action_mailer/railtie'
require 'active_resource/railtie'
require 'rails/test_unit/railtie'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E mais em baixo deste arquivo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;config.generators do |g|
  g.orm :mongoid
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pronto, Rails configurado!&lt;/p&gt;

&lt;h2&gt;Rails, Mongoid e Heroku&lt;/h2&gt;

&lt;p&gt;Quando usando git eu prefiro não colocar o &lt;code&gt;mongoid.yml&lt;/code&gt; ou &lt;code&gt;database.yml&lt;/code&gt;
ou qualquer outro de configuração de base de dados, então em um projeto
que eu tenho no heroku eu apenas criei o arquivo
&lt;code&gt;config/initializers/heroku.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if ENV['MONGOHQ_URL']
  Mongoid.configure do |config|
    uri = URI.parse(ENV['MONGOHQ_URL'])
    connection = Mongo::Connection.from_uri(ENV['MONGOHQ_URL'])
    db = connection.db(uri.path.gsub(/^\//, ''))
    config.master = db
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Sinatra&lt;/h1&gt;

&lt;p&gt;No sinatra só precisa colocar em algum ponto da app a linha:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Mongoid.load!('/path/to/mongoid.yml')
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E, claro, fazer o require dos models.&lt;/p&gt;

&lt;h1&gt;Carrierwave&lt;/h1&gt;

&lt;p&gt;O Carrierwave pode usar o mesmo banco do mongoid para armazenas os arquivos.&lt;/p&gt;

&lt;p&gt;É necessário antes adicionar a gem &lt;code&gt;carrierwave-mongoid&lt;/code&gt; para o projeto:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Gemfile
gem 'carrierwave-mongoid', :require =&amp;gt; 'carrierwave/mongoid'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E o arquivo de configuração, &lt;code&gt;config/initializers/carrierwave.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CarrierWave.configure do |config|
  config.storage = :grid_fs
  config.grid_fs_connection = Mongoid.database
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Mas claro, também dá para usar outro banco:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CarrierWave.configure do |config|
  config.grid_fs_database = 'my_mongo_database'
  config.grid_fs_host = 'mongo.example.com'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No sinatra é semelhante, configurar &lt;code&gt;Gemfile&lt;/code&gt; e &quot;executar&quot; o código ruby
antes de carregar a aplicação (ou no config).&lt;/p&gt;

&lt;h2&gt;Grid&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt; mongo_con = Mongo::Connection.new(
   gridfs_conf['host'],
   (gridfs_conf['port'] || 27017)
 ).db(gridfs_conf['database'])

 key = params[:arquivo]

 Mongo::GridFileSystem.new(mongo_con).open(key, 'r') do |file|
   file.read
 end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No exemplo acima as últimas linha iram fazer a &quot;query&quot; no banco de dados
e retornar um objeto arquivo, o &lt;code&gt;read&lt;/code&gt; vai mostrar o conteúdo do arquivo.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Backup+Restore do MySQL</title>
    <link href="http://blog.dmitrynix.com/backup-restore-do-mysql/"/>
    <updated>2011-09-29T19:57:00+00:00</updated>
    <id>http://blog.dmitrynix.com/backup-restore-do-mysql</id>
    <content type="html">&lt;p&gt;Isto é algo que eu sempre esqueço como se faz (sério).&lt;/p&gt;

&lt;h1&gt;Backup&lt;/h1&gt;

&lt;p&gt;Se for na máquina local:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% mysqldump -u usuario -p banco_de_dados &amp;gt; nome_do_arquivo.sql
Enter password:
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Se não usar a senha, basta remover a opção &lt;code&gt;-p&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;E se quiser por a senha na linha de comando:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% mysqldump -u usuario --password='minha_senha' banco &amp;gt; arquivo.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Backup Remoto&lt;/h2&gt;

&lt;p&gt;Como você notou o backup é gerado na saída padrão e feito um
redirecionamento para &lt;code&gt;arquivo.sql&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% ssh usuario@site-remoto.com 'mysqldump -u usuario --password=&quot;minha_senha&quot; banco' | gzip &amp;gt; arquivo.sql.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No exemplo acima nós acessamos o servidor remoto via &lt;code&gt;ssh&lt;/code&gt; e executamos o
backup &lt;em&gt;com compactação&lt;/em&gt; (com o comando &lt;code&gt;gzip&lt;/code&gt;), mas a &quot;saída padrão&quot; é na
nossa máquina e com ela jogamos no arquivo &lt;code&gt;arquivo.sql.gz&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mas atenção: se o banco de dados for grande você vai usar muita banda.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para bancos pequenos eu faço o comando acima, mas em banco de dados grandes
entro no servidor via ssh, faço o backup compactado e coloco para download
via http ou ftp.&lt;/p&gt;

&lt;h1&gt;Restauação (Restore)&lt;/h1&gt;

&lt;p&gt;O comando para restauração é o mesmo de acesso a &quot;shell&quot; do mysql, com o
&lt;code&gt;arquivo_de_backup.sql&lt;/code&gt; em mãos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% mysql -u usuario --password='senha' banco &amp;lt; arquivo.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Se você ver o erro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ERROR 1049 (42000): Unknown database 'vclientes_production'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;É por que, como a tradução sugere, não existe a base de dados. Neste caso,
é preciso entrar no mysql e executar o comando para criar a base de dados,
com o &lt;code&gt;create database banco&lt;/code&gt;;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 5.1.49-1ubuntu8.1 (Ubuntu)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&amp;gt; create database banco;
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ou se preferir, basta executar direto no shell:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% echo 'create database banco' | mysql -u usuario --password='senha'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Se o arquivo estiver compactado via gzip, basta descompactar e mandar para
o mysql:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% cat arquivo.sql.gz | gunzip | mysql -u usuario banco
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Restauração Remota para Local Direta&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;% ssh usario@host-remoto.com 'mysqldump -u usuario --password=&quot;senha&quot; banco | gzip' | gunzip | mysql -u usuario banco
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Na linha acima o backup é feito e compactado no servidor remoto, e na nossa
máquina ele é descompactado e usado para restauração.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Orientação a Objetos com Ruby</title>
    <link href="http://blog.dmitrynix.com/orientacao-a-objetos-com-ruby/"/>
    <updated>2011-09-22T20:10:00+00:00</updated>
    <id>http://blog.dmitrynix.com/orientacao-a-objetos-com-ruby</id>
    <content type="html">&lt;p&gt;Como você leu no primeiro post fazendo uma &lt;a href=&quot;/ruby/&quot;&gt;Introdução a Ruby&lt;/a&gt;,
Ruby é uma linguagem &lt;em&gt;orientada a objetos&lt;/em&gt;, significa?&lt;/p&gt;

&lt;p&gt;Significa que usando Ruby pode-se &quot;mapear&quot; os objetos do mundo real para os
seus programas.&lt;/p&gt;

&lt;h1&gt;Classes e Objetos&lt;/h1&gt;

&lt;p&gt;As classes constroem objetos com o método &lt;code&gt;new&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% irb
ruby-1.8.7-p352 :001 &amp;gt; String.new(&quot;teste&quot;)
=&amp;gt; &quot;teste&quot; 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O método &lt;code&gt;new&lt;/code&gt; é mapeado para o método &lt;code&gt;initialize&lt;/code&gt; da classe:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Animal
  def initialize(nome)
    @nome = nome
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Para chamar usando o &lt;code&gt;irb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% irb -r ./animal.rb
ruby-1.8.7-p352 :001 &amp;gt; animal = Animal.new('nome')
=&amp;gt; #&amp;lt;Animal:0x7f679fa1e0d8 @nome=&quot;nome&quot;&amp;gt;
ruby-1.8.7-p352 :002 &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Aproveitando vamos fazer perguntas ao objeto:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :002 &amp;gt; animal.class
=&amp;gt; Animal
ruby-1.8.7-p352 :003 &amp;gt; animal.instance_variables
=&amp;gt; [&quot;@nome&quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Variáveis&lt;/h2&gt;

&lt;p&gt;Ao contrário de linguagens estáticas, em Ruby não há relação entre a classe
e as variáveis do objeto. As variáveis de instância só existem quando lhes
é dado um valor, baseado nisso você pode ter 2 objetos de mesma classe
com variáveis de instância diferentes.&lt;/p&gt;

&lt;p&gt;Observe o código abaixo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Animal
  def initialize(nome)
    @nome = nome
    @um_gato = 'sim' if nome == 'gato'
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% irb -r ./animal.rb
ruby-1.8.7-p352 :001 &amp;gt; gato = Animal.new('gato')
=&amp;gt; #&amp;lt;Animal:0x7f1d386e87d0 @um_gato=&quot;sim&quot;, @nome=&quot;gato&quot;&amp;gt;
ruby-1.8.7-p352 :002 &amp;gt; gato.instance_variables
=&amp;gt; [&quot;@um_gato&quot;, &quot;@nome&quot;]
ruby-1.8.7-p352 :003 &amp;gt; macaco = Animal.new('macaco')
=&amp;gt; #&amp;lt;Animal:0x7f1d386d79f8 @nome=&quot;macaco&quot;&amp;gt;
ruby-1.8.7-p352 :004 &amp;gt; macaco.instance_variables
=&amp;gt; [&quot;@nome&quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Métodos&lt;/h2&gt;

&lt;p&gt;Assim como as classes tem seus métodos os objetos também tem, para ver a
lista de métodos de um objeto:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :006 &amp;gt; gato.methods
=&amp;gt; [&quot;inspect&quot;, &quot;tap&quot;, &quot;clone&quot;, &quot;public_methods&quot;, &quot;__send__&quot;, &quot;object_id&quot;, &quot;instance_variable_defined?&quot;, &quot;equal?&quot;, &quot;freeze&quot;, &quot;extend&quot;, &quot;send&quot;, &quot;methods&quot;, &quot;hash&quot;, &quot;dup&quot;, &quot;to_enum&quot;, &quot;instance_variables&quot;, &quot;eql?&quot;, &quot;instance_eval&quot;, &quot;id&quot;, &quot;singleton_methods&quot;, &quot;taint&quot;, &quot;enum_for&quot;, &quot;frozen?&quot;, &quot;instance_variable_get&quot;, &quot;instance_of?&quot;, &quot;display&quot;, &quot;to_a&quot;, &quot;method&quot;, &quot;type&quot;, &quot;instance_exec&quot;, &quot;protected_methods&quot;, &quot;==&quot;, &quot;===&quot;, &quot;instance_variable_set&quot;, &quot;kind_of?&quot;, &quot;respond_to?&quot;, &quot;to_s&quot;, &quot;class&quot;, &quot;__id__&quot;, &quot;tainted?&quot;, &quot;=~&quot;, &quot;private_methods&quot;, &quot;untaint&quot;, &quot;nil?&quot;, &quot;is_a?&quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E para filtrar:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :002 &amp;gt; gato.methods.grep /ins/
=&amp;gt; [&quot;inspect&quot;, &quot;instance_variable_defined?&quot;, &quot;instance_variables&quot;, &quot;instance_eval&quot;, &quot;instance_variable_get&quot;, &quot;instance_of?&quot;, &quot;instance_exec&quot;, &quot;instance_variable_set&quot;] 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Se você abrir o interpretador Ruby, verá que o Ruby armazena as variáveis
de instância no objeto e um &quot;link&quot; para a classe, ou seja, &lt;strong&gt;as variáveis
de instância no objeto e os métodos na classe&lt;/strong&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Animal
  def initialize(nome)
    @nome = nome
    @um_gato = 'sim' if nome == 'gato'
  end

  def qual_o_nome
    @nome
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Como você viu o método &lt;code&gt;qual_o_nome&lt;/code&gt; é de instância, ou seja, só existe
quando um objeto é criado, para exemplificar vamos filtrar os métodos
de instância dos de classe:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :007 &amp;gt; gato.methods.grep /qual/
=&amp;gt; [&quot;equal?&quot;, &quot;qual_o_nome&quot;]
ruby-1.8.7-p352 :008 &amp;gt; Animal.methods.grep /qual/
=&amp;gt; [&quot;equal?&quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Para criar o método de classe usa-se o &lt;code&gt;self&lt;/code&gt; na definição do método:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Animal
  def initialize(nome)
    @nome = nome
  end

  def qual_o_nome
    @ja_foi_mostrado_o_nome = 'sim'
    @nome
  end

  def self.qual_o_nome
    &quot;Eu sou uma classe e ainda nao tenho nome&quot;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Verificando os métodos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% irb -r ./animal
ruby-1.8.7-p352 :001 &amp;gt; Animal.qual_o_nome
=&amp;gt; &quot;Eu sou uma classe e ainda nao tenho nome&quot;
ruby-1.8.7-p352 :002 &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Um pouco sobre herança&lt;/h2&gt;

&lt;p&gt;Quando um método é chamado na instância de um objeto, o interpretador
procura pelo método na sua classe e &quot;sobe&quot; na hierarquia até encontrar o
método.&lt;/p&gt;

&lt;p&gt;Por exemplo, agora temos estas 3 classes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Animal
  def initialize(nome)
    @nome = nome
    @tipo = 'animal'
  end

  def meu_tipo
    @tipo
  end
end

class Macaco &amp;lt; Animal
  def initialize(nome)
    @nome = nome
    @tipo = 'macaco'
  end
end

class Gato &amp;lt; Animal
  def initialize(nome)
    @nome = nome
    @tipo = 'gato'
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Testando:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% irb -r ./animal.rb
ruby-1.8.7-p352 :001 &amp;gt; animal = Animal.new('tipo generico de animal')
=&amp;gt; #&amp;lt;Animal:0x7f11ce5d93a0 @tipo=&quot;animal&quot;, @nome=&quot;tipo generico de animal&quot;&amp;gt; 
ruby-1.8.7-p352 :002 &amp;gt; animal.meu_tipo
=&amp;gt; &quot;animal&quot;
ruby-1.8.7-p352 :003 &amp;gt; macaco = Macaco.new('nome do macaco')
=&amp;gt; #&amp;lt;Macaco:0x7f11ce5c7768 @tipo=&quot;macaco&quot;, @nome=&quot;nome do macaco&quot;&amp;gt;
ruby-1.8.7-p352 :004 &amp;gt; macaco.meu_tipo
=&amp;gt; &quot;macaco&quot;
ruby-1.8.7-p352 :005 &amp;gt; gato = Gato.new('um gato')
=&amp;gt; #&amp;lt;Gato:0x7f11ce5b6d00 @tipo=&quot;gato&quot;, @nome=&quot;um gato&quot;&amp;gt;
ruby-1.8.7-p352 :004 &amp;gt; gato.meu_tipo
=&amp;gt; &quot;gato&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ao inicializar uma instância de cada um dos tipos você verá que cada um
vai responder pelo método &lt;code&gt;meu_tipo&lt;/code&gt;, porém somente a classe &lt;code&gt;Animal&lt;/code&gt;
define o método &lt;code&gt;meu_tipo&lt;/code&gt; as outras duas classes herdam este método.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Ruby</title>
    <link href="http://blog.dmitrynix.com/ruby/"/>
    <updated>2011-09-15T22:27:00+00:00</updated>
    <id>http://blog.dmitrynix.com/ruby</id>
    <content type="html">&lt;p&gt;Vez ou outra aparece alguém perguntando, ou melhor, pedindo &quot;ensina
rails?&quot;.&lt;/p&gt;

&lt;p&gt;Bom a linguagem e framework da moda inspira a muitos e as pessoas creem
que vão do dia para noite: fazer o próximo imenso programa que todo mundo
vai usar e vai pagar por isso e que vai ficar milionário.&lt;/p&gt;

&lt;p&gt;Vou logo avisando, antes de você pegar projeto para fazer com rails estude
muito o framerowk e principalmente a linguagem Ruby.&lt;/p&gt;

&lt;p&gt;Nos tópicos abaixo explico alguns detalhes, isso só faz parte do ponta pé
inicial.&lt;/p&gt;

&lt;h1&gt;Introdução&lt;/h1&gt;

&lt;p&gt;Segundo a wikipedia &lt;a href=&quot;http://en.wikipedia.org/wiki/Ruby_(programming_language)&quot;&gt;Ruby&lt;/a&gt;
é originada no Japão durante a década de 90, desenvolvida por
&lt;a href=&quot;http://en.wikipedia.org/wiki/Yukihiro_Matsumoto&quot;&gt;Yukihiro &quot;Matz&quot;&lt;/a&gt; uma
linguagem dinâmica, orientada a objetos com syntax inspirada por
&lt;a href=&quot;http://en.wikipedia.org/wiki/Perl&quot;&gt;Perl&lt;/a&gt; com algumas características de
&lt;a href=&quot;http://en.wikipedia.org/wiki/Smalltalk&quot;&gt;Smalltalk&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O &quot;padrão&quot; 1.8.7 foi desenvolvido em C pelo Matz. Não há exatamente um
padrão Ruby, além do 1.8.7 existe JRuby, MacRuby e outros padrões da
linguagem.&lt;/p&gt;

&lt;p&gt;Antes ainda de começar com código gostaria de falar um pouco sobre sua
&quot;filosofia&quot;: ainda segundo Matz Ruby é desenvolvido com foco na
produtividade do programador e não na otimização da máquina ou na
&quot;velocidade do código&quot;. Pense nisso ao escrever código Ruby ;)&lt;/p&gt;

&lt;h1&gt;Script ou IRB?&lt;/h1&gt;

&lt;p&gt;Ruby é uma linguagem de script e desta forma para nosso primeiro script:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby

puts &quot;Script em ruby&quot;
puts &quot;Soma #{1+2}&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;Salve-os e execute-os assim:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% ruby script.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Para nossos teste nos vamos usar mais o IRB que é um shell (ou
interpretador) de código, semelhante ao que acontece com shell bash, assim
que teclarmos enter a linha escrita será executada:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :004 &amp;gt; puts &quot;Interpretador Ruby&quot;
Interpretador Ruby
=&amp;gt; nil
ruby-1.8.7-p352 :005 &amp;gt; puts &quot;soma: #{1+1}&quot;
soma: 2
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Tipos em Ruby&lt;/h1&gt;

&lt;h2&gt;String&lt;/h2&gt;

&lt;p&gt;Uma string é qualquer valor dentro de um &lt;code&gt;&quot;&lt;/code&gt; ou &lt;code&gt;'&lt;/code&gt;, dentro de &lt;code&gt;&quot;&lt;/code&gt; podem
existir variáveis, semelhante a última linha do nosso primeiro script.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :002 &amp;gt; &quot;string&quot;
=&amp;gt; &quot;string&quot;
ruby-1.8.7-p352 :003 &amp;gt; puts &quot;string&quot;
string
=&amp;gt; nil
ruby-1.8.7-p352 :004 &amp;gt; puts &quot;string#{1+10}&quot;
string11
=&amp;gt; nil
ruby-1.8.7-p352 :005 &amp;gt; puts 'string#{1+10}'
string#{1+10}
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Integers (Inteiros)&lt;/h2&gt;

&lt;p&gt;Sobre inteiros:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :005 &amp;gt; 1+1
=&amp;gt; 2
ruby-1.8.7-p352 :006 &amp;gt; 10/2
=&amp;gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Além de inteiros você pode tentar usar também os &quot;Floats&quot;: &lt;code&gt;1.0&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Arrays&lt;/h2&gt;

&lt;p&gt;Arrays são criados usando [] ou %w(), exemplo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :007 &amp;gt; [&quot;1&quot;, &quot;2&quot;]
=&amp;gt; [&quot;1&quot;, &quot;2&quot;]
ruby-1.8.7-p352 :008 &amp;gt; %w(1 2 3 )
=&amp;gt; [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O mais interessante dos arrays em Ruby é que pode ser uma mistura de
diversos tipos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :009 &amp;gt; [1, &quot;2&quot;]
=&amp;gt; [1, &quot;2&quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ao invés do que acontece com outras linguagem que se for um Array de
inteiros você só pode colocar inteiros.&lt;/p&gt;

&lt;h2&gt;Hash&lt;/h2&gt;

&lt;p&gt;Hash é mais ou menos como Arrays indexados.&lt;/p&gt;

&lt;p&gt;Você define um hash assim:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{ :idx =&amp;gt; 'valor' }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E seguindo os arrays eles podem ser de diversos tipo, o índice ou o valor:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{ :idx =&amp;gt; 'valor', 1 =&amp;gt; 'um', 'dois' =&amp;gt; 2 }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A nova syntax no ruby19 é definida da seguinte forma:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{ idx: =&amp;gt; 'valor' }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E não foge a regra mistura de estilos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{ um: 1, :dois =&amp;gt; 2, 'tres' =&amp;gt; 3, 4 =&amp;gt; 'quatro' }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Mais um fato interessante dos Hashs é que o índice é na verdade &quot;salvo
internamente&quot; como um hash em inteiro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :007 &amp;gt; a = { :a =&amp;gt; :b, :c =&amp;gt; :d }
=&amp;gt; {:c=&amp;gt;:d, :a=&amp;gt;:b}
ruby-1.8.7-p352 :008 &amp;gt; a.keys.map(&amp;amp;:hash)
=&amp;gt; [237308, 335388]
ruby-1.8.7-p352 :009 &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ou seja, quando você quer recuperar a chave &lt;code&gt;:a&lt;/code&gt; o Ruby transforma o &lt;code&gt;:a&lt;/code&gt;
em hash:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :010 &amp;gt; :a.hash
=&amp;gt; 335388
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Tornando assim a busca mais rápida.&lt;/p&gt;

&lt;h1&gt;Laços&lt;/h1&gt;

&lt;h2&gt;if else end&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;if else end&lt;/code&gt; funciona da mesma forma como em outras linguagens:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :011 &amp;gt; a = 1
=&amp;gt; 1
ruby-1.8.7-p352 :012 &amp;gt; if a == 1
ruby-1.8.7-p352 :013?&amp;gt;   puts 'numero um'
ruby-1.8.7-p352 :014?&amp;gt; else
ruby-1.8.7-p352 :015 &amp;gt;   puts 'outro numero'
ruby-1.8.7-p352 :016?&amp;gt; end
numero um
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O que eu acho mais interessante é que os parenteses é de uso opcional:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if(1 == 1) { puts &quot;ok&quot; }
if 1 == 1 { puts &quot;ok&quot; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E seguindo os fatos extraordinários:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :017 &amp;gt; puts 'numero um' if a == 1
numero um
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Case&lt;/h2&gt;

&lt;p&gt;Fugindo também o padrão o &lt;code&gt;case&lt;/code&gt; aceita diversos tipos como comparação:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :023 &amp;gt; a = 1
=&amp;gt; 1
ruby-1.8.7-p352 :024 &amp;gt; case a
ruby-1.8.7-p352 :025?&amp;gt;   when 1
ruby-1.8.7-p352 :026?&amp;gt;     puts 'numero 1'
ruby-1.8.7-p352 :027?&amp;gt;   when &quot;1&quot;
ruby-1.8.7-p352 :028?&amp;gt;     puts 'string 1'
ruby-1.8.7-p352 :029?&amp;gt;   else
ruby-1.8.7-p352 :030 &amp;gt;     puts 'nenhum'
ruby-1.8.7-p352 :031?&amp;gt;   end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;e:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :001 &amp;gt; a = '1'
=&amp;gt; &quot;1&quot;
ruby-1.8.7-p352 :002 &amp;gt; case a
ruby-1.8.7-p352 :003?&amp;gt;   when 1
ruby-1.8.7-p352 :004?&amp;gt;     puts 'numero 1'
ruby-1.8.7-p352 :005?&amp;gt;   when '1'
ruby-1.8.7-p352 :006?&amp;gt;     puts 'string 1'
ruby-1.8.7-p352 :007?&amp;gt;   else
ruby-1.8.7-p352 :008 &amp;gt;     puts 'nenhum'
ruby-1.8.7-p352 :009?&amp;gt;   end
string 1
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;While&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :011 &amp;gt; a = 1; while a &amp;lt; 5 ; a += 1 ; puts a; end
2
3
4
5
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Until&lt;/h2&gt;

&lt;p&gt;É mais ou menos o &quot;contrário do &lt;code&gt;while&lt;/code&gt;&quot;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :013 &amp;gt; a = 1; until a &amp;lt; 5 ; a += 1 ; puts a; end
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ou&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :014 &amp;gt; a = 1; until a &amp;gt; 5 ; a += 1 ; puts a; end
2
3
4
5
6
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;x.times?&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;x.times&lt;/code&gt; é mais um loop &quot;fácil&quot; no rails, ele executa o mesmo que tiver
no bloco por &lt;em&gt;x&lt;/em&gt; vezes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :017 &amp;gt; 3.times { puts 'uma vez' }
uma vez
uma vez
uma vez
=&amp;gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ao invés de usar um número fixo, pode-se facilmente usar uma variável:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :018 &amp;gt; vezes = 5
=&amp;gt; 5
ruby-1.8.7-p352 :019 &amp;gt; vezes.times { puts 'mais vezes' }
mais vezes
mais vezes
mais vezes
mais vezes
mais vezes
=&amp;gt; 5
ruby-1.8.7-p352 :020 &amp;gt; vezes = 2
=&amp;gt; 2
ruby-1.8.7-p352 :021 &amp;gt; vezes.times { puts 'menos vezes' }
menos vezes
menos vezes
=&amp;gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Each?&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;each&lt;/code&gt; é um laço que facilmente substitui o laço &lt;code&gt;for&lt;/code&gt; (por falar em
&lt;code&gt;for&lt;/code&gt; eu nem lembro mais como se usa oO):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby-1.8.7-p352 :002 &amp;gt; %w(1 2 3).each { |string| puts string }
1
2
3
=&amp;gt; [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;]
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title>Importando Comentários com o disqus.com</title>
    <link href="http://blog.dmitrynix.com/importando-comentarios-com-o-disqus-com/"/>
    <updated>2011-09-15T08:16:00+00:00</updated>
    <id>http://blog.dmitrynix.com/importando-comentarios-com-o-disqus-com</id>
    <content type="html">&lt;p&gt;Segundo o &lt;a href=&quot;http://disqus.com&quot;&gt;disqus.com&lt;/a&gt; sobre si mesmo:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Disqus is all about changing the way people think about discussion on the
web. We're big believers in the conversations and communities that form
on blogs and other sites.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;ou&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Disqus é como mudar a forma como as pessoas pensam sobre &quot;discussão&quot; na
internet. Acreditamos em grandes conversas e nas comunidades que se
formam em blogs e outros sites.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Como parte da mudança entre site estático, wordpress, app própria e por fim
octopress tenho levado comigo além, claro, dos artigos, também todos os
comentários.&lt;/p&gt;

&lt;p&gt;Como ferramenta &quot;hacker&quot; o octopress não &quot;permite&quot; comentários, para isso,
como é sugerido temos que usar o &lt;a href=&quot;http://disqus.com/&quot;&gt;http://disqus.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Primeiro faça seu cadastro em
&lt;a href=&quot;http://disqus.com/admin/register/&quot;&gt;http://disqus.com/admin/register/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O disqus permite importar comentárias das ferramentas mais comuns para
blogs como wordpress e blogger.&lt;/p&gt;

&lt;p&gt;Como eu usava uma app própria não tive outra saída a não ser criar um xml,
porém não tive êxito ao fazê-lo, pesquisando mais um pouco achei um
projeto para usar a API do disqus,
&lt;a href=&quot;https://github.com/norman/disqus&quot;&gt;https://github.com/norman/disqus&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Partindo deste projeto e de exemplos cheguei a seguinte tarefa, você só vai
precisar adaptar aos seus models e obter sua &lt;code&gt;api_key&lt;/code&gt;, neste link
&lt;a href=&quot;http://disqus.com/api/get_my_key/&quot;&gt;http://disqus.com/api/get_my_key/&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace :import do
  desc 'Import comments into disqus'
  task :comments =&amp;gt; :environment do
    Disqus::defaults[:api_key] = '****** MINHA API KEY ******'
    blog_name = 'nome_do_blog_dentro_do_disqus'


    forums = Disqus::Api.get_forum_list
    forum = forums['message'].find do |forum| forum['shortname'] = blog_name end
    forum_key = (Disqus::Api.get_forum_api_key :forum_id =&amp;gt; forum[&quot;id&quot;])['message']
    Page.all.each do |page|
      thread_url = &quot;http://exemplosite.com/#{page.slug}/&quot;
      thread_id = Disqus::Api.thread_by_identifier(:forum_api_key =&amp;gt; forum_key, :title =&amp;gt; page.title, :identifier =&amp;gt; thread_url)['message']['thread']['id']
      page.comments.each do |comment|
        post = Disqus::Api.create_post :forum_api_key =&amp;gt; forum_key,
          :thread_id =&amp;gt; thread_id,
          :message =&amp;gt; comment.content,
          :author_name =&amp;gt; comment.author,
          :author_email =&amp;gt; comment.author_email,
          :parent_post =&amp;gt; nil,
          :created_at =&amp;gt; Time.at(comment.created_at).strftime('%Y-%m-%dT%H:%M'),
          :author_url =&amp;gt; comment.author_url,
          :ip_address =&amp;gt; comment.user_ip

        if post['succeeded']
          puts &quot;added a post successfully: #{post['message']['id']}&quot;
          comment.imported = true
          comment.save
        else
          puts &quot;false: #{post.inspect}&quot;
        end
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Como eu já usava o &lt;a href=&quot;http://akismet.com/&quot;&gt;akismet&lt;/a&gt;, a migração foi muito
fácil e o melhor: até a data que foi feito o comentário foi importado.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Usando Octopress</title>
    <link href="http://blog.dmitrynix.com/usando-octopress/"/>
    <updated>2011-09-08T21:33:00+00:00</updated>
    <id>http://blog.dmitrynix.com/usando-octopress</id>
    <content type="html">&lt;h1&gt;Definição&lt;/h1&gt;

&lt;p&gt;O &lt;a href=&quot;http://octopress.org/&quot;&gt;Octopress&lt;/a&gt;, como o próprio site diz é:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Um framework de blog para hackers&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;É um framework feito usando &lt;a href=&quot;http://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt;, que
por sua vez é um gerador de sites estáticos.&lt;/p&gt;

&lt;p&gt;Como para alguns pode ser muito trabalhoso usar o Jekyll, pois é preciso
escrever seu próprio template html, css, javascripts e toda a configuração.
Mas usando o Octopress bastante disso já é feito, claro que depois que se
aprende a usar você faz suas próprias customizações.&lt;/p&gt;

&lt;h1&gt;Obtendo o Octopress&lt;/h1&gt;

&lt;p&gt;No meu caso não pensei que iria usar o
&lt;a href=&quot;http://octopress.org/&quot;&gt;Octopress&lt;/a&gt; então fiz um clone (e não um fork), mas
caso você já tenha decidido usá-lo faça um fork. De qualquer forma obtenha
o Octopress:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone git://github.com/imathis/octopress.git
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Setup&lt;/h1&gt;

&lt;p&gt;Antes de qualquer ação execute o &lt;code&gt;bundle install&lt;/code&gt; para instalar as
dependências.&lt;/p&gt;

&lt;p&gt;O arquivo de configuração é &lt;code&gt;_config.yml&lt;/code&gt;. Basicamente só é necessário
mudar &lt;em&gt;url&lt;/em&gt;, &lt;em&gt;title&lt;/em&gt;, &lt;em&gt;subtitle&lt;/em&gt; e &lt;em&gt;author&lt;/em&gt; e caso queira as
&lt;em&gt;configurações&lt;/em&gt; do github, twitter,
&lt;a href=&quot;https://www.google.com/analytics/&quot;&gt;Google Analytics&lt;/a&gt; e do
&lt;a href=&quot;http://disqus.com/&quot;&gt;disqus&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;url: http://blog.dmitrynix.com
title: Unix and Me
subtitle: About unix, web programing and me
author: Dmitry Nix
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora o &lt;code&gt;rake install&lt;/code&gt; vai copiar o tema padrão:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;octopress% rake install
## Copying classic theme into ./source and ./sass
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E para levantar um &lt;em&gt;preview&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;octopress% rake preview
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E ficará disponível na porta 4000 da sua máquina:
&lt;a href=&quot;http://localhost:4000&quot;&gt;http://localhost:4000&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;Blogando&lt;/h1&gt;

&lt;p&gt;Os arquivos das postagens devem ser armazenadas seguindo este padrão:
&lt;code&gt;YYYY-MM-DD-post-title.markdown&lt;/code&gt;, dentro de &lt;code&gt;source/_posts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O próprio Octopress já tem uma tarefa rake para executar esta ação:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rake new_post[&quot;Título da Postagem&quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No meu caso ela não está funcionando e eu ainda tenho que fazer isso no
&quot;braço&quot;.&lt;/p&gt;

&lt;p&gt;Abra o seu editor de texto favorito e comece a escrever:&lt;/p&gt;

&lt;p&gt;As primeiras linhas são em yaml, para informar &lt;em&gt;configurações&lt;/em&gt; e
informações da postagem:&lt;/p&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---
layout: post
title: &quot;Titulo da Postagem&quot;
date: 2011-09-08 21:33
comments: true
categories: [categoria1, categoria2]
---

Comece a escrever daqui...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;É importante lembrar que como yaml as categorias precisam ser informadas
seguindo o seu padrão, não apenas separadas por vírgula.&lt;/p&gt;

&lt;p&gt;Leia mais em &lt;a href=&quot;http://octopress.org/docs/blogging/&quot;&gt;Blogging Basics&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;Deploy&lt;/h1&gt;

&lt;p&gt;Caso queira usar o &lt;a href=&quot;http://heroku.com/&quot;&gt;heroku&lt;/a&gt; para hospedagem só é
preciso retirar o diretório &lt;code&gt;public&lt;/code&gt; do &lt;code&gt;.gitignore&lt;/code&gt;. Só alerto que isso
pode acarretar em mais conteúdo para seu commit, exemplo: caso seja
modificado o &lt;em&gt;author&lt;/em&gt; do site, a maioria dos arquivos em &lt;code&gt;public&lt;/code&gt; serão
afetados.&lt;/p&gt;

&lt;p&gt;Já na minha hospedagem &lt;a href=&quot;http://linode.com&quot;&gt;Linode&lt;/a&gt; eu utilizo o capistrano
para atualizar e tive alguns problemas, tudo foi resolvido com o
&lt;code&gt;config/deploy.rb&lt;/code&gt; semelhante a este:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set :keep_releases, 5
set :scm, :git
set :scm_verbose, false
set :repository, 'git@endereco.com:/octopress.git'
set :deploy_via, :remote_cache
set :user, 'dmitry'
set :deploy_to, '/home/dmitry/blog'
set :use_sudo, false
role :app, 'blog.dmitrynix.com', :primary =&amp;gt; true
default_run_options[:pty] = true

namespace :octopress do
  task :generate, :roles =&amp;gt; :app do
    run &quot;cd #{release_path} &amp;amp;&amp;amp; bundle exec jekyll&quot;
  end
end

after 'bundle:install', 'octopress:generate'
after 'deploy:update_code', 'deploy:cleanup'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E com o nginx apontando para o diretório &lt;code&gt;public&lt;/code&gt; dentro do &quot;current&quot; do
capistrano.&lt;/p&gt;

&lt;h1&gt;Atualização&lt;/h1&gt;

&lt;p&gt;Após escrever este artigo uma atualização do Octopress (ou do Jekyll)
passou a não ser mais compatível com ruby18 e como ainda não atualizei o
servidor passei a usar o seguinte script para fazer a autalização:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash

# Não use '/' ao final de endereço de pastas
ssh_user=&quot;dmitry@blog.dmitrynix.com&quot;
remote_tmp_dir=&quot;/tmp/.site_update&quot;
remote_final_dir=&quot;/home/dmitry/blog/current/public&quot;

echo '## Generating Site with Jekyll'
bundle exec rake generate &amp;gt;/dev/null 2&amp;gt;/dev/null
echo '## Sending Site with rsync'
rsync -az --delete public/ ${ssh_user}:${remote_tmp_dir}
ssh ${ssh_user} &quot;rsync -a --delete ${remote_tmp_dir}/ ${remote_final_dir}&quot;
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title>Rails e Jquery-ui Datepicker</title>
    <link href="http://blog.dmitrynix.com/rails-e-jquery-ui-datepicker/"/>
    <updated>2011-09-06T21:20:00+00:00</updated>
    <id>http://blog.dmitrynix.com/rails-e-jquery-ui-datepicker</id>
    <content type="html">&lt;h1&gt;Instalar o jquery e jquery-ui&lt;/h1&gt;

&lt;p&gt;Baixar o jquery e o jquery-ui para o diretório &lt;code&gt;public&lt;/code&gt;, mas se vc quiser
pode usar a gem &lt;em&gt;jquery-rails&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source 'http://rubygems.org'

gem 'rails', '3.0.9'
gem 'jquery-rails'

gem 'sqlite3'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instalar:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E adicionar o jquery:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% rails g jquery:install --ui
  remove  public/javascripts/prototype.js
  remove  public/javascripts/effects.js
  remove  public/javascripts/dragdrop.js
  remove  public/javascripts/controls.js
 copying  jQuery (1.6.1)
  create  public/javascripts/jquery.js
  create  public/javascripts/jquery.min.js
 copying  jQuery UI (1.8.12)
  create  public/javascripts/jquery-ui.js
  create  public/javascripts/jquery-ui.min.js
 copying  jQuery UJS adapter (0e7426)
  remove  public/javascripts/rails.js
  create  public/javascripts/jquery_ujs.js
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;O model&lt;/h1&gt;

&lt;pre&gt;&lt;code&gt;rails g scaffold Aniversario nome:string dia:date
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nosso projeto já recebe datas, pelo método &lt;code&gt;date_select&lt;/code&gt;, mas nos queremos que ou o usuário digite a data (separada por &lt;code&gt;/&lt;/code&gt;) ou selecione no datapicker do jquery-ui uma.&lt;/p&gt;

&lt;p&gt;Um fato interessante desta forma de inserir datas é que permite deixar a
data vazia, algo que no &lt;em&gt;padrão rails&lt;/em&gt; não consegui encontrar.&lt;/p&gt;

&lt;h1&gt;Primeiro: Receber a data como string&lt;/h1&gt;

&lt;p&gt;Vamos primeiro preparar o model e o formulário para inserir a data
manualmente usando o &lt;code&gt;text_field&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O primeiro passo é mudar a formulário de &lt;code&gt;data_select&lt;/code&gt; para &lt;code&gt;text_field&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Se você for criar algum registro desta forma a data será reconhecida de
forma errada.&lt;/p&gt;

&lt;p&gt;Então vamos preparar o model para receber a data em formato usado no
Brasil.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Aniversario &amp;lt; ActiveRecord::Base
  def dia_br
    &quot;#{dia.to_s[8..9]}/#{dia.to_s[5..6]}/#{dia.to_s[0..3]}&quot;
  end

  def dia_br=(dia_en)
    self.dia = &quot;#{dia_en[6..9]}-#{dia_en[3..4]}-#{dia_en[0..1]}&quot;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Como pode-se notar nos não mudamos a &lt;em&gt;forma padrão&lt;/em&gt;, nos apenas criamos um
método auxiliar.&lt;/p&gt;

&lt;p&gt;Continuando no form use, ao invés de &lt;code&gt;dia&lt;/code&gt;, &lt;code&gt;dia_br&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;field&quot;&amp;gt;
  &amp;lt;%= f.label :dia %&amp;gt;&amp;lt;br /&amp;gt;
  &amp;lt;%= f.text_field :dia_br %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Implementando o datapicker&lt;/h1&gt;

&lt;p&gt;Antes de colocar o datapicker vamos primeiro adicionar o &lt;em&gt;locale&lt;/em&gt; dele,
para isso basta baixar o arquivo
&lt;a href=&quot;http://jqueryui.com/ui/i18n/jquery.ui.datepicker-pt-BR.js&quot;&gt;jquery.ui.datepicker-pt-BR.js&lt;/a&gt;, colocar em &lt;code&gt;public&lt;/code&gt; e adicionar usando
&lt;code&gt;javascript_include_tag&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= javascript_include_tag :defaults, 'jquery.ui.datepicker-pt-BR' %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora só falta usar o jquery-ui datapicker como manda a sua documentação:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;% javascript_tag do %&amp;gt;
  $(document).ready(function() {
    $('#aniversario_dia_br').datepicker();
  });
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E para ficar mais bonito adicionar um &lt;a href=&quot;http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css&quot;&gt;tema&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Como de costume o projeto está no github: &lt;a href=&quot;https://github.com/dmitrynix/rails-datepicker&quot;&gt;dmitrynix/rails-datepicker&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Hello Sinatra ;)</title>
    <link href="http://blog.dmitrynix.com/hello-sinatra/"/>
    <updated>2011-08-09T08:59:00+00:00</updated>
    <id>http://blog.dmitrynix.com/hello-sinatra</id>
    <content type="html">&lt;p&gt;Depois de recomendações do &lt;a href=&quot;http://twitter.com/hakagura&quot;&gt;@hakagura&lt;/a&gt;
sobre o framework sinatra (o mesmo que me recomendou o Rails ;) resolvi
voltar a testá-lo. Neste post vou mostrar como criar uma aplicação
usando sinatra e rspec.&lt;/p&gt;

&lt;h1&gt;Preparando ambiente com Bundler&lt;/h1&gt;

&lt;p&gt;Crie um arquivo de &lt;code&gt;Gemfile&lt;/code&gt; seguindo este exemplo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source 'http://rubygems.org'

gem 'sinatra'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora um &lt;code&gt;bundle install&lt;/code&gt; para instalar as dependêcias e criar o
&lt;code&gt;Gemfile.lock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora vamos criar o &lt;code&gt;config.ru&lt;/code&gt; e o &lt;code&gt;demo_app.rb&lt;/code&gt; para carregar as
dependências usando o Bundler:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;config.ru&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'bundler'

Bundler.require :default

require File.dirname(__FILE__)+'/demo_app'

run DemoApp::Application
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;demo_app.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module DemoApp
  class Application &amp;lt; Sinatra::Base
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nossa aplicação já está pronta e ela é considerada do &quot;tipo modular&quot;
quando se usa sinatra.&lt;/p&gt;

&lt;h1&gt;Iniciando o ambiente de testes com RSpec&lt;/h1&gt;

&lt;p&gt;Primeiro adicionar o rspec e o rack-test para o Gemfile:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;group :development, :test do
  gem 'rspec'
  gem 'rack-test', :require =&amp;gt; 'rack/test'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora vamos criar um arquivo &lt;code&gt;spec_helper.rb&lt;/code&gt; dentro do diretório &lt;code&gt;spec&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'bundler'

Bundler.require :default, :test

ENV['RACK_ENV'] = 'test'

require File.dirname(__FILE__)+'/../demo_app'

RSpec.configure do |config|
  include Rack::Test::Methods

  def app
    DemoApp::Application
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nosso ambiente de teste também já está pronto.&lt;/p&gt;

&lt;h1&gt;Primeira spec&lt;/h1&gt;

&lt;p&gt;Ainda dentro do diretório &lt;code&gt;spec&lt;/code&gt; vamos criar o arquivo &lt;code&gt;demo_app_spec.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'spec_helper'

describe DemoApp::Application do
  context 'Get /' do
    it 'should be ok' do
      get '/'
      last_response.status.should be(200)
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nosso primeiro spec irá, obviamente, falhar:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sinatra-demo-app % rspec spec/demo_app_spec.rb
F

Failures:

  1) DemoApp::Application Get / should be ok
     Failure/Error: last_response.status.should be(200)

       expected #&amp;lt;Fixnum:401&amp;gt; =&amp;gt; 200
            got #&amp;lt;Fixnum:809&amp;gt; =&amp;gt; 404

       Compared using equal?, which compares object identity,
       but expected and actual are not the same object. Use
       'actual.should == expected' if you don't care about
       object identity in this example.
     # ./spec/demo_app_spec.rb:7:in `block (3 levels) in &amp;lt;top (required)&amp;gt;'

Finished in 0.02014 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/demo_app_spec.rb:5 # DemoApp::Application Get / should be ok
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Se você tentar inicializar o servidor para testar no navegador também
verá uma mensagem de erro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sinatra-demo-app % rackup config.ru -p 4000
[2011-08-09 08:43:37] INFO  WEBrick 1.3.1
[2011-08-09 08:43:37] INFO  ruby 1.9.3 (2011-07-31) [x86_64-darwin11.0.0]
[2011-08-09 08:43:37] INFO  WEBrick::HTTPServer#start: pid=61772 port=4000
127.0.0.1 - - [09/Aug/2011 08:43:40] &quot;GET / HTTP/1.1&quot; 404 429 0.0085
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Escrevendo nosso código:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module DemoApp
  class Application &amp;lt; Sinatra::Base
    get '/' do
      &quot;&quot;
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Executando o rspec novamente:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sinatra-demo-app % rspec spec/demo_app_spec.rb
.

Finished in 0.02425 seconds
1 example, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Mais um exemplo de spec&lt;/h1&gt;

&lt;p&gt;Agora vamos testar o texto que retorna da requisição:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'spec_helper'

describe DemoApp::Application do
  context 'Get /' do
    it 'should be ok' do
      get '/'
      last_response.status.should be(200)
    end

    it 'should have the correct text' do
      get '/'
      last_response.body.should == 'DemoApp::Application request'
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Quando executado este teste irá obviamente falhar, mas ao escrever
corretamente a aplicação:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module DemoApp
  class Application &amp;lt; Sinatra::Base
    get '/' do
      &quot;DemoApp::Application request&quot;
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ele irá passar.&lt;/p&gt;

&lt;h1&gt;Links recomendados&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Este projeto no github:
&lt;a href=&quot;https://github.com/dmitrynix/sinatra-demo-app-post&quot;&gt;https://github.com/dmitrynix/sinatra-demo-app-post&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sinatrarb.com&quot;&gt;http://sinatrarb.com&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sinatra-book-contrib.com/&quot;&gt;http://sinatra-book-contrib.com/&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  
  <entry>
    <title>Migração</title>
    <link href="http://blog.dmitrynix.com/migracao/"/>
    <updated>2011-07-19T11:20:00+00:00</updated>
    <id>http://blog.dmitrynix.com/migracao</id>
    <content type="html">&lt;p&gt;Atualmente estou num projeto de migração de dados, ao invés de fazer dump de banco nos resolvemos &quot;esqueçer&quot; o banco e iniciar um novo projeto.&lt;/p&gt;

&lt;p&gt;Após a conclusão deste projeto nos vamos &quot;importar&quot; o banco… Não mudaremos uma coluna ou tabela no banco de dados &quot;antigo&quot;.&lt;/p&gt;

&lt;h1&gt;Criando o Projeto para Migrar&lt;/h1&gt;

&lt;p&gt;Vamos começar pelo Gemfile:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source &quot;http://rubygems.org&quot;

gem 'rake'
gem 'activerecord', '3.0.0', :require =&amp;gt; 'active_record'
gem 'mysql', '2.8.1'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nos vamos usar o Rake para migrar a base de dados, o activerecord será usado juntamente com o mysql (ou sqlite, caso vc queira somente testar) para pegar os dados e passar para o outro banco.&lt;/p&gt;

&lt;p&gt;Apenas para migração de dados é somente isso (por enquanto) que precisamos.&lt;/p&gt;

&lt;h1&gt;Inicializando o DB e os &quot;Models&quot;&lt;/h1&gt;

&lt;p&gt;No meu caso eu criei o arquivo &lt;code&gt;db.rb&lt;/code&gt; na raiz do projeto para inicializar o banco de dados e carregar os models:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'active_record'

class MigrateDb &amp;lt; ActiveRecord::Base
end

MigrateDb.establish_connection :adapter =&amp;gt; 'mysql',
  :database =&amp;gt; 'portal',
  :username =&amp;gt; 'root',
  :password =&amp;gt; '',
  :timeout =&amp;gt; 5000

Dir['./models/*.rb'].each { |f| require f }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Veja a criação da classe &lt;code&gt;MigrateDb&lt;/code&gt;, ela será usada somente neste projeto, para não dar conflito de conexão com o ActiveRecord do projeto novo, caso a migração ocorra para outro tipo de banco como o mongodb ou couchdb, não seria necessario isto.&lt;/p&gt;

&lt;p&gt;Ao invés de criar este arquivo vc poderia me questionar de o pq não adicionei logo ao &lt;code&gt;Rakefile&lt;/code&gt;, já que usarei tarefa rake para migrar. São duas as necessidade de não adicionar direto no &lt;code&gt;Rakefile&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pode-se adicionar a linha de require dentro do &lt;code&gt;Rakefile&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Para abrir um &quot;rails console&quot; você usa: &lt;code&gt;bundle exec -r ./db.rb&lt;/code&gt; e pronto o irb já vai carregar com o &quot;banco&quot;;&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;Rakefile&lt;/h1&gt;

&lt;pre&gt;&lt;code&gt;require 'bundler/setup'
require 'rake'
require File.dirname(__FILE__)+'/db'
Dir[ [File.dirname(__FILE__), 'lib', 'tasks'].join('/') + '**/*'].each { |task| load task }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O &lt;code&gt;Rakefile&lt;/code&gt; vai fazer um require no arquivo de inicialização do banco de dados (&lt;code&gt;db.rb&lt;/code&gt;) e nas tarefas em &lt;code&gt;lib/tasks/&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;Construindo os models&lt;/h1&gt;

&lt;p&gt;Ao invés de descender do &lt;code&gt;ActiveRecord::Base&lt;/code&gt;, nossos models desenderá do &lt;code&gt;MigrateDb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Secao &amp;lt; MigrateDb
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O ActiveRecord funciona com menos esforço quando você segue o padrão dele, mas caso vc tenha uma tabela com outro nome use o &lt;code&gt;set_table_name&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Secao &amp;lt; MigrateDb
  set_table_name 'portal_secao'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Uma outra dica rápida seria criar comandos ao invés de decorrar a base de dados:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Postagem &amp;lt; MigrateDb
  set_table_name 'portal_postagens'

  def cidade
    Cidade.find(cidade_id)
  end

  def cidade_id
    self.cod_cidade
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Se você está acostumado com o &quot;padrão ActiveRecord&quot; seria melhor vc criar estes dois métodos, uma vez que nossa base de dados deve se conservar o mais somente leitura quanto possível, não seria necessário métodos como &lt;code&gt;cidade=(cidade)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Por fim eu recomendo que seja criado um método &lt;code&gt;migrate_attrs&lt;/code&gt; (ou qualquer outro nome) que retorna um hash somente com os dados necessários para a nova base de dados:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Usuario &amp;lt; MigrateDb
  set_table_name 'portal_usuario'

  def migrate_attrs
  # Dados como :endereco, :cep, não será necessário
    {
      :email =&amp;gt; email,
      :name =&amp;gt; nome,
      :created_at =&amp;gt; data_cadastro,
      :cell_phone =&amp;gt; celular,
      :login =&amp;gt; codinome,
      :phone =&amp;gt; telefone
    }
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;E o &quot;Banco Novo&quot;?&lt;/h1&gt;

&lt;p&gt;Bom… eu faço um require do projeto novo &quot;inteiro&quot; para poder usar o banco, esta é a melhor forma para não ter que ficar duplicando os projetos (ou somente os models).&lt;/p&gt;

&lt;p&gt;Há um problema no require: o Gemfile do projeto novo, vc ainda vai precisar copiar e colar ele para dentro do Gemfile do projeto de migração:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source &quot;http://rubygems.org&quot;

gem 'rake'
gem 'activerecord', '3.0.0', :require =&amp;gt; 'active_record'
gem 'mysql', '2.8.1'

# Gemfile do novo projeto
gem 'rails', '3.0.0'
gem 'devise', :git =&amp;gt; 'git://github.com/plataformatec/devise.git'
gem 'sqlite3' # Ainda estou somente testando a migração dos dados
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Para fazer este require eu adiciono no arquivo rake (por exemplo: &lt;code&gt;lib/tasks/db_import.rake&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require File.expand_path(&quot;../../../../novo_projeto_rails/config/environment&quot;, __FILE__)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Logo abaixo desta linha eu coloco a conexão do banco de dados do projeto novo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ActiveRecord::Base.establish_connection :adapter =&amp;gt; 'sqlite3',
  :database =&amp;gt; 'db/development.sqlite3',
  :pool =&amp;gt; 5,
  :timeout =&amp;gt; 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Tarefa rake&lt;/h1&gt;

&lt;p&gt;agora basta completar a(s) tarefa(s) rake:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# encoding utf-8
require File.expand_path(&quot;../../../../novo_projeto_rails/config/environment&quot;, __FILE__)

require File.dirname(__FILE__)+'/../../db.rb'

ActiveRecord::Base.establish_connection :database =&amp;gt; 'portal', :username =&amp;gt; 'root', :password =&amp;gt; '', :adapter =&amp;gt; 'mysql'

namespace :db do
  task :import do
    Usuario.all.each do |usuario|
      User.create usuario.migrate_attrs
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Rodando a Importação&lt;/h1&gt;

&lt;p&gt;Vá no projeto novo e execute a migração da base de dados.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle exec rake db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;E no projeto de migração execute:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle exec rake db:import
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title>Git Básico</title>
    <link href="http://blog.dmitrynix.com/git-basico/"/>
    <updated>2011-06-01T17:14:00+00:00</updated>
    <id>http://blog.dmitrynix.com/git-basico</id>
    <content type="html">&lt;h1&gt;Iniciando um Projeto&lt;/h1&gt;

&lt;p&gt;Dentro da pasta que você quer começar a usar git execute o &lt;code&gt;git init&lt;/code&gt;,
pode já ter conteúdo ou não:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;teste % git init
Initialized empty Git repository in /Users/dmitry/teste/.git/
teste %
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Se você tem um projeto no github (fork ou algo semelhante)&lt;/p&gt;

&lt;p&gt;Basta executar um &lt;code&gt;git clone&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dmitry % git clone git@github.com:dmitrynix/teste.git
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;O que eu mudei?&lt;/h1&gt;

&lt;p&gt;Se você já fez as mudanças dentro do seu projeto veja os arquivos que foram modificados com o comando &lt;code&gt;git status&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;teste % git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use &quot;git add &amp;lt;file&amp;gt;...&quot; to include in what will be committed)
#
#   novo_arquivo
nothing added to commit but untracked files present (use &quot;git add&quot; to track)
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;Adicionando arquivos&lt;/h1&gt;

&lt;p&gt;Se um arquivo nunca existiu no git o &lt;code&gt;git add&lt;/code&gt; vai adicionar um novo
arquivo, mas caso o arquivo já exista no git o &lt;code&gt;git add&lt;/code&gt; só vai adicionar
as mudanças feitas.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; teste % git add novo_arquivo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Após adicionar com o &lt;code&gt;git add&lt;/code&gt; tudo que você pretende por no git, use o
comando &lt;code&gt;git commit&lt;/code&gt; para escrever uma mensagem das mudação.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; teste % git commit -m 'Iniciando monitoramento ou adicionando modificacoes'
 [master (root-commit) 46b0893] Iniciando monitoramento ou adicionando modificacoes
  0 files changed, 0 insertions(+), 0 deletions(-)
  create mode 100644 novo_arquivo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pronto seus arquivos já estão no git.&lt;/p&gt;

&lt;h1&gt;Enviando e Recebendo Arquivos do Servidor&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Crie uma conta no &lt;a href=&quot;http://github.com&quot;&gt;github.com&lt;/a&gt; e experimente os
comandos abaixo&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Antes de enviar os arquivos você precisa configurar qual é o endereço do
servidor, no meu caso vou usar: &lt;em&gt;git@github.com:dmitrynix/teste.git&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Enviando arquivos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;teste % git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 244 bytes, done.
Total 2 (delta 0), reused 0 (delta 0)
To git@github.com:dmitrynix/teste.git
   46b0893..266ad1b  master -&amp;gt; master
teste %
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pegando arquivos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;teste % git pull
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From github.com:dmitrynix/teste
   266ad1b..7e0527e  master     -&amp;gt; origin/master
Updating 266ad1b..7e0527e
Fast-forward
 novo_arquivo |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
teste %
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.slideshare.net/slide_user/magia-git&quot;&gt;http://www.slideshare.net/slide_user/magia-git&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git-scm.com/&quot;&gt;http://git-scm.com/&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  
  <entry>
    <title>Não publique conteúdo digital</title>
    <link href="http://blog.dmitrynix.com/nao-publique-conteudo-digital/"/>
    <updated>2011-04-28T13:57:00+00:00</updated>
    <id>http://blog.dmitrynix.com/nao-publique-conteudo-digital</id>
    <content type="html">&lt;p&gt;NÃO GERE CONTEÚDO DIGITAL!!!&lt;/p&gt;

&lt;p&gt;Recentemente cogitei publicamente (leia: twitter) em obter um e-book pago de forma gratuita, o educado que pensava eu ser mais um amigo de twitter logo anunciou o meu pedido e de mais alguém para o dono do e-book.&lt;/p&gt;

&lt;p&gt;Isso não tem desculpa, sei disso, e é por isso que venho aqui pedir desculpas pelo incidente, não citarei nomes nem linkarei nada, apenas &lt;em&gt;desculpa&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Bom, você que aceitou meu pedido de desculpas pode parar de ler, mas continue caso queira saber minha atual situação.&lt;/p&gt;

&lt;p&gt;É cediço que estou tentando &quot;abrir&quot; (não diria abrir realmente) uma empresa com mais 2 amigos, a grana está extremamente curta, para ter uma ideia eu estou a cerca de 4 meses pagando entre o mínimo e abaixo do mínimo no cartão (2 cartões) enquanto a grana não entra…&lt;/p&gt;

&lt;p&gt;Além disse eu também costumo a almoçar no mercado-velho no qual a comida é pela metade do preço, me orgulho disso, sério, a comida é boa, e quando não dá para ir eu vou comprar pelo preço normal (apenas um) para dividir entre mim e meu atual companheiro de trabalho.&lt;/p&gt;

&lt;p&gt;Conteúdo digital eu já &quot;crackeei&quot;, foi através disso que eu, por exemplo, conheci a pragprog, após, conhecer e passar do período de &quot;vacas magras&quot; eu comprei e em outra ocasião vou comprar mais, só para citar estes são os livros que eu comprei:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;agile-web-development-with-rails_b11_0;&lt;/li&gt;
&lt;li&gt;the-rspec-book_p1_0 (pdf e papper book, o livro impresso me ajudou na semana passada com uma dúvida);&lt;/li&gt;
&lt;li&gt;using-memcached_p1_0 (ruim);&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Já crackeei muito, programas, peguei conteúdo pago: ebook, livro scaneado, músicas…;&lt;/p&gt;

&lt;p&gt;Da mesma forma já comprei muito conteúdo digital: pragprog, insistimento, diversos programas para mac (e para linux também), doações para entidades carentes…&lt;/p&gt;

&lt;p&gt;Depois do pedido de desculpas vem o aviso: &quot;NÃO PUBLIQUE CONTEÚDO DIGITAL&quot;, sim isso mesmo, se vc não quer que pelo menos &quot;um cara passe para o seu amigo, que por exemplo, tem mais de 5 anos de amizade (que já pagou muitos lanches)&quot;, não publique.&lt;/p&gt;

&lt;p&gt;Por questões financeiras ou mesmo pq é mais fácil pedir um ebook do que procurar aquele seu cartão de crédito para comprar (não sou obrigado a ter conta em TODOS os gateways de pagamento).&lt;/p&gt;

&lt;p&gt;O aviso não é para imprimir e vender, ou qualquer outro: se vc tiver um programa, e-book, música, qualquer coisa, e quiser cobrar por ele simplesmente não faça, fique com ele para si mofando!&lt;/p&gt;

&lt;p&gt;Só para constar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sim, estou revoltado.&lt;/li&gt;
&lt;li&gt;Não, não estou estressado: conteúdo digital sempre terá a possibilidade de ser &quot;crackeado&quot;.&lt;/li&gt;
&lt;li&gt;Sim, pode comentar/criticar/dizer TUDO que pensa nos comentários (vou tentar não censurar ;)&lt;/li&gt;
&lt;li&gt;e por fim:&lt;/li&gt;
&lt;/ul&gt;


&lt;blockquote&gt;&lt;p&gt;Se você usa windows e não quer pegar vírus, não ligue nunca seu computador.&lt;/p&gt;&lt;/blockquote&gt;
</content>
  </entry>
  
  <entry>
    <title>Moedas, Vale-transporte e Agradecimento</title>
    <link href="http://blog.dmitrynix.com/moedas-vale-transporte-e-agradecimento/"/>
    <updated>2011-03-25T08:10:00+00:00</updated>
    <id>http://blog.dmitrynix.com/moedas-vale-transporte-e-agradecimento</id>
    <content type="html">&lt;p&gt;Hoje (quinta, 24 de março de 2011), quando estavamos saindo Sandro, Álvaro e eu da loja, uma pessoa &quot;chegou junto&quot; e, mostrando um papel, pediu uma ajuda, nessas horas eu sempre lembro: &quot;devo ajudar, pois um dia eu posso ficar nesta situação&quot;.&lt;/p&gt;

&lt;p&gt;Logo depois de ser deixado na Frei Serafim, ao por a mão no bolso senti falta do meu cartão do ônibus.&lt;/p&gt;

&lt;p&gt;O desespero não bateu, pois como se diz de teresina: &quot;cidadezinha pequena que praticamente todo mundo se conhece&quot;. Fiquei próximo da avenida, o local de maior movimento, esperei alguém passar...&lt;/p&gt;

&lt;p&gt;... e passou, primeiro foi Francisco Smile, um amigo de escolha (ensino médio que fiz no CEFET-PI), falei minha situação para ele, expliquei pq não poderia voltar para a loja (longe), deu-me 1.65 em &lt;strong&gt;moedas&lt;/strong&gt;, adradeci muito, muito mesmo.&lt;/p&gt;

&lt;p&gt;Logo passou a Cristiane Menezes, amiga da época que eu trabalhava somente com manutenção de computadores, ela não tinha os 0.2 centavos para completar a passagem, mas com seu sorriso no rosto deu-me um &lt;strong&gt;vale-transporte&lt;/strong&gt;, disse que dava os 1.65 para ela, mas ela praticamente me bateu por falar isso :-D&lt;/p&gt;

&lt;p&gt;O fato é que: eu me sinto eternamente &lt;strong&gt;grato&lt;/strong&gt; a todos os meus amigos, pelo simples fato de que eu os tenho como amigos.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Apaixone-se</title>
    <link href="http://blog.dmitrynix.com/apaixone-se/"/>
    <updated>2011-02-16T17:22:00+00:00</updated>
    <id>http://blog.dmitrynix.com/apaixone-se</id>
    <content type="html">&lt;p&gt;Já tenho a experiencia 4 empresas (2 com carteira assinada e empreendimento da família), em todas eu entrei com o mesmo sentimento: &quot;Apaixonado, vou dar meu sangue pela empresa, afinal sou parte dela agora.&quot;*&lt;/p&gt;

&lt;p&gt;* Quem sabe onde eu trabalhei vai entender essa piada pronta.&lt;/p&gt;

&lt;p&gt;Mas em contrapartida há um sério problema: paixão é algo que, como todos dizem, passa rápido.&lt;/p&gt;

&lt;p&gt;Para solucionar este problema eu crei a seguinte lista:&lt;/p&gt;

&lt;h1&gt;EVITE: Hierarquia, quem manda sou eu e pronto&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Não deixe ter uma hierarquia FORTE&lt;/em&gt;, no empreendimento da família quem manda é minha mãe e acabou, ninguém tem opnião em NADA mais.&lt;/p&gt;

&lt;p&gt;Isso me deixa furioso, pq se ela um dia passar isso para mim eu já vou começar mal, e já está tão mal que se ela me desse tudo agora eu recusaria veementemente. Ora: a empresa sempre foi dela e não vai ser agora que vai deixar de ser.&lt;/p&gt;

&lt;h1&gt;EVITE: Deixar as dívidas afundar a empresa&lt;/h1&gt;

&lt;p&gt;Em casa o empreendimento da família tem suas contas misturadas com as contas minha, da minha irmã, ou seja, &lt;em&gt;as contas da empresa com as contas de casa&lt;/em&gt;. Em todos os cursos e materiais relacionado ao assunto dizem claramente para não misturar.&lt;/p&gt;

&lt;p&gt;No meu primeiro emprego, o problema das contas era o não pagamento, como a empresa pegava em quantidades grandes de dinheiro, eu suponho, a DONA fariava com a grana e depois para pagar as dívidas? Não tinha mais dinheiro para nada, e eu ficava de saco cheio pq a todo instante tinha cobrador e eu tinha que ficar dizendo: &quot;ela não está aqui e sim eu já avisei que você veio&quot;.&lt;/p&gt;

&lt;h1&gt;EVITE: Ser A empresa&lt;/h1&gt;

&lt;p&gt;Sabe quando alguém diz: &quot;vou para a empresa da Dona Maria&quot; e não &quot;vou para a empresa Costura...&quot;, veja no exemplo o uso do DONO e não da instituição. Isso é um erro, quando se tem isso em mente, só existe duas coisas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ou a empresa tem a mesma hierarquia acima e/ou;&lt;/li&gt;
&lt;li&gt;ela só tem um funcionário e ninguém mais para me ajudar.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Neste último caso se o &quot;único funcionário que eu penso que existe&quot; ficar doente quem vai me ajudar?&lt;/p&gt;

&lt;p&gt;Do mesmo jeito que apesar de ter 10 funcionários na empresa, na maioria das vezes somente 1 pode lhe ajudar, pq ele é o &lt;em&gt;chefe&lt;/em&gt; ou pq só &lt;em&gt;ele sabe como fazer&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;EVITE: Rotina, rotina, rotina, rotina, rotina&lt;/h1&gt;

&lt;p&gt;Não caia no &lt;em&gt;fardo de todo dia&lt;/em&gt;, um erro das empresas que trabalhei era o fardo de todo dia, ou seja, eu vou para o mesmo lugar fazer o mesmo para ganhar o mesmo salário. Ninguém quer fazer o mesmo por 1 ano, imagine se alguém ficaria assim por 5 anos! As pessoas (eu principalmente) gostam de mudar E ajudar a mudar.&lt;/p&gt;

&lt;p&gt;Veja o meu exemplo: sou programador, durante o primeiro ano eu fiz o MESMO PROGRAMA, no segundo ano, tudo mudou (para a pior) pq surgiu mais um programa para fazer, mas a pessoa responsável fez tudo praticamente sozinha (analise, um monte de scaffold, designer, ...) e eu!? Não sirvo para NADA? Tudo bem, vc pode dizer que eu poderia opinar depois ou pq assim seria mais rápido entender o funcionamento, mas quer saber f*d@-se com esse pensamento e pegue o meu: EU QUERO FAZER PARTE.&lt;/p&gt;

&lt;h1&gt;EVITE: Deixar o ambiente ficar irrespirável&lt;/h1&gt;

&lt;p&gt;Em todos os aspectos a comunicação é algo fundamental para a empresa, não deixe de conversar com e nem tenha medo de ninguém, seja na empresa, na hora de pegar o cafezinho, quando for beber água, quando for ao banheiro ou chamando alguém para sair.&lt;/p&gt;

&lt;p&gt;Em todos estes casos acima a pessoa está fazendo algo que &quot;o natural&quot; dela exige, ou seja, está descontraída e em 75% das vezes nem querem sequer lembra que trabalham em algum lugar.&lt;/p&gt;

&lt;p&gt;E quando chamar alguém para sair lembre-se: nem todo mundo é alcolatra ou viciado em pizza como vc, pergunte para onde ele quer ir.&lt;/p&gt;

&lt;p&gt;Toda vez que você chama um amigo (ou subordinado) para sair ele recusa pq vc gosta de ir para um bar, mas ele não. Eu, por exemplo, não vejo vantagem em ficar num porcaria de mesa de bar vendo uma porra de futebol, que a propósito eu odeio. Pense bem antes de chamar alguém para &quot;relaxar&quot;. Vá para um lugar comum: veja se o lugar que você quer ir ele iria e veja se o lugar que ele quer ir você iria.&lt;/p&gt;

&lt;p&gt;Não esqueça que na empresa &lt;em&gt;não existe só você&lt;/em&gt; e que você não é o &lt;em&gt;chefe que manda e desmanda&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;SEJA: Parte da empresa&lt;/h1&gt;

&lt;p&gt;Precisa ficar um final de semana inteiro programando ou precisa ir no final de semana para &quot;limpar&quot; a empresa? Sem problema eu vou sim! Sou parte da empresa (não confunda como &lt;em&gt;sou A empresa&lt;/em&gt;), se a empresa vai mal eu também ficarei mal, do mesmo jeito que se ele ficar rica eu fico rico ;)&lt;/p&gt;

&lt;p&gt;Tenha isso em mente.&lt;/p&gt;

&lt;h1&gt;Finalizando&lt;/h1&gt;

&lt;p&gt;Isto é o que eu poderia dizer que aprendi na marra, mas não esqueça que você as vezes tem que cometer os mesmos erros. Não leve nada disso ao pé da letra, depende muito da pessoa que está na sua frente.&lt;/p&gt;
</content>
  </entry>
  
</feed>

