Archive for Mayo, 2010

Ramificando en Mercurial

Lunes, Mayo 31st, 2010

En el artículo anterior prometí volver a hablar de Mercurial y heme aquí cumpliendo la promesa.

En este caso quiero hablar de uno de los cambios más importantes en la filosofía respecto a subversion: la ramificación (o branching).

Ramificando en Subversion

En svn la ramificación se realiza de un modo bastante rudimentario, aunque bonito a su manera. Ya sabéis cómo funciona, así que no me extenderé, y lo contaré todo en plan resumen.

La ramificación se hace con la orden branch. Al ejecutarla, se crea una copia de la estructura del directorio origen, al directorio destino, incluyendo toda la información de historial y revisiones.

Las convenciones nos dicen que en el directorio trunk se encuentra la rama principal (de ahí el nombre, tronco), donde está el desarrollo estable. Las ramas de desarrollo se almacenan todas dentro del directorio branches (ramas), y a veces se ramifican también las versiones estables que salieron a la luz en releases.

Pera esta estrucutura no es más que, como hemos dicho, convenciones. SVN no sabe qué directorio es una rama, o cuál es el principal. Nosotros usamos source/trunk en lugar de trunk, y podríamos usar ramas en lugar de branches como nombre de directorio para las ramas.

De hecho SVN, no sabe qué es rama y qué es tronco, y aquí es donde vienen los quebraderos de cabeza. Cuando fusionamos ramas mediante la orden merge, tenemos que especificar qué revisiones vamos a mezclar. Eso significa muchas veces bucear por los historiales de unas ramas y otras para saber cuándo se creó la rama y cuál fue el último cambio en fusionarse.

Ramificación en Mercurial

En Mercurial no existen ramas en un repositorio. Cuando quieres hacer una rama, te creas otro, clonándolo del padre (orden clone).

Esto puede embrollar un poco el desarrollo con varias ramas, sobre todo si hay distintos desarrolladores trabajando sobre distintas ramas, pero el control de las ramas y los cambios que van de una a otra puede ser más fino, menos rudimentario.

Así, resulta muy cómodo para el programador crearse las ramas de los diferentes aspectos o versiones en las que esté trabajando, y propagar los cambios de una a otra.

Yo recomiendo una estructura absolutamente jerárquica, en la que estén muy claros qué rama empuja los cambios a cuál, y no mezclarlas, ni crear flujos extraños.

Ejemplo

En la entrega anterior hablé de las ramas o repositorios que creé para las modificaciones de OpenTPV. Hoy, aparte de repetirlo, voy a poner un gráfico.

Partimos de la base de Openbravo POS, la aplicación original. Openbravo POS tiene su respositorio en Mercurial, de ahí mis inicios con este SCV. Opensistemas tiene su propio fork de Openbravo POS. Cuando se usaba SVN, mantener OpenTPV actualizado era muy laborioso, puesto que había que ir generando parches e irlos aplicando. Ahora con Mercurial, sólo tenemos que ir haciendo pull del contenido cuando haya alguna actualización.

Por tanto creé OpenTPV como un clon de Openbravo POS, sobre el que hice las modificaciones. Además, consideré oportuno crear un repositorio estable y otro de desarrollo, por lo que cloné el estable.

Ahora, ciertas modificaciones que quería nuestro cliente no las consideraba apropiadas para la versión oficial de OpenTPV, por lo que creé otro repositorio más, clon del de desarrollo. Por último, el cliente quería una versión para resoluciones pequeñas, así que creé otro clon para poder ofrecer ambas.

Una vez tenemos definidos los repositorios que vamos a tener, hay que diseñar la dirección en la que se propagarán los cambios. Si colocamos cada clon debajo de su original, podemos considerar útil propagar los cambios hacia arriba (push) o hacia abajo (pull). En la corta experiencia que tengo con Mercurial no recomiendo mezclar direcciones.

Juntando todo, la estructura más lógica es la siguiente:

Ramas de OpenTPV

