Arquivo

Textos com Etiquetas ‘Rails’

Múltiplos construtores em Ruby (minha versão)

10 de setembro de 2010

Ontem, através de uma mensagem no Twitter do André Moreira, estava lendo um post no blog do Rinaldi Fonseca falando sobre múltiplos construtores em Ruby. Comecei a escrever um comentário, que acabou se tornando muito grande. Então achei melhor escrever aqui para expressar minha opinião a respeito.

Na primeira parte do post é mostrado a utilização de métodos de classe para construir um novo objeto passando parâmetros diferentes dos recebidos no construtor, onde foi usado esse exemplo:

class Carro
  attr_accessor :marca, :placa, :dono

  def initialize(marca, placa, dono)
    @marca, @placa, @dono =  marca, placa, dono
  end

  def Carro.carro_sem_dono(marca, placa)
    new marca, placa, "SEM DONO"
  end

  def Carro.carro_sem_placa(marca, dono)
    new marca, "SEM PLACA", dono
  end
end

carro = Carro.new "Ferrari", "ABC1234", "João"
carro_sem_dono  = Carro.carro_sem_dono "Vectra", "ABC5678"
carro_sem_placa = Carro.carro_sem_placa "Palio", "José"

puts carro.inspect           #<Carro: @dono="João", @placa="ABC1234", @marca="Ferrari">
puts carro_sem_dono.inspect  #<Carro: @dono="SEM DONO", @placa="ABC5678", @marca="Vectra">
puts carro_sem_placa.inspect #<Carro: @dono="José", @placa="SEM PLACA", @marca="Palio">

Os métodos carro_sem_dono e carro_sem_placa seguem o Factory Method Design Pattern (Padrão de Projeto Método Fábrica) e atuam como uma DSL na classe Carro. Desse modo, não há necessidade da redundância do nome da classe no ínicio de cada método fábrica:

class Carro
  attr_accessor :marca, :placa, :dono

  def initialize(marca, placa, dono)
    @marca, @placa, @dono =  marca, placa, dono
  end

  def self.sem_dono(marca, placa)
    new marca, placa, "SEM DONO"
  end

  def self.sem_placa(marca, dono)
    new marca, "SEM PLACA", dono
  end
end

carro = Carro.new "Ferrari", "ABC1234", "João"
carro_sem_dono  = Carro.sem_dono "Vectra", "ABC5678"
carro_sem_placa = Carro.sem_placa "Palio", "José"

puts carro.inspect           #<Carro: @dono="João", @placa="ABC1234", @marca="Ferrari">
puts carro_sem_dono.inspect  #<Carro: @dono="SEM DONO", @placa="ABC5678", @marca="Vectra">
puts carro_sem_placa.inspect #<Carro: @dono="José", @placa="SEM PLACA", @marca="Palio">

Já na segunda parte do post é mostrada uma maneira de se passar um bloco para o construtor da classe Carro e assim inicializar seus atributos:

class Carro
  attr_accessor :ano, :marca, :modelo, :dono, :cor, :tipo

  def initialize(&block)
    instance_eval &block
  end
end

carro = Carro.new do
  self.ano    = "2000"
  self.marca  = "Gol"
  self.modelo = "Exemplo"
  self.dono   = "Dono exemplo"
  self.cor    = "Vermelho"
  self.tipo   = "Tipo exemplo"
end

puts carro.inspect #<Carro: @ano="2000", @marca="Gol", @modelo="Exemplo", @dono="Dono exemplo", @cor="Vermelho", @tipo="Tipo exemplo">

Eu particularmente gosto do tipo de inicialização de atributos de um novo objeto permitada nas classes da camada Model de Ruby on Rails. O método new dessas classes (que herdam de ActiveRecord::Base) podem receber tanto um hash quanto um bloco com os valores dos atributos. Dessa maneira, a classe Carro poderia ser inicializada assim:

carro = Carro.new :ano => "2000",
                   :marca => "Gol",
                   :modelo => "Exemplo",
                   :dono => "Dono exemplo",
                   :cor => "Vermelho",
                   :tipo => "Tipo exemplo"

