La Coctelera

por Guillermo Álvarez

image

Diferencia entre extend e include (extend vs include)

La diferencia entre extend e include puede ser confusa a veces, por eso voy a intentar aclarar, como creo yo que es. Pero primero echemos un vistazo al rdoc

Obj.extend Mod.include



A jugar...

Vamos a poner este código de ejemplo:

 module A
   def a
     puts "Has llamado a A#a"
   end
 end
 
 module B
   def b
     puts "Has llamado a B#b"
   end
 end
 
 class C
   include A
   extend B
 end
 

La diferencia es que los métodos del módulo A son para la instancia y los métodos del módulo B son para la clase por lo que sería lo mismo que hacer:

 class D
   include A
   class << self
     include B
   end
 end
 

Esta técnica es muy usada en frameworks como merb. Cuando un objeto es incluido, se llama a:

   include InstanceMethods
   extend ClassMethods
 

Este es uno de los usos más típicos que he visto de include vs extend

Otras diferencias que me vienen a la mente son:

  1. extend es un método público, mientras que include no.
  2. Si se llama a una a extend de una instancia, es lo mismo que si la abrieses e incluyeses el módulo.

  3.  o = Object.new
     o.extend A
     class << o
       include B
     end
     
     o.a #=> Has llamado a A#a
     o.b #=> Has llamado a B#b
     

Y hasta donde yo se... no tiene mucho más misterio

30, dic | 3 comentarios Posteado por: cientifico compártelo Tags: classmethods, class, instancemethods, instance, include, extend, ruby

Añadir métodos a una clase o estancia creada

Actualización: Este post es de cuando empecé con ruby.

Pues más sencillo de lo que parece. Como es normal en ruby, la lógica aplastante por encima de todo y un simple "<<" bastará.

Por ejemplo.

En vez de hacer

def di_hola puts "hola chaval!" end

podemos hacer:

class << self def di_hola puts "hola chaval!" end end

O su manera enfuscada:

class << self; def hey; puts "hola chaval!"; end

Como llamar a metodos de un modulo

Estaba yo intentando llamar a un método de un helper. Probando encontré un método que sirve para extender clases con módulos.

Sé que esto es básico, pero por desgracia no me he leído todavía ningún libro sobre ruby. He de suponer que lo que estoy haciendo es un mixin de clases con los módulos.

La palabra clave es extend

Por ejemplo, si estoy en un ./script/console de rails, solo tengo que hacer un:

self.extend CommentsHelper

Para completar, es saber que módulos están cargados en la clase actual, vamos, que mixins se presentan.

self.extended_by

Espero que nadie pierda el tiempo que perdí yo intentando hacer esto.

30, dic | 3 comentarios Posteado por: cientifico compártelo Tags: extended by, rails, puts, extend, script, self, ruby

Descarga de urls desde consola

El otro día (hará ya 6 meses), poniendo plugins de compiz, tenía que descargar de manera rápida unos 8 o 9 urls. Como el ratón me parece un dispositivo bastante lento, quería hacerlo desde consola (con wget, curl o fetch), y se me ocurrió esta manera, que resultó bastante buena.

cat | xargs wget

Ahora un simple copy y paste de las urls, y a descargar.

Solo queda hacer que se descarguen todas de manera concurrente.

Nota: Solo podrás descargar un número máximo de archivos. Para saber este número teclea:
getconf ARG_MAX

Nota2: Con curl quedaría algo así como:

cat | xargs curl -O

30, dic | sin comentarios Posteado por: cientifico compártelo Tags: arg max, cat, getconf, descargar, wget, curl

Mod rails, auth y allow todo junto.

Como programadores modernos que somos, muchas veces tenemos que trabajar desde casa/estación de ski/playa/piscina/montaña, por eso la máquina de integración continua, donde se autodeploya el proyecto en cada comit, debe de ser accesible tanto desde dentro de la oficina como desde fuera. 
Sin embargo, la seguridad debe de ser tenida en cuenta como siempre, por lo que para acceder desde fuera de la oficina, queremos que pida contraseña. Tras más de 5 minutos investigando me ha quedado este archivo de configuración que permite acceder desde la office sin contraseña y desde fuera con contraseña.
<VirtualHost *:80>
      ServerName test.jobandtalent.com
      ServerAlias office.jobandtalent.com test.jobandtalent.com
      DocumentRoot /home/jobandtalent/jobandtalent/public
      RailsEnv talentorris
      <Location "/">
            Order deny,allow
            Deny from all
            Allow from 192.168.1
            Satisfy Any
            AuthType Basic
            AuthName "CI Machine is only for authorized personal only"
            AuthUserFile /etc/apache2/passwords
            Require user jobandtalent
      </Location>