Así, cada vez que tenía que añadir una funcionalidad (o corregir un bug), analizaba la parte a la que correspondía aplicar:

  • Si la funcionalidad era apropiada para OpenTPV, la aplicaba a la rama OpenTPV desarrollo. Después propagaba los cambios hacia las versiones de los clientes.
  • Si era una funcionalidad querida por el cliente, pero no apropiada para OpenTPV, lo aplicaba sobre la versión del cliente. Después propagaba los cambios hacia la versión de baja resolución.
  • Si era un cambio de interfaz para baja resolución, lo aplicaba sobre la personalización de baja resolución exclusivamente.

Hablando de Redes Sociales

Lunes, Mayo 31st, 2010

Efectivamente son habituales los perfiles de personajes famosos en las redes sociales, y en muchos casos existen perfiles no oficiales por decirlo así.

En estos días he investigado el estado del arte en cuanto a redes sociales y me he encontrado que existen cada vez más redes sociales temáticas: artistas, ciudadanas,  educativas, religiosas, etc., esto consolida aún más su implantación en Internet.

Y como es de esperarse el mundo del Software Libre facilita aún más el desarrollo de las redes sociales mediante aplicaciones como Elgg, Dolphin, OpenSocialNetwork, etc. sin dejar de lado la posibilidad de usar un CMS tradicional. Nos encontramos ante una nueva forma de comunicación de la que apenas estamos vislumbrando su potencial, se ha creado el cargo de Community Manager en las empresas, cuya responsabilidad es desarrollar la estrategia de promoción de la empresa, de las campañas comerciales y atención a usuarios  en las redes sociales, esto modifica el escenario habitual de las estrategias de marketing y los medios a utilizar, ahora no se puede dejar de lado la inclusión de las redes sociales en las campañas mediáticas.

Éxito social de Twitter

Martes, Mayo 25th, 2010

Me parece impresionante el protagonismo que está teniendo la red social Twitter en los últimos tiempos. Esta mañana oyendo el programa “Hoy empieza todo” de Radio 3 en el coche escuché que comentaban que tanto Gandhi como Hugo Chavez tenían su cuenta de Twitter …

La verdad que yo sigo el Twitter  de algún que otro personaje famoso y no me termina de sorprender, pero es que he hecho una búsqueda rápida de 8 ó 10 personajes famosos y el 100% de ellos tienen su cuenta creada y actualizada en la mayoría de los casos …, lo que no está tan claro que ellos en persona mantengan la información actualizada o que por el contrario tengan a alguien trabajando para eso ;-) Evitente en casos como el de Gandhi por motivos evidentes.

A continuación una tablita de mi búsqueda de esta mañana:

Fidel Castro
Hugo Chávez
Barack Obama
Cristiano Ronaldo
Jose Luis Rodríguez Zapatero
Mariano Rajoy
Baltasar Garzón
Evo Morales

Y en algún caso, como con Hugo Chávez no he podido evitar copiar alguna perla como la siguiente “¿ Expropiar Yo? Ei capitalismo te lo iva a quitar pero me adelanté. Ahora es de todos y aunque ahora no tengas nada te salve“.

Nada más, solo dar mi humilde enhorabuena a Twitter y animaros a tod@s los que aún no lo uséis a probarlo.

Nota: Espero no ofender a nadie con la frase de Hugo Chávez ya que este blog en ningún caso pretende ser un blog político.

Googlear tu blog por seguridad

Martes, Mayo 25th, 2010

El otro día encontré un breve artículo en el que comentaba la necesidad de googlear tu blog debido a que la gente lo puede utilizar para poner spam.

“Hace algunos días me puse a buscar algunos artículos en otros blogs a través de Google, pero al obtener los resultados noté algo extraño en lo que mostraba Google: en lugar de los títulos adecuados, aparecían frases típicas de enlaces de spam. Por ejemplo, en Dokshor.com, de mi compañero AyerViernino Fabián Ramírez”

ejemplo de busqueda

ejemplo de busqueda

Redes sociales con localización, otro punto de vista

Martes, Mayo 25th, 2010

