A extinção do programador sênior

Posted by Humberto on julho 29, 2010

Quando foi a última vez em que você viu um programador sênior? Eu tenho tido sérias dificuldades para encontrar algum. Acho que se estivesse procurando ararinhas azuis teria tido mais sucesso — será que alguma toparia programar? Desconfio que não. Consciente da causa ecológica, ela me diria: cada ararinha programando toma o lugar de um programador sênior, que é de uma espécie muito mais em risco do que eu. E bateria as asas em retirada.

É claro que, ao contrário da pobre arara, o programador sênior ainda existe, e em grandes quantidades. Mas algo deu errado na evolução da sua espécie que, ao invés de melhorar, foi substituída por uma variedade mais fácil de reproduzir, bem adaptada ao cativeiro, de comportamento dócil, capaz de passar anos fazendo a mesma coisa e com duas opções de cor: terno preto ou azul. E que, curiosamente, não consegue programar. Eu já vou batizando essa variedade de programador senhor.

Estou falando por experiência própria. A empresa em que eu trabalho está recrutando um “programador sênior” há alguns meses. Dada a indisponibilidade dos colegas no nosso networking (o que nos pouparia um grande tempo), resolvemos apelar e buscar no mercadão de trabalho (vulgo apinfo, catho, essas coisas). Nós filtramos dezenas de currículos, conduzimos entrevistas, aplicamos testes. Com isso, conseguimos achar diversos programadores senhores mas nenhum propriamente sênior. A maioria tinha 10+ anos de carreira, 30+ anos de idade e -1 noção para bolar respostas satisfatórias para questões como:

  1. Como dois programas podem se comunicar?
  2. O que são threads?
  3. Implemente o fizz buzz na linguagem que preferir.

E assim por diante. Nada muito específico: preferimos encontrar gente que tivesse convivido com certos problemas, independente da tecnologia adotada. Gente demonstrasse senioridade propriamente dita: maturidade, bom senso, raciocínio, segurança. E conhecimento suficiente para não achar que a chave de todos os problemas é uma consulta ao Google (houve quem confessasse isso). Não encontramos essa gente ainda, mas em compensação vimos muitas pessoas bem intencionadas, certamente esforçadas, mas com imensas dificuldades para concatenar opiniões a respeito de conceitos que julgamos básicos e, no nosso negócio, fundamentais.

Sequer exigimos que o candidato conheça tópicos como controle de versão, orientação a objetos, design patterns, agilidade e etcetera, que são sinais mais do que evidentes de maturidade. Já entendemos que tudo isso está além dos limites do habitat do programador senhor. São coisas tão exóticas quanto um programador sênior genuíno, que só deve existir em áreas de proteção ambiental, como este blog.

(Às araras azuis que estiverem interessadas no recrutamento: por ora concluímos o processo, mas não deixem de entrar em contato.)

Gerando rotas com parâmetros dinâmicos no Rails de modo fácil

Posted by Rodrigo Panachi on julho 02, 2010

A API de rotas do Rails simplifica consideravelmente o desenvolvimento fornecendo um padrão de geração e utilização de URLs para toda aplicação. Porém algumas necessidades especificas e relativamente simples podem gerar dores de cabeça se forem implementadas incorretamente.

Um caso bastante comum são URLs compostas que sempre apontam para um mesmo recurso. Por exemplo, um blog que possua rotas para seus posts no formato /posts/autor/categoria/permalink provavelmente terá uma rota mapeada como map.post "posts/:author/:category/:permalink" gerando automaticamente os helpers post_path e post_url.

Muito bom, porém para usufruirmos desta facilidade precisamos fornecer os valores dos parâmetros dinâmicos nos controllers e views:

post_path(:author => @post.author, :category => @post.category, :permalink => @post.permalink)

E mesmo que você forneça os parâmetros em um array, vai dar muito trabalho além de deixar muito código repetido pela aplicação.

Entendi! Mas como resolvo este problema?

Para este caso, apenas implementar o método to_param do model não vai servir. Uma solução seria reescrever o método post_path (que é gerado automaticamente) no respectivo helper (posts_helper.rb):

def post_path(post, options = {})
  super(post, :author => post.author, :category => post.category, :permalink => post.permalink)
end