#ArgumentError: wrong number of arguments (1 for 0)

Eu disse poderia. Não pode, pois o construtor new espera um bloco e não um hash, e Carro não é uma classe Model do Rails.

Para solucionar isso, podemos modificar o construtor da classe Carro para receber um hash de atributos ao invés de um bloco. Então atribuímos cada valor presente no hash para seu respectivo atributo:

class Carro
  attr_accessor :ano, :marca, :modelo, :dono, :cor, :tipo

  def initialize(attributes = nil)
    attributes.each do |attr, value|
      self.send("#{attr}=", value)
    end unless attributes.nil?
  end
end

carro = Carro.new :ano => "2000",
                   :marca => "Gol",
                   :modelo => "Exemplo",
                   :dono => "Dono exemplo",
                   :cor => "Vermelho",
                   :tipo => "Tipo exemplo"

puts carro.inspect #<Carro: @ano="2000", @marca="Gol", @modelo="Exemplo", @dono="Dono exemplo", @cor="Vermelho", @tipo="Tipo exemplo">

Mas e se quisermos também ter a opção de inicializar a classe Carro passando um bloco? Sem problemas, usamos o comando yield passando como parâmetro self se um bloco foi fornecido:

class Carro
  attr_accessor :ano, :marca, :modelo, :dono, :cor, :tipo

  def initialize(attributes = nil)
    attributes.each do |attr, value|
      self.send("#{attr}=", value)
    end unless attributes.nil?

    yield self if block_given?
  end
end

carro = Carro.new do |c|
  c.ano    = "2000"
  c.marca  = "Gol"
  c.modelo = "Exemplo"
  c.dono   = "Dono exemplo"
  c.cor    = "Vermelho"
  c.tipo   = "Tipo exemplo"
end

puts carro.inspect #<Carro: @ano="2000", @marca="Gol", @modelo="Exemplo", @dono="Dono exemplo", @cor="Vermelho", @tipo="Tipo exemplo">

Nessa implementação sempre irá prevalecer o que vier no bloco. Então se você passar um hash e um bloco para o construtor ao mesmo tempo (o que é uma bizarrice), os atributos que coincidirem terão o valor que foi passado no bloco:

carro = Carro.new(:ano => "2000", :marca => "Gol", :modelo => "Exemplo") do |c|
  c.modelo = "MODELO DO BLOCO"
  c.dono   = "Dono exemplo"
  c.cor    = "Vermelho"
  c.tipo   = "Tipo exemplo"
end

puts carro.inspect #<Carro: @ano="2000", @marca="Gol", @modelo="MODELO DO BLOCO", @dono="Dono exemplo", @cor="Vermelho", @tipo="Tipo exemplo">

Esses eram meus comentários sobre o interessante assunto de construtores em Ruby.

Ruby , , , , , , ,

Returning em Ruby on Rails

5 de agosto de 2010

Quantas vezes você já criou algum método em Ruby que inicializa uma variável, atribui valores a ela e depois a retorna?

Veja o exemplo abaixo:

def some_values
  values = []
  values << "first element"
  values << "second element"
  values
end

some_values # => ["first element", "second element"]

A linha 2 é cria um array vazio, depois são atribuidos valores nas linhas 3 e 4, e finalmente na linha 5 o array é retornado pelo método.

Em Ruby on Rails existe o método returning da classe Object que facilita nossa vida nesses casos:

def some_values
  returning values = [] do
    values << "first element"
    values << "second element"
  end
end

some_values # => ["first element", "second element"]

Na linha 2 chamamos o método returning passando a variável que será retornada já atribuindo seu valor inicial. Dentro do bloco, nas linhas 3 e 4, então atribuímos os valores ao array.

Há também esse outro tipo de sintaxe:

def some_values
  returning [] do |values|
    values << "first element"
    values << "second element"
  end
end

some_values # => ["first element", "second element"]

Funciona da mesma forma, mas acaba sendo não tão intuitivo como o código anterior.

Veja um trecho de código utilizando o método returning, de um método auxiliar para testes de RSpec retirado de uma aplicação real:

def variants
  returning variants = [] do
    5.times do |priority| do
      variants << Factory.build(:variant, :priority => priority)
    end
  end
end

E olhe só como é simples a implementação do método returning:

def returning(value)
  yield(value)
  value
end

Ruby , , ,

[fisl11] O que rolou de Ruby e Ruby on Rails

27 de julho de 2010

Como nas edições anteriores, esse ano no fisl11 tivemos várias palestras relacionadas com Ruby e Rails.

Quarta, 21 de julho

No primeiro dia, mostrei o uso do Spree, uma plataforma completa de comércio eletrônico desenvolvida em Ruby on Rails, como base de um novo sistema de loja virtual da Locaweb.

Nessa apresentação foram mostradas algumas técnicas de metaprogramação Ruby para lidar com as extensões do Spree e organizar melhor seu código.

Os slides da palestra “Locaweb + Spree: transformando código aberto em um projeto comercial” estão disponíveis nesse link:
http://www.slideshare.net/Prodis/locaweb-spree-transformando-cdigo-aberto-em-um-projeto-comercial

Quinta, 22 de julho

Neste dia, Daniel Lopes iniciou o “Mini-curso de Ruby e Rails”, introduzindo a linguagem de programação Ruby e os primeiros passos de Ruby on Rails. Essa primeira parte do curso teve duas horas de duração com a sala lotada.

Sexta, 23 de julho

“Lapidando Ruby” foi uma palestra muito interessante de Mauricio Szabo. Foram apresentadas algumas práticas para deixar seu código Ruby mais limpo, e outras técnicas para que seus testes fiquem mais claros e compreensíveis.

Os slides dessa palestra estão disponíveis nesse link:
http://www.slideshare.net/mauricioszabo/lapidando-ruby

A exemplo do dia anterior, a segunda parte do “Mini-curso de Ruby e Rails”, de Daniel Lopes, também teve sua sala lotada. O foco foi em montar uma aplicação simples em Ruby on Rails.

Sábado, 24 de julho

No último dia do fisl11, tivemos praticamente uma Maratona Ruby on Rails.

Para começar, Fabio Akita apresentou em duas horas “Ecossistema Ruby on Rails”, falando sobre o que se formou em volta do Ruby on Rails, como soluções completas em diversas áreas como deployment, e filosofias de empreendedorismo e desenvolvimento ágil.

Os slides dessa palestra estão disponíveis nesse link:
http://www.slideshare.net/akitaonrails/fisl-11-ecossistema-ruby-on-rails

Logo em seguida, tivemos mais uma apresentação do Fabio Akita, dessa vez sobre “Dicas de Desenvolvimento Web com Ruby”, onde foram mostradas algumas soluções simples para resolver o problema de lentidão de aplicações Web, por conta do entendimento pobre da arquitetura Web e suas alternativas.

Os slides dessa palestra estão disponíveis nesse link:
http://www.slideshare.net/akitaonrails/fisl-11-dicas-de-desenvolvimento-web-com-ruby

E o vídeo usado na apresentação está em:
http://dl.dropbox.com/u/1732133/dicas-de-desenvolvimento-web-com-rails.zip

E para finalizar a maratona, Daniel Lopes deu a terceira e última parte do “Mini-curso de Ruby e Rails”, finalizando a aplicação Ruby on Rails iniciada no segundo dia do treinamento e mostrando várias dicas interessantes sobre Rails.

Os slides de todo mini-curso estão disponíveis nesse link:
http://www.slideshare.net/danielvlopes/minicurso-ruby-e-rails

E o código fonte está em:
http://github.com/danielvlopes/fisl

.
Além disso, a galera do #HoraExtra esteve presente programando e publicando aplicações pequenas, desenvolvidas em Ruby on Rails, durante todo o fisl11. Mais detalhes do como isso aconteceu, você pode ver aqui.

Um abraço a todos os Railers que estiveram presentes ou que acompanharam virtualmente mais esse grande evento.

Eventos, Ruby , , , , , , , , ,

[fisl11] Sala de recepção dos palestrantes

25 de julho de 2010

