Pasar de Perl a Python

Técnicas para migrar de Perl a Python legacy no probado

Convertir legacy Perl en Python puede ser una tarea desalentadora. En este artículo puede aprender algo sobre la teoría relacionada con el código legacy, incluyendo lo que no se debe hacer.

Noah Gift , Founder, GiftCS, LLC

Photo of Noah GiftNoah Gift es co-autor de Python For UNIX and Linux System Administration de O'Reilly, y también trabaja en Google App Engine In Action para Manning. Es autor, conferencista, consultor y líder comunitario, y escribe para publicaciones tales como Red Hat Magazine, O'Reilly, y MacTech. El sito de la Web de su compañía consultora es http://www.giftcs.com, y muchos de sus escritos los podrá encontrar en http://noahgift.com. Usted también podrá seguir a Noah en Twitter. Tiene un doctorado en CIS de Los Ángeles, Estado de California y una licenciatura en Ciencias Nutricionales de Cal Poly San Luis Obispo. Es administrador certificado de los sistemas Apple y LPI, y ha trabajado en empresas tales como Caltech, Disney Feature Animation, Sony Imageworks, Turner Studios y Weta Digital. Le gusta pasar su tiempo libre con su esposa, Leah, y su hijo, Liam, componer temas para piano, correr maratones y entrenar religiosamente.



21-01-2011

Voy a comenzar citando a Damian Conway en Perl Best Practices: "El enfoque de Perl "orientado a los objetos" es casi excesivamente Perlish: hay demasiadas maneras de hacerlo... Existen tantas combinaciones de implementación, estructura y semántica posibles que es muy raro encontrar dos jerarquías de clases no relacionadas que utilicen exactamente el mismo estilo de Perl OO".

Esta flexibilidad inherente al diseño del lenguaje Perl sin duda ha provocado la acumulación orgánica del código de Perl que todavía es técnicamente frágil para cambiar y difícil de comprender. Para agravar el problema existe la posibilidad de que los desarrolladores originales ya no estén más disponibles habiendo pasado a otros proyectos o compañías. Además de la carga del código legacy, los requisitos de la producción pueden haber cambiado o los nuevos vendedores de APIs están únicamente disponibles en Python. En este punto es donde comienza la monumental hazaña de pasar de Perl a Python.

Una vez que haya tomado esa decisión, necesita elegir la mejor estrategia para resolver el problema. Si usted tiene la suerte de tener una base de códigos de Perl lo suficientemente bien escrita y orientada a los objetos, con una cobertura de prueba completa, entonces esto podría ser tan simple como convertir las pruebas de las unidades de Perl a Python y luego hacer que el código de Python apropiado pase las pruebas de las unidades de Python recientemente transferidas. Aunque hay muchos programadores de Perl talentosos que escriben códigos bien documentados y legibles, estas personas no son tan comunes como deberían serlo. Lo más probable es que usted se encuentre en una situación en la que no tenga la menor idea de cómo funciona exactamente el código de Perl, que no sea tan sólo observarlo. Aquí es realmente en donde comienza la parte más compleja de pasar de Perl a Python.

Qué no se debe hacer: Llamar al código de Perl desde el nuevo código de Python

Automatizar la generación de prueba en Python

Los programadores de Python no deberían ser demasiado engreídos. Mientras que muchas personas están de acuerdo con que Python está diseñado de tal manera que lo convierte en un lenguaje de fácil comprensión, todavía pueden existir problemas también con el código de Python legacy no probado. Después de todo, Python no se prueba a sí mismo...¿o sí?

Una manera posible de lidiar con el problema de Pynthon legacy no probado es utilizar la herramienta de generación de pruebas Pythoscope. La misión de Pythoscope es "Crear una herramienta de fuente abierta que sea fácil de adaptar y ampliar que generará en forma automática, o semiautomática, las pruebas de las unidades para los sistemas legacy escritos en Python". Además, usted puede definir los puntos de entrada que en forma automática prueben las funciones basadas en su ejecución. Consulte la sección Resources para obtener un ejemplo detallado de cómo funciona esto.

Antes de profundizar en la forma adecuada de hacer las cosas, primero vamos a explorar lo que no debemos hacer. Es relativo a la naturaleza humana elegir el camino con menor resistencia cuando nos enfrentamos con un desafío. Convertir una década de crecimiento empresarial y no probado del código Perl en Python es un problema difícil, por lo tanto la solución más obvia parece ser encontrar un camino alrededor de la reescritura del código de Perl. Esta línea de pensamiento lo llevará luego a un módulo llamado perlmodule, que permite incorporar un intérprete Perl a Python. Entonces podría parecer simple llamar al anterior código de Perl desde el nuevo Python y hacerlo con él.