Outra solução seria sobrescrever o método default_url_options no controller para retorna os parâmetros padrões da rota:

def default_url_options(options = {})
  options.merge!(:author => @post.author, :category => @post.category, :permalink => @post.permalink) if options[:action] == "show"
end

A má notícia é que você terá que fazer isto para todos seus controllers e respectivos models.

A terceira solução (e mais elegante) é padronizar a maneira com que os parâmetros opcionais da rota são obtidos a partir do controller e seu respectivo model. Basta adicionar os seguintes métodos no seu ApplicationController:

def default_url_options(options = {})
  if (model = controller_model(options))
    dynamic_route_params(options).each do |param|
      options[param] = model.send(param) if model.respond_to?(param)
    end
  end
  options
end
 
def controller_model(options = {})
  clazz = (options[:controller].singularize.camelize.constantize rescue ActiveRecord)
  options.select { |key, value| value.is_a?(clazz) }.first.second
rescue
  nil
end 
 
def dynamic_route_params(options = {})
  returning [] do |dynamic_params|
    matched_routes = ActionController::Routing::Routes.routes.select do |route|
      route.matches_controller_and_action?(options[:controller], options[:action])
    end
    dynamic_segments = matched_routes.map(&:segments).flatten.each do |segment|
      dynamic_params << segment.key if segment.is_a?(ActionController::Routing::DynamicSegment)
    end
  end
end

Assim, os valores defaults dos parâmetros da rota serão obtidos diretamente do model. Caso queiram contribuir, este código está disponível no github.

Referências
Rails Routing from the Inside Out
Rails Guides: Routing

Active Record em: Como adicionar comportamento as suas associações

Posted by Roger Leite on maio 19, 2010

Qualquer um que comece a desenvolver com Active Record (AR), minha primeira recomendação é, para tudo e leia:  A Guide to Active Record Associations ou O Guia de Associações do Active Record. O guia é bem completo, e descreve muito bem os tipos de associações que estão disponíveis no AR.

Association Proxy, #wtf !

As associações:

  • belongs_to
  • has_one
  • has_many
  • has_and_belongs_to_many

Quando usadas, adicionam alguns métodos (veja Detailed Association Reference). Por exemplo, ao declarar uma associação belongs_to, o model “ganhará” os seguintes métodos:

  • association(force_reload = false)
  • association=(associate)
  • build_association(attributes = {})
  • create_association(attributes = {})

Onde association, será substituído pelo nome da associação. Exemplo retirado do guides:

class Order < ActiveRecord::Base
   belongs_to :customer
end

Cada instância de Order, conterá os métodos:

  • customer
  • customer=
  • build_customer
  • create_customer

O association proxy, é o objeto que faz a ligação do objeto que contém a associação, conhecido como owner, e o objeto associado, conhecido como target.

Legal e daí !?!

Graças ao association proxy, ao declarar uma associação, podemos extendê-la e adicionar comportamentos “customizados”. No guia, é citado como Association Extensions. O código de exemplo abaixo, está no github em random-samples.

Para exemplificar, vamos criar um modulo que adiciona o comportamento de uma galeria a qualquer coleção.

module GalleryColletion
 
  def current=(curr = nil)
    @current, @index = nil
 
    if curr.nil?
      @current = collection.first
      @index = 0
    else
      collection.each_with_index do |item, index|
        if item.id.to_i == curr.to_i
          @current = item
          @index = index
        end
      end
    end
    @current
  end
 
  def current
    @current
  end
 
  def position
    @index + 1
  end
 
  def previous?
    return false if @index.nil?
    !!(@index - 1 >= 0)
  end
  def previous
    collection[@index - 1] if previous?
  end
 
  def next?
    return false if @index.nil?
    !!(@index + 1 < collection.size)
  end
  def next
    collection[@index + 1] if next?
  end
 
  private
 
  def collection
    proxy_owner.send(proxy_reflection.name)
  end
 
end

Gallery Collection

Note que o modulo está na pasta lib, logo, a pasta tem que ser adicionada no path via config/environment.rb.

Para extender a associação, declare:

class Article < ActiveRecord::Base
  has_and_belongs_to_many :images, :extend => GalleryColletion
end

Article model, Image model aqui.

Agora para navegar entre as imagens, você pode usar:

a = Article.first
a.images.current = 1 #1 e o Image.id que deseja selecionar
a.images.current
a.images.position
a.images.next?
a.images.next
a.images.previous?
a.images.previous

Caso esteja com coragem, baixe o projeto e veja rodando.

Dúvidas, sugestões, algum “case” de sucesso, comente!

Teste sua aplicação de Linha de Comando com Cucumber! 1

Posted by Roger Leite on maio 14, 2010

É engraçado como tudo é questão de treino e disciplina. Levei um tempo para me acostumar com TDD, Vim e não poderia ser diferente com testes funcionais, sendo mais especifico, Cucumber.

Até o momento, só tinha usado cucumber em projetos web. E quando voltei a desenvolver o rubygems_snapshot, senti falta de algo para testar funcionalmente. Baseado no pik, montei um esquema simples para validar qualquer aplicação de linha de comando.

Como instalar

Basicamente, será necessário (fontes via gist):

  • rake para executar o cucumber
  • env_terminal.rb
  • terminal_steps.rb

Dado que você tem cucumber instalado, com o esquema da pasta “features”.

  • Copie o cucumber.rake para a raiz.
  • Copie o env_terminal.rb para a pasta features.
  • Copie o terminal_steps.rb para a pasta features/step_definitions/terminal_steps.rb.
  • Edite o  env.rb incluindo (pode ser no começo):
require "env_terminal"
  • Dentro do Rakefile, pode ser no final mesmo, adicione:
load "cucumber.rake"

Como usar

Todas features:

rake cucumber

Features com a tag @wip, também conhecida como Work in Progress.

rake cucumber:wip

Informações Extras

Caso precise de mais informações, você tem a opção de ver a saída dos comandos, executando a rake assim:

rake cucumber show_output=true

ou

rake cucumber:wip show_output=true

No caso do snapshot, tive a necessidade de “modificar” o comando gem toda vez que era executado, ou melhor, passar um parâmetro para controlar o ambiente. Dentro do env_terminal.rb, existe o método gsub_command, nele você pode “redefinir” comandos, caso necessite.

Gostei, quero mais!

A solução acima, é bem “caseira”. Para projetos simples com funcionalidades simples, funciona bem.

Caso queira algo mais robusto, você tem a opção da gem Aruba.

Tem este post como introdução:

Aruba – Cucumber Goodness for the Command-Line

Rubygems Snapshot! Importando/Exportando gems com velocidade!

Posted by Roger Leite on maio 10, 2010

Nova versão do Rubygems_Snapshot no ar!

Fico feliz em dizer que este é o meu primeiro projeto que passou dos dez “watchers” ! :D E que realmente ajudou alguns developers mundo afora.

A primeira versão foi muito focada no uso pessoal, como “quebra-galho” mesmo. Resolvi investir algum tempo e praticamente refaze-lá, pois ao usar no dia-a-dia percebi algumas falhas e dificuldades de uso.

Basicamente, nesta nova versão:

- É possível trabalhar com mais de um formato. Yml e Tar, que é o padrão.

- Ao exportar, os arquivos “.gem” serão exportados.

- Ao importar, ocorre praticamente uma instalação “offlline”, muito mais rápido e livre de problemas com “sources” do rubygem !

- Usar o Snapshot como API !

Como tive um trabalhão para deixar o Readme legal, não pretendo escrever mais que isso! :D

Marcos, valeu pelo incentivo! Cara, forka lá e manda bala!

Importando e exportando suas gems com Rubygems Snapshot 2

Posted by Roger Leite on dezembro 22, 2009

Final de ano está rendendo.
O rubygems_snapshot nasceu da necessidade de “migrar” as gems instaladas de uma máquina para outra, aliado ao rvm (veja este post-guia-rápido), permite mudar e/ou criar diferentes ambientes em minutos. Assim você pode fugir do famoso “gem hell”.

Veja como é difícil usar:

Instalação:

sudo gem install rubygems_snapshot

Para exportar as gems instaladas:

gem snapshot export projeto-exemplo.yml

Supondo que esteja em outra máquina, para importar as gems, use:

[sudo] gem snapshot import projeto-exemplo.yml

Afinal, o que tem de legal nisso?

Vamos supor que você acaba de entrar numa nova equipe e tem que montar o ambiente de desenvolvimento (por sinal, um ambiente complicado de configurar). O gem snapshot aliada ao rvm, foi feito para facilitar isto, vamos a um exemplo rápido:

Com o rvm, você pode criar um “novo ambiente”:

rvm use 1.8.7%projeto_exemplo
gem list

Deve retornar vazio.

gem install rubygems_snapshot
gem snapshot import projeto-exemplo.yml

Instalará as gems necessárias para o projeto e pronto!

ToDo:

Esta é uma versão bem básica, onde o “import” somente lê as gem e version e manda instalar sem requerir dependências. Está previsto de colocar um aviso no final das gems que deram erro, geralmente devido a dependências de “build nativos”, mas por enquanto estamos usando aqui na equipe com sucesso.

Como faço para criar um rubygems plugin também?

Bom, logo de cara posso te garantir que não é difícil (apesar da pouca documentação na internet), mas deixarei os detalhes para um outro post. Por enquanto, a minha recomendação é: clone o projeto, analise os dois rb do projeto :D e crie o seu!

Caso algum corajoso for usar, estou a disposição para ajudar, é só deixar um comentário aê!
Valeu e sucesso!

Agile Enterprise Edition 3

Posted by Rodrigo Panachi on dezembro 21, 2009

Para começar o post, segue esta história sobre gerenciamento que vi no blog do Gustavo Ribeiro:

Todos os dias, uma formiga chegava cedinho ao escritório e pegava duro no trabalho. A formiga era produtiva e feliz. O gerente marimbondo estranhou a formiga trabalhar sem supervisão. Se ela era produtiva sem supervisão, seria ainda mais se fosse supervisionada.

E colocou uma barata, que preparava belíssimos relatórios e tinha muita experiência, como supervisora. A primeira preocupação da barata foi a de padronizar o horário de entrada e saída da formiga.

Logo, a barata precisou de uma secretária para ajudar a preparar os relatórios e contratou também uma aranha para organizar os arquivos e controlar as ligações telefônicas.

O marimbondo ficou encantado com os relatórios da barata e pediu também gráficos com indicadores e análise das tendências que eram mostradas em reuniões.

A barata, então, contratou uma mosca, e comprou um computador com impressora colorida. Logo, a formiga produtiva e feliz, começou a se lamentar de toda aquela movimentação de papéis e reuniões!
O marimbondo concluiu que era o momento de criar a função de gestor para a área onde a formiga produtiva e feliz, trabalhava. O cargo foi dado a uma cigarra, que mandou colocar carpete no seu escritório e comprar uma cadeira especial.

A nova gestora cigarra logo precisou de um computador e de uma assistente (sua assistente na empresa anterior) para ajudá-la a preparar um plano estratégico de melhorias e um controle do orçamento para a área onde trabalhava a formiga, que já não cantarolava mais e cada dia se tornava mais chateada.

A cigarra, então, convenceu o gerente marimbondo, que era preciso fazer um estudo de clima. Mas, o marimbondo, ao rever as cifras, se deu conta de que a unidade na qual a formiga trabalhava já não rendia como antes e contratou a coruja, uma prestigiada consultora, muito famosa, para que fizesse um diagnóstico da situação. A coruja permaneceu três meses nos escritórios e emitiu um volumoso relatório, com vários volumes que concluía: “Há muita gente nesta empresa!”

Então o marimbondo mandou demitir a formiga porque ela andava muito desmotivada e aborrecida.

Então lembrei de uma imagem que ilustra perfeitamente esta fábula e retrata fielmente a “organização” de alguma empresas:

Dividir para conquistar: você está fazendo isso errado!

Quando uma startup passa a vender mais e ter uma procura maior por seus produtos/serviços (o que é bom), uma reação comum da “cúpula” é aumentar o quadro de funcionários visando atender a demanda. Logo surgem os problemas com a organização do pessoal e/ou fluxo de trabalho. A solução mais simplista (e óbvia) é a especialização: fulano faz isso, ciclano faz aquilo, e beltrano gerencia. Logo controles são criados, fluxos validados, centros de custo, documentos, reuniões, atas, comitês, gestão de pessoas e relacionamento, terceirização, cargos, departamentos… e nasce o monstro da burocracia, aka “enterprise”.