Existen varias redes sociales de este tipo, algunas de las más conocidas son Google Latitude, Foursquare, MyTown…

Estas redes podrían utilizarse para la captación y fidelización de clientes. Centrandonos por ejemplo en Foursquare, el usuario típico de la red sería: varón, rondando los 30 años, trabajador en activo, urbanita y techie.

Actualmente la red esta en fase de crecimiento, y habrá que ver si aguanta el tirón de Google Latitude.

Estamos preparados para dar el salto, la alta penetración de redes sociales como facebook facilita la migración hacia nuevas propuestas como foursquare

Debajo os pongo la fuente, pero hay partes del articulo que voy a copiar literalmente, especialmente la parte dedicada a la fidelización de clientes:

“Grandes oportunidades para la distribución minorista

Por último, entre los resultados del estudio también hay datos que justifican el que grandes enseñas americanas de la distribución minorista, como Starbucks, se hayan apresurado a tomar posiciones en foursquare. Los usuarios potenciales, y en especial los que ya lo son, se muestran muy interesados en utilizar la aplicación tanto para conocer las ofertas y promociones que ofrecen los establecimientos que estuvieran próximos a su ubicación, como por recibir descuentos en aquellos negocios que se frecuentan con mayor asiduidad. Sin duda, redes sociales como foursquare abren la puerta a nuevas formas de captación y fidelización a la distribución minorista.”

Fuente aquí

Vídeo demo Nuxeo DM · 5.3

Miércoles, Mayo 12th, 2010

El equipo de Open Sistemas y Omoi Studio ha elaborado el siguiente vídeo (que hemos tenido que partir en dos por restricciones de youtube) para mostraros como es el comportamiento de Nuxeo DM.

El vídeo repasa, mediante el siguiente guión, los aspectos más relevantes de la herramienta:

  • 01 Introducción
  • 02 La barra de navegación
  • 03 El árbol de documentos: Áreas de trabajo
  • 04 Plantillas
  • 05 Lista de trabajo y portapapeles
  • 06 Nuevo Documento
  • 07 El Documento
  • 08 Gestión de usuarios y control de acceso
  • 09 Motor de búsqueda
  • 10 Panel de control

Espero que te haya gustado y te animo a que realices los comentarios que estimes oportunos ;-)

Para más información puedes seguir leyendo aquí

Europa duda de la legalidad del canon digital en España

Martes, Mayo 11th, 2010

El canon digital sólo puede gravar los equipos, aparatos y materiales de reproducción digital que presumiblemente se utilicen para realizar copias privadas, y no puede aplicarse indiscriminadamente a empresas o profesionales que los utilicen claramente para otras finalidades

Verica Trstenjak, abogada general del Tribunal de Justicia de la Unión Europea (UE).

Más claro, el agua.

catch (Exception e) {}

Martes, Mayo 4th, 2010

Hola, me gustaría compartir con vosotros un viejo truco de los programadores Java.

Cuando empezamos a hacer algo medio serio con el lenguaje, a la primera compilación nos encontramos con que el compilador nos molesta constantemente en lugares donde hemos invocado métodos de terceros, con mensajes como éste:
unreported exception java.io.IOException; must be caught or declared to be thrown

Esto es muy molesto, porque si se te ocurre lanzar la excepción hacia arriba, luego te encontrás con el mismo mensaje en otro punto del código. Y si la capturas, casi seguro que te molesta con otra excepción diferente, y así hasta no acabar nunca.

Pues aquí está el supertruco:

Cuando quiera que aparezca el molesto mensaje, rodeas la línea, el método entero o bien un conjunto aleatorio de líenas con la expresión
try {

}catch (Exception e) {}

y tus problemas se desvanecen por arte de magia.

Bueno, hasta aquí la ironía. El objeto de este artículo es llamar la atención de esta práctica que no por ser mala se encuentra poco extendida. Incluyendo una enorme cantidad, apostaría a que más del 50% de los códigos en producción.

El problema con el catch (Exception e) {}