</VirtualHost>

De aquí lo más interesante es esa directiva que está resaltada: Satisfy Any, que hace que hace el clásico OR entre los dos sistemas de autentificación que hay. IP y basic auth.
Ahora, ya puedo dormir sabiendo que tengo una contraseña menos que escribir...

1, dic | sin comentarios Posteado por: cientifico compártelo

Webs Autodeployables

Una de las últimas novedades en un proyecto personal, es el autodeploye, que pese a sonar tan mal, mola mucho.
Pongamos el caso de una aplicación rails, usando git para el control de versiones y servida por Apache2 y Passenger. Mi objetivo es que la aplicación se deploye en el momento que hago commit a una determinada rama. Para ello analicemos la forma de deployar en esta aplicación en concreto.
En este caso tenemos a la aplicación (merb) ejecutándose en /home/user/app/ y servida por passenger. El deploye entero se resumiría en tres simples pasos:
1.- git pull --rebase # Se descarga los cambios del servidor

2.- rake db:autoupgrade # Ejecutar las automigraciones

3.- touch restart.txt # Reiniciar el servidor

Ahora lo definimos como método privado del controlador de admin
def deploy

output = %x(git pull --rebase)

output << %x(rake db:autoupgrade)

output << %x(touch restart.txt)

output

end

private deploy

De esta forma, despues de un post en el controlador#método: admin/deploys#create la aplicación se verá automática deployada.

Y sí. Efectivamente admin/deploys es un resources donde se tiene guardados los deploys que se han hecho, que integrado con el sistema de gestión de excepciones de la aplicación, se pueden hacer millones de estadísticas interelacionadas por ejemplo fallos-commiter, proporción de fallos en función de la hora (interesante para prohibirse deployar a diferentes horas), fallos-controlador (saber que controladores son más susceptibles a fallo), etc...


Lo bueno de este sistema, es que... casualidades del señor todo poderoso que está de encierros, github permite especificar un hook, de git, de post, de app (fuuuuu...) para notificar el post-receive. GitHub hará un post a la url privada http://user:pass@mywebapp/admin/deploys/ (o /admin/deploys/create si no eres lo suficiente restful).

Cuando comitees a tu repo de git, github se encargará de autodeployar. :-)
TODO:

class Admin::Deploys < Application

before_filter :pass_tests, :only => :create

...
end

PD: Perdón por el espaciado. Es mi tercer post. Prometome a mi mismo mejorar. A los fieles bot lectores de mi blog que os den. Si eres humano, ¡¡¡ bienvenido !!!

9, nov | 2 comentarios Posteado por: cientifico compártelo

ReverseProxy de Apache a Monit

A veces se da la situación de que en el sistema tenemos varias aplicaciones con su propio servidor web. Es una pesadez recordar el puerto en el que se ejecutan, por lo que prefiero hacer un virtualhost con el nombre del programo.maquina.dominio. En este ejemplo monit.esther.cientifico.net.
Apache 2 debe tener los siguientes módulos activos:
proxy.conf
proxy.load
proxy_balancer.load
proxy_http.load
Para ello hacemos lo siguiente (suponiendo que es un ubuntu-server):
cd /etc/apache2/mods-enabled
ln -s ../mods-available/proxy.conf .
ln -s ../mods-available/proxy.load .
ln -s ../mods-available/proxy_balancer.load .
ln -s ../mods-available/proxy_http.load .
Y creamos un sitio en apache. Este sitio se crea en /etc/apache2/sites-available un archivo llamado monit, con el siguiente contenido. (Es un ejemplo)

<VirtualHost *:80>
ServerName monit.esther.cientifico.net
ProxyRequests Off

<Proxy *>
Order deny,allow
Allow from all
</Proxy>

ProxyPassReverse / http://127.0.0.1:2812/
</VirtualHost>
Por último activamos el stio creando un vínculo simbólico:

cd /etc/apache2/sites-enabled
ln -s ../sites-available/monit 002-monit
Obviamente has de substituir con tus propios valores.

9, nov | sin comentarios Posteado por: cientifico compártelo Tags: sistemas

Queridos reyes vagos...

Quiero esta sudadera para cuando salga de fiesta.

Estoy hasta las narices de que se acabe la cerveza y no tener otra. Son momentos en los que se pasa realmente mal, ya que tienes cigarro y no tienes cerveza para acompañarle. :-)

El señor todo poderoso, en respuesta a mis plegarias, me encontró la respuesta que buscaba.

Con esta sudadera, puedo viajar por el ancho mundo sin miedo a quedarme sin birra.

2, nov | 3 comentarios Posteado por: cientifico compártelo