Com essa especialização, cada “módulo” (também conhecido como departamento) começa a perder o foco no GRANDE objetivo da empresa e passa a defender apenas seus interesses – a famosa MISSÃO da empresa passa a ser coadjuvante. O resultado? A empresa dobra ou triplica seu quadro de funcionários e na maioria dos casos, seu lucro bruto. Porém agora tem mais despesas com pessoal e gastos extras para manter esse novo modelo “enterprise”. Trocando em miúdos, continua na mesma!

Onde está o erro? Mais uma vez o FOCO está na solução ao invés de PROBLEMA. Se você ler meus posts anteriores vai ver que este é um tema recorrente. Então por que as empresas continuam fazendo as coisas erradas e cometendo os mesmos erros?

Idéias criativas surgem das pessoas diretamente relacionadas com os problemas e não de diretores, contadores, gestores, etc. Esse modelo “enterprise” é um overhead organizacional que só gera ruído e desperdício!

A solução é adotar agile!

SOLUÇÃO!? Mas qual era o PROBLEMA mesmo!? Sim, mais uma vez o foco é a solução ao invés do problema.

Como eu disse nos posts anteriores, acreditar que uma mudança drástica do processo pode mudar a cultura da empresa e pincipalmente as pessoas é o maior erro na adoção de metodologias ágeis. Mudam o processo mas não mudam as pessoas.

De uma forma simples e direta, agile resume-se a quatro valores:

Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan

Ou seja, pessoas, software, colaboração e feedback. Simples assim!

O manifesto ágil não cita nada sobre “enterprise”, sobre a implementação. Este é o grande desafio em sua adoção. Como seguir estes valores sem burocratizar e engessar o processo? Como criar uma relação de colaboração com os clientes? Como responder rapidamente a mudanças? Como eliminar o esforço que não agrega valor ao produto e/ou empresa? Como evitar politicagem?

Mantenha-se pequeno!

Otimize! Busque soluções para os problemas que impedem de produzir mais e com mais qualidade. Faça MAIS com MENOS. Foque no O QUE ao invés do COMO. Escale as pessoas verticalmente!

Inove! Não espere conseguir resultados diferentes fazendo sempre a mesma coisa. Busque novidades, opniões, experiências. Ouça seus funcionários, seus clientes. Estude, pesquise, arrisque, erre, acerte… continuamente.

Mantenha o foco! Tenha um GRANDE e único objetivo e certifique-se que todos acreditem nesta filosofia. É importante que todos comprem a idéia e o modus operandis.

Finalizando, este é apenas meu ponto de vista, baseado na minha experiência em diversas empresas grandes e pequenas, vivenciando problemas, errando muito e principalmente aprendendo com os erros dos outros. Agilidade pode funcionar bem em grandes corporações, desde que haja foco e que todos comprem a idéia. Você pode concordar ou não.

Ruby, Rubygems e $LOAD_PATH ou Como funciona o require de gems

Posted by Roger Leite on dezembro 17, 2009

Na madrugada passada, andei “brincando” com o fonte do Rubygems. Logo de cara posso te dizer que não consegui fazer o que queria, e pra amenizar o sentimento de “perda de tempo”, resolvi postar alguns truques aprendidos.

Baixei o fonte do rubygems, como faço pra rodá-lo sem alterar o meu sistema?

Foi a primeira pergunta que fiz. Percebi que com o google não iria encontrar a resposta, mas consegui uma dica importante: $LOAD_PATH.

$ irb
irb(main):001:0> $LOAD_PATH

No meu Ubuntu, obtive:

["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]
$ ls /usr/local/lib/site_ruby/1.8/

Exatamente nesta pasta que se encontra o rubygems.rb. Bingo!
Para rodar o fonte do rubygems, só é necessário adicionar ao $LOAD_PATH a pasta lib do projeto. Dado que estou na raiz do projeto rubygems baixado, execute:

~/rubygems$ ruby -I $PWD/lib ./bin/gem -v

O paramêtro -I permite adicionar diretório ao $LOAD_PATH. Simples e prático. Primeiro problema resolvido, comecei a programar.

Afinal, como funciona o “require de gems”?

Bom, já sabemos que o require “rubygems” fuciona pois encontra-se no $LOAD_PATH do ruby, no caso do meu Ubuntu em “/usr/local/lib/site_ruby/1.8″.

Basicamente (e muito), o Rubygems faz duas coisas no Kernel do Ruby.

  • Adiciona o metodo Kernel#gem.
  • Faz um Monkey Patch no Kernel#require

Kernel#gem

Permite “acionar” uma versão específica de gem. Note que este acionar, traduz-se para, adicionar a lib da gem no $LOAD_PATH. Segue um trecho do comentário do Kernel#gem:

##

# Use Kernel#gem to activate a specific version of +gem_name+.

#

# +version_requirements+ is a list of version requirements that the

# specified gem must match, most commonly “= example.version.number”.  See

# Gem::Requirement for how to specify a version requirement.

#

# If you will be activating the latest version of a gem, there is no need to

# call Kernel#gem, Kernel#require will do the right thing for you.

#

# Kernel#gem returns true if the gem was activated, otherwise false.  If the

# gem could not be found, didn’t match the version requirements, or a

# different version was already activated, an exception will be raised.
[...]

Kernel#require

No final do rubygems.rb encontramos:

if RUBY_VERSION < ‘1.9′ then

require ‘rubygems/custom_require’

end

Não consegui descobrir o que acontece com o ruby 1.9, mas no 1.8, o monkey patch executa os seguintes passos:

  • Chama o “original” require;
  • Em caso de LoadError;
    • Executa o “Gem.searcher.find(path)”;
    • Se true
      • Chama o activate (novamente traduz-se para adiciona a gem no $LOAD_PATH)
      • Executa o “original” require novamente;

Exemplos com o IRB

Para finalizar legal e comprovar tudo isso, fiz alguns testes:

$ gem list json

*** LOCAL GEMS ***

json (1.2.0, 1.1.9)

json_pure (1.2.0)

$ irb
irb(main):001:0> $LOAD_PATH

=> ["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]

irb(main):004:0> require "json"

LoadError: no such file to load — json

from (irb):4:in `require’

from (irb):4

from :0

irb(main):005:0> gem "json", "= 1.2.0"

NoMethodError: undefined method `gem’ for main:Object

from (irb):5
from :0

O require “json” por si só, carrega a versão mais atual da gem.

irb(main):006:0> require "rubygems"

=> true

irb(main):007:0> require "json"

=> true

irb(main):008:0> JSON::VERSION

=> “1.2.0″

irb(main):009:0> $LOAD_PATH

=> ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]

irb(main):010:0> quit

Após o require “json”, as pastas foram adicionadas no $LOAD_PATH.

"/usr/lib/ruby/gems/1.8/gems/json-1.2.0/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/lib"

Agora olhe que interessante este último teste:

$ irb

irb(main):001:0> require "rubygems"

=> true

irb(main):002:0> $LOAD_PATH

=> ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]

irb(main):003:0> gem "json", "= 1.1.9"

=> true

irb(main):004:0> $LOAD_PATH

=> ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]

irb(main):005:0> JSON

NameError: uninitialized constant JSON
from (irb):5

irb(main):006:0> require "json"

=> true

irb(main):007:0> JSON::VERSION

=> “1.1.9″

irb(main):008:0> quit

Note que após o gem “json”, “= 1.1.9″ … a versao 1.1.9 foi adicionada no $LOAD_PATH mas não foi carregada. Ao executar o require “json”, como este já estava no $LOAD_PATH, a versão 1.1.9 é usada.

Espero que com estas explicações, você use com mais segurança o rubygems.

Rails Summit 2009 1

Posted by Rodrigo Panachi on outubro 23, 2009

Estamos de volta depois de algumas semanas de correria e muito trabalho, o que nos impediu de postar sobre vários assuntos atuais e experiências recentes. Também migramos de empresa. Agora o Roger e eu estamos trabalhando em uma empresa maior, focada em conteúdo digital, desenvolvendo aplicações de grande porte com Ruby e Rails :)

O evento

Se você não soube do Rails Summit 2009 ou não sabe nem o que é Rails recomendo que acesse este site. Deixando o sarcasmo de lado, a edição 2009 do Rails Summit foi muito boa. As palestras foram excelentes (com algumas poucas exceções). Os coffe-breaks e as locagirls também!

Rails Summit 2009 Locaweb

Quem não conseguiu ir este ano pode conferir o que aconteceu e assistir a algumas palestras nos seguintes links:

http://akitaonrails.com/2009/10/17/rails-summit-2009-retrospectiva

http://andrefaria.com/2009/10/15/rails-summit-2009-chad-fowler/

http://andrefaria.com/2009/10/19/rails-summit-gregg-pollack/

http://marciotrindade.com/2009/10/13/rails-summit-2009-parte-1

http://marciotrindade.com/2009/10/14/rails-summit-2009-parte-2

http://marciotrindade.com/2009/10/16/rails-summit-2009-parte-3

Rails não escala

Das palestras técnicas, focadas em Ruby e Rails, destaco a do Gregg Pollac: On The Edge of Rails Performance, que falou sobre algumas ferramentas e plugins para ajudar a melhorar a performance de aplicações Rails.

O estreiante Pratik Naik também deu algumas dicas muito boas para melhoar a performance e falou um bouco sobre suas experiências com Rails.

Para finalizar, o Bruno Miranda fechou falando sobre sua experiência com o desenvolvimento do Cyloop, uma rede social de música, mostrando os problemas enfrentados com escalabilidade e as estratégias utilizadas para resolvê-los.

E claro que não podia deixar de falar da excelente palestra do Fábio Kung sobre metaprogramação com Ruby, apresentando um hands-on, ou seja, <faustao>quem sabe faz ao vivo</faustao>, para criar uma DSL em Ruby e outras técnicas de magia negra como Callbacks, que pretendo abordar com mais detalhes aqui no blog.

Resumindo, projetar aplicações Rails escaláveis não é uma tarefa trivial e deve ser pensada com muito cuidado. Pretendo explorar mais este assunto nos próximos posts do blog.

Agilidade a seu favor

Apesar de ser um evento sobre Rails, um tema predominante foi agile. A largada foi dada pelo Chad Fowler que falou sobre a insurgência Ruby on Rails, incentivando o movimento ágil a “quebrar as regras”, parar de fazer as coisas que sabemos que estão erradas! Também ressaltou que é preciso ter coragem e atitude para rejeitar os moldes corporativos e lutar contra os trolls, os guardiões da cascata.

O Akita realmente surpreendeu com sua palestra “Agile, beyond chaos”. Explicou os princípios do manifesto ágil e comprovou cientificamente o “porque” agile funciona!

A palestra sobre empreendedorismo do Vinícius Teles foi uma verdadeira aula, contando um pouco da sua história, as dificuldades e obstáculos superados até conseguir transformar o Be on the Net em realidade. Resumindo: ganhe dinheiro fazendo o que você gosta e ajudando as outras pessoas a ganhar dinheiro!

Finalizando com chave de ouro, o Obie Fernandez falou sobre a “arte” do desenvolvimento de aplicações. Assim como um artista que precisa praticar muito para atingir a excelência, um programador precisa praticar e codificar muito… “O que você está esperando? Fuck the enterprise!”

Resumindo, falou-se muito sobre agilidade usando ruby e rails como uma ferramenta pragmática. As empresas de software sérias já estão usando Ruby. É a linguagem ideal para o modelo ágil.

Comentários do Roger

Tomei a liberdade de adicionar uma nota neste post do Panachi, pois como participante do Rails Summit 2008, resumidamente notei três coisas do evento:

  • A infra estrutura do evento estava muito melhor, mais espaço, mais organização e sem o calor infernal do ano passado. Parabéns para o Akita e o pessoal da Locaweb pelo ótimo trabalho e evento mais uma vez!
  • Tivemos ótimas palestras técnicas sobre como melhorar a performance de aplicações Ruby!
  • Em 2008 a grande mensagem foi “Participe!”. Ficou bem claro a importância de participar de projetos e contribuir. Este ano, a grande mensagem foi “Fuck the Enterprise!“. :D

Ruby: quando a linguagem de programação faz diferença! 3

Posted by Rodrigo Panachi on agosto 18, 2009

Pretendo neste post falar um pouco da minha evolução na programação e como Ruby e Rails agregaram mais conhecimento e me tornaram um melhor desenvolvedor.

A gente se forma na faculdade e de repente estamos trabalhando como programador em alguma empresa de software. A primeira coisa que você vai concluir é que nada a maioria das coisas que foram ensinadas na faculdade não se aplicam na vida real. Triste realidade…

