May 14, 2011

ivanacostarubio

Refactor : Extraer una Clase y Metodo

Podemos hacer muchos tipos de Refactor pero hoy nos concentraremos en la extracción de una clase "extract class". Este se refiere al extraer una clase y agrupar los metodos relacionados con esta para terminar con dos clases que definan un poco mejor lo que esta pasando. Aqui les dejo un ejemplo:

              
              class CachedEvent
              
                def self.destroy_all
                  @db = Mongo::Connection.new('localhost').db("mydb")
                  coll = @db.collection('cached_events')
                  coll.remove()
                end
              
                def self.destroy(options={})
                  @db = Mongo::Connection.new('localhost').db("mydb")
                  coll = @db.collection('cached_events')
                  coll.remove(options)
                end
              
                def self.create(attributes)
                  ## PROBLEM
                  @db = Mongo::Connection.new("localhost").db("mydb")
                  coll = @db.collection('cached_events')
                  coll.insert(attributes)
                  return coll
                end
              
                def self.all
                  @document = Array.new
                  @db = Mongo::Connection.new("localhost").db("mydb")
                  coll = @db.collection('cached_events')
                  coll.find().each {|doc| @document << doc }
                  @document
                end
              
                def self.last
                  self.all[-1]
                end
              end
              

En el código anterior podemos ver que hay bastante duplicación. Esto es un olor que nos indica que algo esta mal. Recuerden que la duplicación es la causa de muchos problemas en la programación. Pedemos ver que duplicamos la llamada a la conexión a la base de datos, en este caso MongoDB, como tambien duplicamos el llamado a la colección llamada "cached_events".

              
              class MongoC
                def self.conection
                  $mongo_connection ||= Mongo::Connection.new('localhost').db('mydb')
                end
              end
              
              MongoC.conection
              
              class CachedEvent
              
                def self.collection_name
                   self.name.underscore.pluralize
                end
              
                def self.find_collection
                  $mongo_connection.collection(collection_name)
                end
              
                def self.destroy_all
                  self.find_collection.remove()
                end
              
                def self.destroy(options={})
                  self.find_collection.remove(options)
                end
              
                def self.create(attributes)
                  self.find_collection.insert(attributes)
                end
              
                def self.all
                  document = Array.new
                  self.find_collection.find().each {|doc| document << doc }
                  document
                end
              
                def self.last
                  self.all[-1]
                end
              end
              

En este segundo ejemplo podemos ver que el código esta factorizado mucho mejor. Tenemos dos clases. La primera clase se encarga de hacer la llamada de conexión a la base de datos. En la segunda clase podrán ver que realizamos algo parecido al "extract class" pero con el metodo find_collection. Esto lo llamamos "extract method".

Recapitulando podemos decir que:

Una señal para realizar un Refactor es ver parte de nuestro código que son parecidas o identicamente iguales.

Extract Class: es una tecnica en la cual de una clase extraemos otra para separar responsabilidades.

Extract Method: es una tecnica en la cual extraemos un metodos para rehusar en varios metodos dentro de la misma clase.

Apr 29, 2011

ivanacostarubio

Freedom Patching - los monos tienen derechos

Esto es un pequeño pedazo de codigo que ilustra una de las ideas centrales en Ruby. La habilidad de abrir clases de la libreria standar y modificarlas a gusto. Personalmente yo no recomiendo hacer tal cosa ya que contamina el espacio del objeto .

Con un gran poder viene una gran responsabilidad

              
              # FREEDOM PATCHING
              # because monkeys have right
              # http://vimeo.com/17420638
              
              class Object
                def has_attached_file(attribute, options={})
                  puts attribute
                  # WE CAN DO FANCY STUFF HERE
                end
              end
              
              # OBJECT IS A TOP LEVEL CLASS SO WE CAN CALL IT FROM HERE
              has_attached_file("On" + self.class.to_s)
              
              class Tickets # THIS CAN INHERIT FROM EVERYTHING. THAT INCLUDES ACTIVE RECORD
                # OR WE CAN CALL IT FROM HERE
                has_attached_file("On " + self.class.to_s)
              end
              
              Tickets.new
              
              class User
                def initialize
                  # WE CAN LEVERAGE THE INITIALIZE METHOD
                  has_attached_File("On " + self.class.to_s)
                end
              end
              
              Ticket.new
              
              # RELIGION WARS HAVE BEEN FOUGHT FOR THE CONCEPTS EXPRESSED HERE
              # AVOID WHEN POSIBLE / USE AT YOUR OWN RISK
              
Feb 22, 2011

ivanacostarubio

Exportando con Ruby CSV

Algo muy común al trabajar con data y ruby es exportarla a un archivo de Excel, Open Office o Numbers. Para esto podemos crear un archivo .csv. En solo dos pasos podemos lograr esto en ruby. El primero es crear un objeto con la data a exportar y el segundo es crear un archivo mientras iteramos sobre la data.

Seguir leyendo...

Tags: ruby