O site do fisl11 trouxe várias notícias durante o evento.

Estava dando uma olhada nessas notícias e encontrei uma foto minha na sala de recepção dos palestrantes, onde conversei com um rapaz que trabalhava na comunicação do evento sobre minha apresentação.

Foto retirada do site do fisl11

Foto retirada do site do fisl11

Veja um trecho da notícia:

…Fernando Hamasaki de Amorim, da Locaweb, já está com sua palestra pronta e aguardando. “Transformando código aberto em um projeto comercial” às 20h na sala 41E de hoje.

Fernando pretende apresentar um estudo de caso onde ele irá relatar os desafios e dificuldades, vantagens e desvantagens em utilizar código aberto para criar um novo sistema. “Vou falar também de códigos aberto em detalhes e mostrar como se ganha dinheiro com software livre. O código é aberto, mas alguém ganha com isto”, explicou. Mais detalhes vale a pena conferir a palestra de Fernando.

.
Para ver a notícia completa, acesse o link abaixo:
http://softwarelivre.org/fisl11/noticias/sala-de-recepcao-dos-palestrantes-esta-lotada

Eventos , , , , , , , , ,

[fisl11] Slides da apresentação Locaweb + Spree: transformando código aberto em um projeto comercial

22 de julho de 2010

Veja os slides da palestra “Locaweb + Spree: transformando código aberto em um projeto comercial” que foi apresentada em 21/07/2010 no fisl11.

Agradeço a todos que estiveram presentes.

Eventos , , , , , , , , ,

[fisl11] Confirmadas data e hora da palestra Locaweb + Spree

12 de julho de 2010

Está confirmada data, hora e sala da minha palestra “Locaweb + Spree: transformando código aberto em um projeto comercial” no fisl11.

A apresentação será no dia 21/07 às 20h na sala 41-E fisl 5.

Veja também:

Eventos , , , , , , , , ,

[fisl11] Minha proposta de palestra foi aceita

21 de junho de 2010

Nos dias 21 a 24 de julho, será realizado em Porto Alegre o fisl11, o 11º Fórum Internacional de Software Livre.

O FISL é o maior evento de software livre da América Latina e a edição do ano passado atingiu a marca de 8.244 participantes.

Entre os assuntos que serão abordados, estão:

  • Linux, Ubuntu, KDE, BSD
  • Desenvolvimento em Ruby, Java, PHP, Python, Perl e Smalltalk
  • Desenvolvimento de Jogos, Multimídia e Streaming
  • Gerenciamento de Dados (SGBD, Storage, backup…)
  • Hardware, Sistemas Embarcados e Robótica
  • Segurança
  • Software livre e negócios
  • Educação e Inclusão Digital

Minha proposta de palestra “Locaweb + Spree: transformando código aberto em um projeto comercial” para o fisl11 foi aceita.

Segue o resumo da palestra:

Os desafios, benefícios, dificuldades e lições aprendidas que a equipe de desenvolvimento de SaaS da Locaweb teve na utilização do Spree, uma plataforma de comércio eletrônico de código aberto, como base de seu novo sistema de loja virtual multi-usuário, desenvolvido em Ruby on Rails. O poder e o dinamismo do Ruby tiveram destaque, com grande utilização de metaprogramação nas extensões do Spree.

Eventos , , , , , , , , ,

Screencasts sobre Ruby on Rails 3

14 de junho de 2010

Em um keynote da RailsConf 2010, Gregg Pollack divulgou uma série de screencasts sobre Ruby on Rails 3.

Dive into Rails 3
http://rubyonrails.org/screencasts/rails3

Esses screencasts foram feitos por ele em parceria com a EnvyLabs.

Veja também esses slides da RailsConf 2010:

Keynote do Gregg Pollack
http://s3.amazonaws.com/dhhmix/rails3-railsconf2010.pdf

Tutorial “The Rails 3 Ropes Course”
http://assets.en.oreilly.com/1/event/40/The%20Rails%203%20Ropes%20Course%20Presentation.pdf