Mas como um bom programador (que você é) logo começará a se questionar e se interessar por novos assuntos, aprender novos conceitos e técnicas de programação, pois você não se sentirá confortável fazendo as mesmas tarefas repetitivas ou que não sejam otimizadas.

Orientação a objetos

Nada de cachorrinhos ou pessoas com ações como andar, comer, etc. No mundo real, seus problemas são faturas, notas fiscais, relatórios, importadores de arquivos, planilhas… e por aí vai. Seu primeiro desafio será de entender a orientação a objetos de verdade. Mas não se preocupe se isto demorar um pouco pois logo a “lâmpada” acenderá e tudo ficará claro como o dia.

Linguagem e frameworks

Agora você consegue modelar os objetos da sua aplicação mas se depara com assuntos técnicos que podem ser solucionados prontamente utilizando-se frameworks e alguns recursos avançados da linguagem em questão. Logo você estará visitando os sites da documentação do Struts, do Hibernate, do Ant… e descobrirá que o nome Apache, além de tribo indígena, é muito mais do que um servidor Web. Após muitas provas de conceito e algumas noites sem dormir, você será um programador muito produtivo e confiante.

Análise e documentação

Parabéns! Aqui você já pode ser considerado um desenvolvedor. Logo seu destaque na equipe será recompensado com mais trabalho de corno desafiador. Nesta fase sua empresa se parece com uma padaria: “Me vê meio quilo do relatório X”, “Faz dois webservices pra viagem!”, “Aí, saindo uma fornada de casos de uso…”, etc. Logo alguém tem a brilhante idéia de “documentar” tudo desde uma simples alteração no CSS do sistema até complexos e numerosos diagramas e notações daquele novo sistema para integração. No começo a novidade até parece ser uma boa idéia, mas logo você vai descobrir que o que realmente importa é ouvir os problemas dos clientes.

Testes

Se você não teve a sorte de ser orientado desde o começo da sua carreira sobre desenvolvimento guiado por testes, você aprende a importância de testes da melhor maneira possível: tomando na cabeça! Os problemas começam a ficar mais claros. Você fica mais focado na tarefa que está desempenhando e felizmente também cresce profissionalmente com este aprendizado. Você se pergunta como conseguia desenvolver sem testes e por que a linguagem que você utiliza não tem um suporte mais “nativo” a testes.

Metodologia

No decorrer da sua experiência você tentará desempenhar suas atividades de várias maneiras. Quando você faz de tudo um pouco acha que o melhor seria fazer apenas uma tarefa específica mas depois descobre que estava enganado. Neste ponto você provavelmente já experimentou pelo menos duas metodologias de desenvolvimento e saberá identificar as vantagens e desvantagens em cada uma.

Agilidade

Felizmente sua experiência o guia para um caminho mais ágil. Após aprender e aplicar os mandamentos do manifesto ágil e aprimorar seus conceitos e habilidades técnicas, desenvolver aplicações torna-se uma tarefa “natural” que você desempenha com fluência independente da linguagem ou tecnologia utilizada. Suas maiores conquistas se resumem em conseguir contornar um problema tecnológico ou limitação da linguagem, negociar o escopo do projeto com o cliente, implementar a maior cobertura de testes possíveis, automatizar processos durante o desenvolvimento, etc.

Neste ponto você começa a se questionar: o que devo fazer agora para evoluir profissionalmente?

Ruby!

Eis que você conhece Ruby e Rails. A linguagem parece estranha a primeira vista mas após algum tempo dedicado e muito estudo você descobre que é uma ferramenta muito poderosa e produtiva, onde você pode “fluir” com seu desenvolvimento. Você pensa no que quer fazer e faz! Escreve sua “feature”, implementa e roda! Simples e divertido!

Ruby e Rails vieram suprir uma necessidade e/ou carência dos desenvolvedores por simplicidade. Até seu surgimento, desenvolver aplicações nas linguagens populares do mercado era uma tarefa complicada e trabalhosa. Ruby é uma linguagem poderosa. Rails é simples e muito produtivo. Combinação perfeita!

O que você tá esperando? Comece agora mesmo a estudar Ruby e Rails e seja feliz!

UPDATE: para não causar confusão, alterei o título. Lembre-se: Ruby é linguagem e Rails é framework!