¿A qué viene tanta inquina? Bien, el problema es que meter todo el código en este tipo de bloques es subvertir el sistema de excepciones, que, aunque no lo parezca, no se ha creado con objeto de fastidiar.

Lo que se pretende evitar es que, como sucedía con el manejo de errores tradiconal (generalmente a través de devolución de valores por una función), no te olvides de considerar los posibles percances en la ejecución.

Ya no estamos en la facultad, donde te pueden pasar la mano, ni en un programa chusco que te creas para una tarea cotidiana, que si peta lo ejecutas otra vez o ves qué le pasa tranquilamente. Estamos haciendo software que ha de comportarse de forma correcta siempre, y que ha de saber cómo reaccionar ante la más inusitada circunstancia, en vez de dar un batacazo cuando ocurra algo que no se nos haya ocurrido al programar.

El compilador de Java con las excepciones se comporta como una madre o un padre que a vece puede resultar pesado, pero lo hace por tu bien, diciéndote lo que necesitas aunque no quieras oírlo. Es muy difícil que mientras programamos se nos ocurran todas las cosas que pueden ir mal: ¿permisos? ¿espacio en disco? ¿no se pueden resolver nombres? ¿la codificación de caracters no está soportada? ¿el fichero comprimido está corrupto?

El compilador (con la ayuda del que programó la biblioteca que usas) es el amigo que te dice: “¡Eh! ¿Y si la cuenta del usuario ha expirado?”, cuando a ti no se te había ocurrido pensarlo. Lo más inteligente no es ponerse los auriculares e ignorar los avisos.

Manejo responsable de excepciones

Me gustaría daros un criterio mecánico sobre cómo tratar las excepciones. Desgraciadamente, es un arte y debe formar parte del diseño del programa. Dónde recoger y tratar una excepción va a depender íntimamente de la lógica del programa.

Os dejo unas pautas a tener en cuenta:

  • Lo principal es pensar en el problema que ha sucedido y cómo afecta al flujo del programa. Comprobar si se puede solucionar dentro del mismo método (catch), o si hay que dejar la excepción vaya hacia arriba (throws).
  • Hay que ver igualmente, las líneas de código que van invalidadas por la excepción, y asegurarnos de que estén todas dentro del bloque try. Esto puede suponer que reordenemos las líneas de código para que estén juntas las líneas que dependen unas de otras.
  • Hay que poner antención a qué se va a ejecutar tras la excepción, y si sigue teniendo sentido cuando se ha producido el fallo. Hay que mirar tanto las líneas posteriores dentro del mismo método, como las que pertenecen a los métodos donde se llama al que falla.
  • Considerar si hay que deshacer algún cambio ante el fallo (liberar un bloqueo, desconectar del servidor, hacer rollback de una transación, etc)
  • No hacer catchs ni throws genéricos (como recoger Exception), sino recoger las excepciones concretas que puedan producirse. Por mucho que poner 6 catch en un bucle pueda ser pesado.
  • Observar lo útiles que nos son las excepciones para afrontar imprevistos y de qué forma son más útiles, para nosotros a nuestra vez crear excepciones en nuestro código que sean útiles y manejables.
  • No dejar para mañana lo que podamos hacer hoy. Si colocas un try{…}catch (Exception e) {} en el código cuando estás empezando, pensando que ya tratarás los errores más tarde, te encontrarás que después es muy difícil gestionar correctamente las excepciones, pues tu código no estará organizado de una forma propicia.

Puede que tengamos la sensación de que estamos programando enfocados principalmente a las excepciones, pero eso no es malo. Si empezar a aplicar estos principios te causa muchos problemas, significa que estabas haciendo las cosas muy mal (ver último punto).

nullPointerException

Otro problema que puede ser peor son las “excepciones silenciosas”, término que invento sobre la marcha para referirme a aquellas de las que el compilador no se va a quejar. La más habitual es nullPointerException, y nos va a servir para enteder por qué existen. Tan sólo hay que pensar en que cada llamada a un método podría dar esta excepción si la variable sobre la que llama es null.

