Continuum

Continuum

Continuum Chile: Agilistas y Desarrolladores Web en Java, Ruby, Rails ..Java, Python, Ruby, Javascript, Ajax, Web 2.0, ESB, SOA…
Continuum

Script python para borrar directorios recusivamente…

Este es un simple script hecho en python para borrar todos los directorios que terminen en un patrón.

#! /usr/bin/python
import os
import sys
def rmsvn(arg, dirname, names):
    if dirname.endswith(arg):
        print "Borrando directorio %s" % dirname
        """Puede no estar vacio, por tanto borramos hacia
        dentro recursivamente
        """
        for root, dirs, files in os.walk(dirname, topdown=False):
            # borramos los archivos
            for name in files:
                os.remove(os.path.join(root,name))
            # borramos los subdirectorios
            for name in dirs:
                os.rmdir(os.path.join(root, name))
        # ahora podemos borrar el directorio
        os.rmdir(dirname)
if __name__ == "__main__":
    os.path.walk(sys.argv[1],rmsvn, sys.argv[2])

Lo hice puntualmente porque había copiado el workspace (de eclipse) de un amigo y con la copia vinieron todos los directorios .svn (metadata de subversion), y el eclipse los interpretaba y mostraba el package explorer de forma inusual (fea)

Package Explorer

Entonces bastó con ejecutar:

./my-delete ./workspace .svn

y listo,

Packages Explorer (Eclipse)

Si quieren usarlo copien el script (en gris) hacia un archivo (digamos my-delete) y luego basta con ejecutarlo usando python o cambiando el modo del script (digamos sudo chmod 755 my-delete) y ejecutandolo en linux (debes tener instaldo el python)

Closures en JavaScript, Ruby, Python y Java

Introducción:

Para quienes ya programaron en lenguajes como C, C++, Pascal, y/o Java, y que a lo mejor solo conocian de la existencia de lenguajes dinámicos (mal llamados de script) como JavaScript, Lisp, o Python sin entrar en profundizar, seguramente no conocian o no conocen la palabra Closure.

Que es un Closure?

En el contexto de la programación un closure no es otra cosa que un bloque de código que puede ser pasado como argumento a la llamada de una función y está presente de forma nativa en la mayoría de los lenguajes dinámicos como Lisp, JavaScript, Smalltalk, Ruby, en Python (mediante los lambda).

Veamos un ejemplo en Ruby, JavaScript y Python (mis preferidos).

JavaScript:

var eachArr = function (arr, callback) {
    for (var i = 0; i < arr.length; i++) {
        callback(arr[i]);
     }
 };
eachArr( [1, 2, 3], function( e ) { alert(e); } );

Ruby (Nativo):

[1, 2, 3].each {|e| puts e}

Python (nativo a través de las lambda pero limitado a un bloque de una expresión, no obstante es posible crear closures pasando funciones como argumentos a otras funciones al igual que hicimos en el ejemplo de JavaScript):

def eachArr(arr, l):
    r = [];
    for e in arr:
        r.append(l(e))
    return r
print eachArr([1,2,3], lambda e: e*e)

Donde pueden aplicarse los Closures?:

Supongamos que hemos hecho una aplicación donde tenemos un listado de objetos productos y nos han pedido hacer un servicio para descubrir el listado de productos que pertenecen a una categoría.

En Java 5 que NO incorpora closures hariamos algo como esto:

public List pertecenenA(List l, String categoria) {
    List result = new ArrayList();
    for (Producto p : l) {
        if (p.perteneceA(categoria)) {
            result.add(p);
        }
    }
    return result;
}

En Ruby, sería algo como:

def pertenecenA(productos, categoria)
    return productos.select { |p| p.perteneceA(categoria) }
end

Aquí “select” es un método nativo de las listas en Ruby que acepta un closure y que debe retornar true/false basado en una expresión, en este caso el bloque de código pregunta si p(instancia de Producto, se omiten las definiciones para acortar el post) pertenece a la categoría, si retorna true Ruby automaticamente lo incluye en la sublista. Bien mas sencillo no?

Closures en Java:

Java (hasta la version 6) no incluye closures, sin embargo es posible simularlo usando clases anónimas (particularmente lo uso mucho). Por ejemplo, algo como:

public interface QueryProduct {
    boolean isTrue(Producto p);
}
public List query(List l, QueryProduct ask) {
    List result = new ArrayList();
    for (final Producto p : l) {
        if (ask.isTrue(p)) {
            result.add(p);
        }
    }
    return result;
}

de esta forma hemos implementado un pequeñoo framework que usa closures para hacerle consulta al listado de producto que retornen true o false, al igual que el select de ruby, por ejemplo el servicio anterior de si un producto pertenece a una categoría sería

public List pertecenenAUsandoClosure(List l, final String categoria) {
    return query(l, new QueryProduct() {
        public boolean isTrue(Producto p) {
            return p.perteneceA(categoria);
        }
    });
}

o entonces, conocer los que tienen un precio mayor a,

public QueryProduct precioMasAlto(final Producto p, final double precio) {
    return new QueryProduct() {
        public boolean isTrue(Producto p) {
            return p.getPrecio() > precio;
        }
    };
 }

Nota *: Esto es muy parecido a la implementación de templates, de hecho la forma en que es posible implementar closures en C o C++ es a través de templates.

Como pueden ver, esta solución es bien mas elegante, y genérica, aunque debemos reconocer la excesiva cantidad de código que necesitamos. Por otra parte a pesar que de esta forma simulamos los closures, en realidad no lo hace en su totalidad, pues un closure debe ser capaz de ser construido teniendo acceso a variables de contexto que existan en el momento de su definición y que a pesar que el closure sea invocado incluso cuando estas variables no existan más sea capaz de usarla como si fuera local a la invocación del closure.

Conclusiones:

Los closures son mecanismos que facilitan la vida del programador simplificando el código y haciendolo mas reusable y elegante, en el caso de Java, considero que Sun y James Gosling debían haber pensado en incluirlos de forma nativa evitandonos tener que escribir código para simularlo.

Entradas Siguientes »

 
Copyright © 2012 Continuum Ltda. Coronel Pereira 72. Oficina 903. Las Condes. Santiago. Chile
Tel: +56 2 9341951