No es una buena idea, ¡porque ahora usted tiene un problema aún mayor que cuando comenzó! Usted posee un código legacy que no comprende y tiene un nuevo código que llama a un código que no comprende. Esto es como hacer un pago único con una tarjeta de crédito utilizando un anticipo en efectivo con otra tarjeta de crédito—lo único que logra es retrasar lo inevitable e incrementa su deuda técnica (vea Resources para obtener más información relacionada con la deuda técnica). Para empeorar las cosas, usted habrá "infectado" su nuevo código al incorporar errores sutiles que son difíciles o imposibles de probar. Por último, los nuevos desarrolladores que se incorporen al proyecto más adelante tendrán que trabajar con una base de códigos que sea una mezcla no aconsejable entre el Perl no probado y el Python insuficientemente probado.


Código legacy de prueba funcional con nose para crear nuevas especificaciones

En el libro Working Effectively With Legacy Code, el autor, Michael Feathers, dice, "Una de las cosas que casi todos notan cuando se trata de escribir pruebas para un código existente es lo poco adecuado que este código es para la prueba". Lo más probable es que usted note lo mismo cuando piense por primera vez en convertir el Perl legacy no probado a Python.

Un paso psicológico y técnico importante puede ser crear una prueba funcional que capture con precisión el resultado final del código de Perl que está intentando convertir. Por ejemplo, si usted está convirtiendo un script de Perl que analiza un archivo de registro de gran tamaño y genera un informe de valores separado por comas podría escribir una prueba simple, defectuosa y funcional para controlar qué ocurre realmente en el nuevo código que está escribiendo.

Para seguir adelante con el siguiente ejemplo, necesitará instalar nose. Si ya tiene instalada la herramienta Python easy_install, sólo tiene que emitir el comando easy_install nose. De no ser así, puede instalar setuptools en primer lugar siguiendo las setuptools installation instructions.

Superado este inconveniente, aquí hay una prueba del ejemplo de nose:

Listado 1. Prueba funcional de nose con errores cometidos intencionalmente
                #!/usr/bin/env python
                """First pass at porting Perl to Python"""
                
                import os
                
                def test_script_exists():
                """This test intentionally fails"""
                assert os.path.exists("myreport.csv")

Si usted continúa y realmente ejecuta esta prueba, debería tener este aspecto:

Listado 2. Resultados de la prueba
 linux% /usr/local/bin/nosetests F
    linux% /usr/local/bin/nosetests
    F
    ======================================================================
    FAIL: test_failing_functional.test_script_exists
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    File "/usr/local/Python/2.5/site-packages/nose-0.10.4-py2.5.egg/nose/case.py", 
    line 182, in runTest 
    self.test(*self.arg)
    File "/usr/home/ngift/tests/test_failing_functional.py", line 7, in test_script_exists
    assert os.path.exists("myreport.csv")
    AssertionError
    
    ----------------------------------------------------------------------
    Ran 1 test in 0.037s
    
    FAILED (failures=1)

Como puede ver en esta prueba con errores, la aseveración falló porque nunca hicimos nada para crear este archivo. Si bien esto en un comienzo puede parecer no tener ningún sentido, es un paso en el proceso de la planificación de tantas cosas como sea posible realizar en nuestro black back del código legacy.

Una vez que las pruebas funcionales que han sido escritas cubran lo más posible las especificaciones funcionales del código anterior, valdría la pena mirar para ver si usted puede identificar cualquier parte modular, comprobable y bien escrita de Perl para crear las pruebas de las unidades defectuosas. Más pruebas de error podrían ser escritas para esas partes del código hasta que una especificación razonable comience a tomar forma.

El paso final, que en realidad es el más complejo, es escribir a continuación el código de Python que pase esas pruebas que usted creó. Desafortunadamente, no hay una solución milagrosa. Pasar el código legacy no probado o a Perl o a cualquier otro idioma es simplemente difícil, pero escribir las pruebas con error podría ser de gran ayuda, y son una estrategia razonable.


Conclusión

Permítanme terminar citando a Guido Van Rossum en su artículo "Strong Versus Weak Typing": "Usted nunca podrá eliminar todos los errores. Hacer que el código sea más fácil de leer y escribir, y más transparente al equipo de lectores humanos que revisarán los códigos fuente puede ser mucho más valioso...."

Finalmente, la creación de un código legible y comprobable es una de las principales metas para convertir el código legacy en un nuevo lenguaje tal como Python, si se lo realiza de un modo simple. Abrazar este ideal puede eliminar un poco el miedo y el dolor del proceso. ¡Buena suerte!

Recursos

Aprender

Obtener los productos y tecnologías

  • Evalú los productos IBM del modo que mejor se adecue a usted: Descargue una prueba del producto, pruebe un producto en línea, utilice un producto en un entorno en nube o dedíquele unas pocas horas a SOA Sandbox aprendiendo cómo implementar eficientemente la Service Oriented Architecture.

Comentar

  • Involúcrese en la My developerWorks community. Conéctese con otros usuarios de developerWorks mientras explora los blogs, foros, grupos y wikis basados en los desarrolladores.

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que se registra en developerWorks, se crea un perfil para usted. Información sobre su perfil (nombre, país/región y compañia) estará disponible al público y acompañará cualquiera de sus publicaciones. Puede actualizar su cuenta IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Linux
ArticleID=619388
ArticleTitle=Pasar de Perl a Python
publish-date=01212011