La nullPointerException no debería atraparse ni gestionarse nunca (o casi nunca). Siempre que ocurre, se debe a un error de la programación.

En vez de atrapar nullPointerException, lo que debemos hacer es pensar en todo momento si las variables tendrán un valor adecuado con seguridad. Si la variable puede ser null (por ejemplo, porque así la devuelve el API que usamos), entonces debemos comprobarlo antes de hacer algo con ella. El qué hagamos en caso de ser null, dependerá también de la lógica del programa, y, de nuevo. El asegurarnos en todo momento de que las variables van a tener un valor correcto, es otra de las cosas que vamos a tener que tener en mente mientras diseñamos y programamos.

Si se nos olvida la comprobación, ya que el compilador no avisa, nos enteraremos generalmente porque el programa cascará con una bonita traza de excepción que nos dirá dónde metimos el gambazo. Si se nos ocurrió rodear el bloque donde ocurre con un try {…} catch (Exception e), no nos enteraremos de que la ejecución se abortó en otro punto, y el problema explotará en otro lugar del código, haciendo difícil rastrear lo que ocurrió.

Ejemplos de mal uso

Supongamos un trozo de código:
Filostro f = null;

try {
Chumba ch = foo.getChumba(); // Llamada que provoca la excepción
f = ch.getFilostro();
} Exception (e) {}

Muy mal. Porque si hay resulta que foo no tiene “chumbas”, f se queda como null, la ejecución se aborta, y nosotros nos hemos quedado tan campantes.

Cuando vayamos a usar f, nos encontraremos un nullPointerException… si es que no hemos rodeado ese bloque con un try{…} catch Exception (e), momento en el cual nos podemos echar a temblar porque las consecuencias pueden ser imprevisibles.

Excepciones a las excepciones

En realidad hay algunos momentos, muy específicos, donde se puede justificar un try{…}catch(Exception e). Supón que vamos a entregar un programa final. Es muy feo que la ventana desaparezca de golpe porque ha ocurrido algún error no contemplado (ej: nullPointerException). Podemos incluir un catch (Exception e) en algún punto muy de alto nivel, que se encargue de loguear el error e informar al usuario de que ha ocurrido un error.

Lo mismo se puede aplicar a páginas webs. Una página tipo “ha ocurrido un error” es fea, pero no tanto como si es tomcat el que se encarga.

Eso sí, insisto en que es *un* punto a muy *alto nivel*, y siempre con mucho control de lo que estamos haciendo. Recuerda que un gatito muere en cada catch (Exception e), por lo que no queremos que ocurra más a menudo de lo necesario.

Terminando

Ha sido un poco árido, pero espero que a partir de ahora me ayudéis a erradicar es mala práctica que tanto nos da que llorar.

Desactivada versión v13 del api de google adwords

Martes, Mayo 4th, 2010

Hace una semana aproximadamente, se desactivaron herramientas que utilizaban muchos programas desarrollados para seo, debido a la migración de la versión v13 del api a la v200909. Todas las herramientas que no se hayan actualizado, dejarán de funcionar. Los servicios eliminados son:

CampaignService
AdGroupService
CriterionService
AdService
InfoService
KeywordToolService
SiteSuggestionService

El resto de servicios, seguirán funcionando igual.
Por otro lado, la nueva versión ofrece estos servicios y muchos más, pero encapsulados en distintas funciones. Las principales mejoras de la nueva versión son:

* Asynchronous bulk job support: Use BulkMutateJobService to build, schedule, and retrieve jobs that can operate on thousands of campaign objects.
* Location extension support: Use CampaignAdExtensionService to augment your text ads with information about your business’s physical location. You can also override location extensions on a per-ad basis using AdExtensionOverrideService For more information about how ad extensions work, read the AdWords Help Center overview.
* Keyword and placement ideas: Use TargetingIdeaService to generate new keyword and placement ideas for your campaign ads.
* API usage retrieval: Use InfoService to get information about your API usage, such as the amount spent on an operation in the past month or the number of API units available.
* Ad parameters: Use AdParamService to perform on-the-fly updates to parameterized snippets of ad text.

