lunes, 31 de agosto de 2009

Branches remotos en git

Git es un poderoso sistema de gestion de versiones, que entre otras cosas, esta pensado para gestionar branches ( cosa que por ej svn no tiene ), al ser git descentralizado y al ser de uso comun con varios repositorios para un mismo proyecto, surge la necesidad de crear ramas de manera distribuida tambien, algo que no es muy intuitivo.


1) Con git push se crea el branch en el repositorio remoto (en este caso origin), asi de simple

git push origin HEAD:refs/heads/nombre_del_branch


2) Despues tenemos que asegurarnos de tener actualizado el repositorio

git fetch origin


3) Verificamos que el branch remoto ha sido creado

git branch -r


4) Generar un branch local que "trackee" el branch remoto

git checkout --track -b nombre_del_branch origin/nombre_del_branch


Ese ultimo comando crea un branch local que "trackea" el branch que se creo antes en el repositorio remoto. Y con trackear implica que los cambios y commits del branch remoto vendran a este branch local al hacer git pull e iran de nuestro branch remoto al hacer git push.

Fuente: http://www.zorched.net/2008/04/14/start-a-new-branch-on-your-remote-git-repository/

jueves, 16 de julio de 2009

Ruby RAII

RAII (Resource Acquisition Is Initialization) es una técnica aplicable en muchos lenguajes de programación como C++ y los lengujaes .net que sirve para asegurar que la liberación de un recurso siempre se llevara a cabo al cerrarse un bloque de código sin importar que evento ocurrise (retorno de una funcion, excepcion, etc...). Ruby por supuesto que cuenta con esta posibilidad a través del uso de métodos con bloques de código (palabra clave yield)

He aqui un ejemplo:


#
# La clase X tiene un metodo open para inicializar (open)
# Y uno para cerrar, seria una tragedia si el metodo open
# se invocara y no se invoque el close correspondiente al final
#
#
class X
def open( argument1, argument2 )
print "open with argument1=#{argument1} and argument2=#{argument2}\n"
end

def operation1
print "running operation1\n"
end

def operation2
print "running operation2\n"
end

def close
print "closing\n"
end
end


#
# Mejor usar RAII
#

class X
def self.open( *args )
x_instance = X.new
x_instance.open( *args )
begin
yield(x_instance)
ensure
x_instance.close
end
end
end


#
# Y se usa asi
#
X.open( "arg1", "arg2" ) do |x|
x.operation1
x.operation2
end




Espero que os haya iluminado

martes, 23 de junio de 2009

NilClass horror

Un horror




# el nil class es la clase de la cual nil es instancia
class NilClass
# todo metodo desconocido que es invocado sobre el nil
def method_missing(method_obj,*args)
method_obj.to_s
end
end

print nil.koiiiewiiriieiw,"\n"

print @oooooooooooooooooooooo.blahhhhhhhhhhhhhhhhhhhhhhhhh,"\n"
print @ewewewwwewo.dakishimetakokoronokusumo,"\n"

# un horror
print $uqhwuiqwhrqrqwrkjwqhrjkqwhrqwkjrhqwrjkwqrhkqwrjqwrj.l,"\n"



Un horror

domingo, 21 de junio de 2009

Comparacion de rangos

Es muy común al programar, encontrarse con la necesidad de verificar algún rango de algo:


# la manera "dificil"
if a > 3 and a < 9 then
print "a esta entre 3 y 9\n"
end


Mejor asi, usando el operador ===


# la manera "canchera"
if (3..9) === a then
print "a esta entre 3 y 9\n"
end


Como si esto fuera poco, el operador === tiene todos los usos que uno se pueda imaginar, como por ej, para verificar si un texto matchea una expresion regular:


# la manera "canchera"
if /^ruby/ === txt then
print "'#{txt}' tiene ruby al principio\n"
end


Y si se les da la gana, pueden usar este operador en sus propias clases (también obviamente definirlo o redefinirlo para la clase existente que quieran)



class X
def ===(a)
print a,"\n"
end
end

viernes, 5 de junio de 2009

Ruby hooking

Les traigo un truco que los asombrara... con una tenica de hooking aplicada al ruby para poder enganchar los metodos que quieran de cualquier objeto y controlar su ejecucion, asi como registrar llamados a ese metodo , filtrar cosas, etc.

Aca el module q lo hace posible:

hooking.rb


module Hook
def hook( method_name, hook_name = nil, old_method_name = nil)

obj = self

# si no se le pasa el nombre de la funcion que controla el hook
# arma un nombre de funcion
hook_name ||= "#{method_name}_hook"

#lo mismo con el nombre de la variable de instancia
# que almacena la referencia al metodo original
old_method_name ||= "__old__#{method_name}"

# almacenar el metodo original
eval("@#{old_method_name} = self.method( method_name.to_sym)")

# redefinir el metodo para que invoque el metodo de hook, pasandole
# un bloque de codigo que ejecute el metodo original, entonces el metodo
# de hook puede invocar al metodo original usando yield
eval("
def obj.#{method_name}(*x)
self.#{hook_name}(@#{old_method_name},*x) do |*x|
yield(*x) if block_given?
end
end
")

end
end

class Object
# includir el modulo de Hook en Object para que se pueda aplicar a todo Object
include Hook
end



Y ahora un pequeño ejemplo de como podria usarse

main.rb


require "hooking"

class X

def foo( num )
print "metodo foo invocado con num = #{num}\n"
end

def bar
print "metodo bar invocado\n"
[1,2,3].each do |x| yield(x) end
end

end

x = X.new

x.hook(:foo)

def x.foo_hook( foo_original, num )
print "foo invocado\n"

# se invoca al metodo original, pero alterando los parametros
foo_original.call( num+1)

print "fin de foo\n"
end

x.hook :bar
def x.bar_hook( bar_original )

print "bar invocado\n"

bar_original.call do |x|
# tambien se puede alterar y controlar
# el uso de yield del metodo
yield(x+2)
end

print "fin de bar\n"
end


x.foo(3)
x.bar do |x|
print x,"\n"
end

martes, 21 de abril de 2009

Programacion ruby EN un celular :p


No pude evitar observar la palabra clave del ruby "def" (se usa para DEFinir metodos en ruby) en una de las teclas del celular, asi que imagine: esto esta pensado para programadores de ruby, en seguida me puse a pensar como seria programar EN un celular:





# para pner cmtrios ay q scrbrlos tods asi
# est mtodo c pue d usr cmo print
def abc(ghi)
print ghi,"\n"
#porq noay na tcla cn "end" en l celu?
end
abc "hla mndo!"
abc "cmo ests"