Na RailsConf 2010 foi anunciado o Rails 3 beta 4 e que a versão release candidate seria lançada até o final do evento. Ainda não foi lançado, mas deve estar disponível nos próximos dias.

Eventos, Ruby , , , , ,

Material de estudo sobre Ruby on Rails 3

14 de junho de 2010

Para acompanhar melhor os tutorias e apresentações relacionadas ao Ruby on Rails 3 que rolaram na RailsConf 2010, separei uma série de artigos/posts e fui lendo na viagem de ida.

Seguem os links:

Ruby on Rails 3.0 Release Notes
http://guides.rails.info/3_0_release_notes.html

Rails Edge Architecture
http://yehudakatz.com/2009/06/11/rails-edge-architecture

Rails 3: The Great Decoupling
http://yehudakatz.com/2009/07/19/rails-3-the-great-decoupling

ActiveModel: Make Any Ruby Object Feel Like ActiveRecord
http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord

Sexy Validation in Edge Rails (Rails 3)
http://thelucid.com/2010/01/08/sexy-validation-in-edge-rails-rails-3

validates :rails_3, :awesome => true
http://lindsaar.net/2010/1/31/validates_rails_3_awesome_is_true

Active Record Query Interface 3.0
http://m.onkey.org/2010/1/22/active-record-query-interface

Why Arel?
http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-wrote-arel

Active Record Query Interface
http://guides.rails.info/active_record_querying.html

The Rails Module (in Rails 3)
http://litanyagainstfear.com/blog/2010/02/03/the-rails-module

The Lowdown on Routes in Rails 3
http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3

Rails 3 I18n changes
http://blog.plataformatec.com.br/2010/02/rails-3-i18n-changes

Rails 3: Introdução a Javascript Não-Obstrutivo e Responders
http://www.akitaonrails.com/2010/05/10/rails-3-introducao-a-javascript-nao-obstrusivo-e-responders

Rails 3: Introdução a Engines
http://www.akitaonrails.com/2010/05/10/rails-3-introducao-a-engines

Customizing Rails Apps with Plugins
http://www.railsdispatch.com/posts/building-or-updating-a-rails-3-plugin

Upgrading a Rails 2 App to Rails 3
http://www.railsdispatch.com/posts/upgrading-a-rails-2-app-to-rails-3

Getting Rails 3 Edge with jQuery, RSpec and Cucumber using RVM
http://lindsaar.net/2010/5/9/Getting-Rails-3-Edge-with-jQuery-RSpec-and-Cucumber-using-RVM

Rails 3.0 Beta – 36 Links e artigos para você começar
http://www.rubyinside.com.br/rails-30-beta-36-links-e-artigos-para-voce-comecar-2947

Ruby , , , , , , ,

“Pretty print” para seus objetos Ruby

8 de abril de 2010

Vira e mexe, seja no irb ou no script/console, temos que exibir o conteúdo de objetos para examinar seus valores. A maneira mais comum para fazer isso é utilizando os método puts ou o método p, como no exemplo abaixo:

Esse tipo de exibição não é muito legível, principalmente se você estiver no script/console visualizando os dados de  um ActiveRecord:

No caso de objetos ActiveRecord, há a opção da exibição em YAML, chamando o método y no script/console:

Agora existe uma gem chamada awesome_print que permite exibir os dados dos objetos com identação e cores de acordo com o tipo de dado.

Primeiro vamos instalá-la:
$ sudo gem install awesome_print

E para exemplificar, vamos usar o script/console para exibir os valores de um hash. Note que é necessário fazer uma referência para o arquivo “ap”. Depois bastar chamar o método ap:

Uma coisa legal é que dependendo do tipo do valor, as cores são diferentes.

Agora veja um exemplo utilizando um ActiveRecord:

Uma ressalva negativa é a não exibição dos valores decimais, como acontece quando se exibe o ActiveRecord em YAML. Talvez para uma próxima versão isso melhore.

Há também algumas opções para customizar a forma como os dados são exibidos pela awesome_print, como por exemplo o tamanho da identação e as cores. Para mais informações, veja a documentação da gem: http://github.com/michaeldv/awesome_print.

Ruby , , , , , ,