Os dejo el fuente aquí con las mejoras y los cambios de la api actual.

Mercurial, explicado para usuarios de Subversion

Martes, Mayo 4th, 2010

Debido a que los repositorios de Openbravo son de Mercurial, en los últimos meses me he tenido que acostumbrar con ese sistema de control de versiones (SCV).

Para alguien que sólo ha trabajado con Subversion (o anteriores), esto significa un importante cambio de filosofía, puesto que Mercurial se engloba dentro de los más modernos sistemas de control de versiones distribuidos (como Git, Bazaar y otros). Lo que voy a contar es específico de Mercurial, pero estos cambios vienen motivados por su característica de distribuido.

El principal cambio es respecto a la redifinición de los conceptos de cliente y servidor. En SVN, la separación está muy clara: el servidor aloja las versiones y se encarga de su gestión. Por otro lado, los distintos clientes se bajan copias del servidor, realizan cambios, y envían esos cambios al servidor.

SCV tradicional

En toda esta relación está claro quién es quién. En nuestra máquina local tenemos el cliente, y en el servidor el repositorio. Con Mercurial la cosa cambia mucho, porque cada copia del repositorios es a la vez cliente y servidor. En lugar de hacer checkout, para hacerte con un repositorio cliente del servidor, haces clone, con lo que creas un nuevo repositorio cliente-servidor copia del anterior. Las operaciones de commit y update funcionan en local, mientras que se introducen nuevas operaciones (pull y push) para intercambiar cambios entre repositorios. Todo junto quedaría en el siguiente esquema:

SCV distribuido

Esta estructura es bastante más compleja que un SCV tradicional, pero ofrece una serie de ventajas que compensan el aprendizaje inicial. Se suele decir que las principales ventajas son relativas a proyectos grandes, con un montón de colaboradores y varias personas validando grupos de estos colaboradores. Sin embargo, mi experiencia es que incluso cuando hay un único desarrollador, hay beneficios importantes.

Una ventaja que puede parecer secundaria, pero que a mí me encanta, es la capacidad de realizar commits locales. Esto permite trabajar con el control de versiones aún cuando no tienes acceso al servidor princiapl (circunstancia muy frecuente). Esto permite que los desarrolladores incomunicados puedan hacer commits con cambios pequeños y atómicos, en lugar de realizar un envío masivo donde todos los cambios van a tropel y hacen inmanejables logs, control de cambios y vueltas atrás.

Hablando de vueltas atrás, con Mercurial también es posible revertir cualquier fichero a cualquier revisión sin necesidad de conexión con el servidor. Los programadores que se han visto en estas situaciones adversas (como proxies) durante largos periodos pueden valorar estas ventas.

Pero quizá la ventaja más importante está en el prácticamente nulo esfuerzo requerido para clonar repositorios. Por ejemplo, cada vez que un cliente nuevo requiere una personalización de Openbravo POS, se le puede crear un nuevo repositorio simplemente clonándolo. Luego cada desarrollador clonaría de este nuevo repositorio y compartirían los cambios a partir de él.

Si es el caso de OpenTPV, la versión de Opensistemas de Openbravo POS para negocios de restauración, la estructura sería Openbravo POS -> OpenTPV -> versión del cliente . Si hay cambios en el repositorio principal de Openbravo POS, es trivial irla bajando a OpenTPV y a sus modificaciones. Si arreglamos un bug, dependiendo de la raíz del problema, podemos corregir Openbravo POS, OpenTPV o la versión del cliente, y luego difundir esos cambios a los que corresponda.

La única desventaja que le encuentro a Mercurial es que requiere algo más de control y pensar bien cómo organizar estos repositorios. En otras entradas planeo contar un poco más de esto ya que, por si no se ha notado, Mercurial me ha encantado.

Por todo esto, yo recomendaría su uso, o al menos probarlo. Quizá algún día merezca implantarlo a nivel oficial en la empresa, como alternativa al madurito Subversion.