<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2spanishfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-33066466</atom:id><lastBuildDate>Wed, 11 Nov 2009 05:12:18 +0000</lastBuildDate><title>Blog de Marcos Crispino</title><description /><link>http://blog.marcoscrispino.com/</link><managingEditor>noreply@blogger.com (Marcos Crispino)</managingEditor><generator>Blogger</generator><openSearch:totalResults>165</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/mcrispino" type="application/rss+xml" /><feedburner:emailServiceId>mcrispino</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-480371801807271681</guid><pubDate>Tue, 27 Oct 2009 12:52:00 +0000</pubDate><atom:updated>2009-10-27T10:52:12.170-02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">collaborative proyects</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Automatic Pattern Generator, lanzamiento del proyecto colaborativo</title><description>En una &lt;a href="http://blog.marcoscrispino.com/2009/10/automatic-pattern-generator-idea-para.html"&gt;nota anterior&lt;/a&gt;, comentaba una idea para presentar en los &lt;a href="http://www.gxtechnical.com/cp"&gt;Collaborative Projects 2.0&lt;/a&gt;, de hacer un generador de patterns basado en código que ya existe en una base de conocimiento.&lt;br /&gt;
&lt;br /&gt;
Por suerte en la nota había dicho que no lo iba a hacer... lo que demuestra una vez más que lo único constante es el cambio. Con &lt;a href="http://ealmeida.blogspot.com/"&gt;Enrique&lt;/a&gt; queríamos presentar algo, y decidimos presentar este proyecto.&lt;br /&gt;
&lt;br /&gt;
Desde ya damos la bienvenida a todos los que quieran sumarse al proyecto. Se necesitan desarrolladores, documentadores, testers, beta testers, etc. También se aceptan ideas y sugerencias.&lt;br /&gt;
&lt;br /&gt;
El primer paso ahora va a ser definir el alcance y hacer una primera iteración, con una versión que genere un pattern a partir de una instancia compuesta por un único procedimiento, lo más sencillo posible. Cuando eso esté pronto, vamos a tener más claro el panorama y podremos repartir tareas entre los interesados.&lt;br /&gt;
&lt;br /&gt;
En breve estaremos publicando el proyecto en el Wiki de la comunidad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-480371801807271681?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/Szipq49NWSg/automatic-pattern-generator-lanzamiento.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/10/automatic-pattern-generator-lanzamiento.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-440056060285622914</guid><pubDate>Tue, 20 Oct 2009 12:12:00 +0000</pubDate><atom:updated>2009-10-20T11:35:09.065-02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">open source</category><category domain="http://www.blogger.com/atom/ns#">collaborative proyects</category><category domain="http://www.blogger.com/atom/ns#">c#</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Neptuno.net Open Source</title><description>&lt;a href="http://www.concepto.com.uy/"&gt;Concepto&lt;/a&gt; acaba de hacer público el proyecto Neptuno.net, que consiste en una aplicación que permite ver en un árbol de llamadas los objetos que hacen commit, de forma de poder buscar problemas de integridad transaccional.&lt;br /&gt;
&lt;br /&gt;
Hay una descripción un poco más amplia &lt;a href="http://blog.marcoscrispino.com/2009/04/gxpublic-applets.html"&gt;en esta otra nota del blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
El proyecto está en Assembla, se puede obtener mediante SVN de &lt;a href="http://code.assembla.com/neptuno_net"&gt;http://code.assembla.com/neptuno_net&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Si alguien lo quiere probar, tiene que bajar el proyecto y hacer un Build. Yo lo tengo funcionando con Visual C# 2008 Express, con el .Net Framework 3.5.&lt;br /&gt;
&lt;br /&gt;
La idea es colaborar con otro proyecto en el marco de los Collaborative Proyects 2.0, planteado por Edgar Jimenez Demestri y titulado "Analizador de UTLs". Espero que Neptuno.net sirva como punto de partida.&lt;br /&gt;
&lt;br /&gt;
Quienes bajen el proyecto, tengan en cuenta que era un desarrollo interno, por lo que no se caracteriza por la prolijidad...&lt;br /&gt;
&lt;br /&gt;
Si alguien le quiere hacer alguna mejora, será bienvenida. Por el momento el único que puede hacer commits en este proyecto soy yo, así que si alguien quiere colaborar me debería mandar el código modificado para que yo lo suba.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Actualización&lt;/b&gt;:&amp;nbsp; Me olvidé de decir que solo funciona con GeneXus9.0...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-440056060285622914?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/CIDZsauAb2E/neptunonet-open-source.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/10/neptunonet-open-source.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-7535406414358620759</guid><pubDate>Thu, 08 Oct 2009 13:15:00 +0000</pubDate><atom:updated>2009-10-08T11:15:53.954-02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">collaborative proyects</category><category domain="http://www.blogger.com/atom/ns#">desarrollo</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Automatic Pattern Generator, idea para los proyectos colaborativos</title><description>&lt;b&gt;Motivación&lt;/b&gt; &lt;br /&gt;
Una de las cosas que veo que pasa bastante seguido, es que hacemos cosas que resultan repetitivas, pero no lo suficiente como para desarrollar un pattern que las haga más automáticas.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, ahora estoy trabajando en una aplicación para transferir datos del sistema a la base de datos local de un PDA. Son varias cosas las que hay que transferir, y todos los programas son iguales:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;una pantalla de selcción con filtros, paginado y un link en la grilla para agregar el elemento a una tabla intermedia que luego va al PDA&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;un web panel para ver los datos agregados&lt;/li&gt;
&lt;li&gt;un web panel y un procedimiento para agregar los datos&lt;/li&gt;
&lt;li&gt;un web panel y un procedimiento para borrar algún dato que se agregó.&lt;/li&gt;
&lt;/ul&gt;Ahora lo estoy haciendo a mano, entro a cada uno de los 6 objetos de una de las "instancias", le doy Save as..., le pongo el nombre adecuado y le cambio las partes que son variables.&lt;br /&gt;
&lt;br /&gt;
Es claramente un pattern. Pero entonces, ¿por que no desarrollo uno que se que me va a hacer la vida más fácil? Porque desarrollar un pattern nuevo es muy complicado. Porque el tiempo que me llevaría no justifica la inversión, porque haciéndolo a mano lo hago mucho más rápido para las 4 o 5 instancias que necesito ahora.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;La idea&lt;/b&gt;&lt;br /&gt;
La idea sería entonces hacer una herramienta que tome varias instancias de un pattern (que todavía no existe, en realidad sería de un proyecto de pattern), saque factor común, y genere los XMLs, DKTs y demás cosas que se precisan para crear el pattern.&lt;br /&gt;
&lt;br /&gt;
En el ejemplo anterior, tomaría las 2 o3 "instancias" que ya tengo hechas, cada una compuesta por 6 objetos, le diría a la herramienta como son las correspondencias (que objeto de cada instancia corresponde a que objeto de la otra, se podría hacer con expresiones regulares), y el programa dejaría fijas las cosas que son comunes y pondría como variables las cosas que están distintas.&lt;br /&gt;
&lt;br /&gt;
No es trivial, pero pienso que se puede lograr algo bastante interesante.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;El proyecto colaborativo&lt;/b&gt;&lt;br /&gt;
Como &lt;a href="http://blog.marcoscrispino.com/2009/09/collaborative-projects-20.html"&gt;comentaba en otra nota&lt;/a&gt;, no tengo tiempo para liderar un proyecto, así que no lo voy a hacer. Si a alguien le interesa presentarlo, me anoto para definir el alcance, la arquitectura y colaborar en el desarrollo.&lt;br /&gt;
&lt;br /&gt;
Entonces, lo que se necesitaría es:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Alguien que lidere el proyecto, debería definir el alcance (junto conmigo), las tareas a realizar y coordinar el equipo de desarrollo.&lt;/li&gt;
&lt;li&gt;Uno o más desarrolladores, porque si bien yo podría participar, no voy a poder hacer todo el desarrollo.&lt;/li&gt;
&lt;li&gt;Uno o más beta testers.&lt;/li&gt;
&lt;/ul&gt;Si a alguien le interesa, le ve potencial, le parece que es factible, y quiere participar, que me avise. Así vemos si el proyecto es viable o no.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-7535406414358620759?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/M0XpF3lnn6M/automatic-pattern-generator-idea-para.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/10/automatic-pattern-generator-idea-para.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-5026102887011773525</guid><pubDate>Mon, 05 Oct 2009 12:46:00 +0000</pubDate><atom:updated>2009-10-05T10:46:47.628-02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">útiles</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Tema por defecto en un modelo GeneXus 9.0</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_gG6tlx1eBKw/SsnqOhZPQzI/AAAAAAAABAU/oIa8vXQ741U/s1600-h/GX9Logo.jpeg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_gG6tlx1eBKw/SsnqOhZPQzI/AAAAAAAABAU/oIa8vXQ741U/s320/GX9Logo.jpeg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;En un modelo de una KB GeneXus 9.0 (upgrade 4) quería cambiar el tema por defecto... Esto que parece trivial fue más complicado de lo que pensaba.&lt;br /&gt;
&lt;br /&gt;
Lo primero que hice fue ir a las propiedades del modelo, pero ahí no hay nada.&lt;br /&gt;
&lt;br /&gt;
En el modelo de diseño hay una propiedad con el tema, pero lo cambié y no me cambió el tema por defecto en el modelo de prototipo.&lt;br /&gt;
&lt;br /&gt;
Después de darle varias vueltas sin encontrar nada, busqué con el &lt;a href="http://blog.marcoscrispino.com/2007/12/kbquery-ejecucin-de-consultas-sql-en.html"&gt;KBQuery&lt;/a&gt; en las propiedades del modelo, y encontré que ahí sí aparecía...&lt;br /&gt;
&lt;br /&gt;
Al final, encontré que la propiedad está en el archivo model.ini.&lt;br /&gt;
&lt;br /&gt;
Debería ser más fácil de cambiar, tendría que estar en las propiedades del modelo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-5026102887011773525?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/1Q2x7gR0JW8/tema-por-defecto-en-un-modelo-genexus.html</link><author>noreply@blogger.com (Marcos Crispino)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_gG6tlx1eBKw/SsnqOhZPQzI/AAAAAAAABAU/oIa8vXQ741U/s72-c/GX9Logo.jpeg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/10/tema-por-defecto-en-un-modelo-genexus.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-746822361288714698</guid><pubDate>Tue, 29 Sep 2009 16:18:00 +0000</pubDate><atom:updated>2009-10-08T11:17:10.525-02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">collaborative proyects</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Collaborative Projects 2.0</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_gG6tlx1eBKw/SsIzSt7Ec9I/AAAAAAAAA-U/qyPqiZohjYU/s1600-h/CP20.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_gG6tlx1eBKw/SsIzSt7Ec9I/AAAAAAAAA-U/qyPqiZohjYU/s320/CP20.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;En el último encuentro GeneXus, se hizo el lanzamiento de los Collaborative Proyects 2.0.&lt;br /&gt;
&lt;br /&gt;
La página en el Wiki de la comunidad es &lt;a href="http://www.gxtechnical.com/cp"&gt;www.gxtechnical.com/cp&lt;/a&gt;, además en las últimas noticias GeneXus &lt;a href="http://www2.gxtechnical.com/portal/hgxpp001.aspx?15,7,3,O,S,0,PAG;CONC;123;11;D;23856;1;PAG;,"&gt;hay una entrevista&lt;/a&gt; a &lt;a href="http://arminbachmann.blogspot.com/"&gt;Armin&lt;/a&gt; que explica en que consiste, y por último también está la charla que se dio durante el encuentro.&lt;br /&gt;
&lt;br /&gt;
Estaría bueno participar, pero lamentablemente no tengo mucho tiempo, así que descarto liderar un proyecto. Veré en cual de las propuestas me anoto. Por ahora hay unos pocos proyectos, esperemos que en breve hayan varios más para poder elegir.&lt;br /&gt;
&lt;br /&gt;
Me gustaría participar en alguno que se dedique a extender de alguna forma GeneXus Server, para probar esta nueva tecnología...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-746822361288714698?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/Ihs0yefKP4c/collaborative-projects-20.html</link><author>noreply@blogger.com (Marcos Crispino)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_gG6tlx1eBKw/SsIzSt7Ec9I/AAAAAAAAA-U/qyPqiZohjYU/s72-c/CP20.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/09/collaborative-projects-20.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-2715094995868412212</guid><pubDate>Sun, 20 Sep 2009 00:12:00 +0000</pubDate><atom:updated>2009-09-19T21:13:40.126-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">tecnología</category><category domain="http://www.blogger.com/atom/ns#">iphone</category><title>Comprar un iPhone en Uruguay, ¿puede ser tan complicado?</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://images.apple.com/iphone/gallery/images/photos-hardware-05-20090608.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="118" src="http://images.apple.com/iphone/gallery/images/photos-hardware-05-20090608.jpg" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;En Uruguay, en general, estamos bastante atrasados respecto al mundo civilizado en lo que tiene que ver con la tecnología. Las cosas siempre llegan tarde y son mucho más caras.&lt;br /&gt;
&lt;br /&gt;
Con el iPhone, pasa exáctamente lo mismo...&lt;br /&gt;
&lt;br /&gt;
Acá el iPhone lo traen dos compañías: Claro y Movistar.&lt;br /&gt;
&lt;br /&gt;
Lo de Claro es una vergüenza... El plan de $1.000 por mes (unos 45 dólares americanos), tiene 200MB de navegación por mes. ¿Quién compra un iPhone para usarlo solo como teléfono? ¿A quién le alcanzan 200MB si lo va a usar para conectarse a internet?&lt;br /&gt;
&lt;br /&gt;
El plan de Movistar está un poco mejor. El de $760 por mes (unos 35 dólares americanos), tiene 500MB de navegación. No es una maravilla, pero supongo que para usarlo desde el teléfono debería alcanzar. Si alguien lo quiere para usarlo de modem y conectarse desde el PC, seguramente se quede corto.&lt;br /&gt;
&lt;br /&gt;
Entonces me decidí, y lo fuí a comprar... Pregunté en dos tiendas de Movistar hace unos 20 días, en ninguna de las dos sabían nada, no tenían ni el precio de los planes. En ese momento pregunté también por teléfono a Movistar, y me dijeron que tenía que preguntar directamente en las tiendas.&lt;br /&gt;
&lt;br /&gt;
Ahora esta semana volví a preguntar, ahora en la casa central de 18 y Andes, y dice que ya está agotado.&lt;br /&gt;
&lt;br /&gt;
Mi duda es si efectivamente lo quieren vender...&lt;br /&gt;
&lt;br /&gt;
La otra alternativa es comprarlo sin contrato, desbloquearlo y usarlo con Ancel, pero el precio del aparato se va a más de 1.000 dólares comprándolo acá. Se de gente que lo ha traído de Estados Unidos por menos de 400...&lt;br /&gt;
&lt;br /&gt;
¿Puede ser tan complicado conseguirlo?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-2715094995868412212?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/AN70nhUR7JU/comprar-un-iphone-en-uruguay-puede-ser.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">11</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/09/comprar-un-iphone-en-uruguay-puede-ser.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-5288978619898074752</guid><pubDate>Wed, 16 Sep 2009 17:41:00 +0000</pubDate><atom:updated>2009-09-16T14:43:34.431-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">genexus</category><category domain="http://www.blogger.com/atom/ns#">eventos</category><title>XIX Encuentro Internacional GeneXus, mañana del día 3</title><description>&lt;b&gt;¿Qué podríamos ver en GeneXus?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Se hablaron de varios temas que están investigando en Artech para incorporar a GeneXus, entre ellos:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Aplicaciones Multy-tenant, sería solo cambiar una propiedad en el modelo y GeneXus se encargaría de agregar el TenentId en todas las tablas que lo necesiten, y filtro en todos los programas que lo requieran.&lt;/li&gt;
&lt;li&gt;Herencia, ahora ya se puede resolver con subtipos, pero están pensando en algo más declarativo.&lt;/li&gt;
&lt;li&gt;Dominios extendidos, que pueda tomar los valores "estáticos" del dominio enumerado pero además pueda tomar valores dinámicos de una tabla.&lt;/li&gt;
&lt;li&gt;Implicit data selectors, es algo que habían hablado de agregarlo a la X pero al final no entró, permite definir un data selector que se usa siempre que se recorre la tabla correspondiente, a menos que explicitamente se diga que no se quiere usar, por ejemplo, para recorrer siempre los clientes activos.&lt;/li&gt;
&lt;li&gt;Transaction inicialization, permitiría cargar los datos de una transacción mediante un mapeo definido a priori, por ejemplo para inicializar la factura a partir de la orden de compra.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Evolución del lengiuaje GeneXus&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Se presentaron también algunas líneas que están trabajando, para tener más semántica en la KB y lograr lenguajes más declarativos:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Dominios: los dominios van a poder tener una UI, una especificación de lo que se debe hacer en la reorganización y comportamiento. Por ejemplo, el dominio TimePeriod, se representaría gráficamente como dos campos date, en la reorganización debería crear dos campos (inicio y fin del período) en vez de uno, y podría tener una función que diga si una fecha está comprendida en el período.&lt;/li&gt;
&lt;li&gt;Módulos: los objetos van a pertenecer a un módulo como&amp;nbsp;públicos&amp;nbsp;o privados (mencionaron una tercer opción pero no dijeron cual... ¿internal?), de un módulo a otro solo se van a poder usar los objetos públicos, y se van a poder importar bases de conocimiento como si fueran módulos.&lt;/li&gt;
&lt;li&gt;User interface, hacerla más declarativa, por ejemplo diciendo que tipo de pantalla es (trabajar con, master-detail, etc.)&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Además Gastón mostró una foto de este blog, de la nota que hablaba del &lt;a href="http://blog.marcoscrispino.com/2009/08/pasaje-de-parametros-entre-objetos.html"&gt;pasaje de parámetros en GeneXus&lt;/a&gt;. :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Futuro de las aplicaciones RIA con GeneXus&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Se habló de AJAX y como GeneXus genera código utilizando esta tecnología, y se comentó que de momento no tienen pensado trabajar en generadores Silverlight o Flex, ya que con AJAX se tienen las mismas características.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Además se contó como implementaron el generador Ruby, que hicieron un generador de HTML separado del generador del lenguaje, lo que les permitiría generar código para otras plataformas como ser iPhone o Android. Están investigando fuertemente este tema y posiblemente haya algún generador&amp;nbsp;móvil&amp;nbsp;en el futuro.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;REST web services&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;La primer parte de la charla fue una explicación de que es REST, que fue un poco pesada.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Después se comentó como piensan generar web services REST en GeneXus, que básicamente consiste en exponer business components y data providers como web services REST.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;En principio no me queda demasiado clara la necesidad, se podría usar para exponer datos para usar en algún mashup. En todo caso si alguien lo necesita aparentemente va a ser muy simple de usar.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-5288978619898074752?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/Rx9DiJ3KOHc/xix-encuentro-internacional-genexus_16.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/09/xix-encuentro-internacional-genexus_16.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-4577504457281187013</guid><pubDate>Wed, 16 Sep 2009 00:43:00 +0000</pubDate><atom:updated>2009-09-15T21:43:18.620-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">genexus</category><category domain="http://www.blogger.com/atom/ns#">eventos</category><title>XIX Encuentro Internacional GeneXus, días 1 y 2</title><description>Y se vino el encuentro GeneXus...&lt;br /&gt;
&lt;br /&gt;
Estoy tratando de hacer un seguimiento más o menos en vivo en &lt;a href="http://twitter.com/mcrispino"&gt;twitter&lt;/a&gt;, pero no da para escribir mucho, así que acá van los comentarios de las charlas que he ido.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Estado del arte de MDD (Model Driven Development)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
No me convenció demasiado la charla, esperaba algo más concreto, me resultó demasiado teórica y poco aplicable.&lt;br /&gt;
&lt;br /&gt;
En realidad como GeneXus ya aplica varios de los conceptos de MDD, no parece algo que nos cambie demasiado el paradigma de desarrollo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;GeneXus en el desarrollo, GXTest en el testing&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Fue una charla donde se explicaron algunos conceptos y se hizo una demo de GXTest.&lt;br /&gt;
&lt;br /&gt;
La herramienta en general es muy buena, tuve la oportunidad de hacer algo de beta test de la misma, y es altamente recomendable.&lt;br /&gt;
&lt;br /&gt;
La sala estaba llena con gente parada en el fondo, lo que demuestra que el testing en general y GXTest en particular han logrado llamar la atención.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Compartiendo fuentes de datos: Data Providers&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Se mostraron algunos casos de uso para los Data Providers y como pretenden sustituir a los Procedures en las áreas donde son utilizables.&lt;br /&gt;
&lt;br /&gt;
Lo más interesante es que en la Evolution 1 agregaron un Data Provider Generator que puede generar el Data Provider para inicializar datos de una o varias tablas, tomando los datos de &lt;a href="http://www.freebase.com/"&gt;Freebase.com&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Keynote de Nicolás Jodal&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
La charla "deportiva" de Jodal estuvo buena, creo que vale la pena verla.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Extendiendo GeneXus con Programación Orientada a Aspectos (AOP)&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Se presentaron los conceptos de AOP. El tema es interesante, y la principal ventaja parece ser que permite separar distintos aspectos de la programación del código de la aplicación, como ser temas de seguridad, auditoria, etc.&lt;br /&gt;
&lt;br /&gt;
La solución mostrada parece ser un poco compleja para quienes programan en GeneXus, ya que los "aspectos" hay que programarlos (o declararlos) usando un lenguaje con una sintaxis propia&lt;br /&gt;
&lt;br /&gt;
Sería muy bueno poder definir estos aspectos desde GeneXus, eso le daría mucha potencia y sin duda lograría mucha más adopción.&lt;br /&gt;
&lt;br /&gt;
Además de mencionó el producto &lt;a href="http://certus.accendo-it.com/"&gt;Certus&lt;/a&gt;, que aplica estos conceptos.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creando User Controls con GWT y GeneXus X Ev1&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
El tema es interesante, pero la charla no me dejó mucho...&lt;br /&gt;
&lt;br /&gt;
Se presentaron algunos conceptos teóricos y después se mostró algo de código y un ejemplo de un User Control en GeneXus, pero me parece que le faltó un enfoque un poco más práctico.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;GeneXus X: ¡Rich Internet Applications Ya!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Estuvo interesante, se mostró una aplicación RIA hecha con GX: un lector de RSS.&lt;br /&gt;
&lt;br /&gt;
Además se presentaron varios conceptos de como encarar el desarrollo de aplicaciones RIA, que pueden resultar útiles.&lt;br /&gt;
&lt;br /&gt;
La conclusión es que con GeneXus se pueden hacer aplicaciones muy interactivas usando User Controls, como por ejemplo GeneXus Server.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Como lograr discusiones de calidad&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Creo que esta charla vale la pena verla. No tiene nada que ver con GeneXus pero las ideas comentadas fueron muy interesantes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Un motor de reglas de negocio dinámicas inserto en el ecosistema GeneXus&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
La gente de Artech está trabajando en dar la posibilidad de definir reglas dinámicas, que pueden ser modificadas sin cambiar los programas y son evaluadas en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
El lenguaje para definir las reglas aparentemente sería definible en la KB, con lo que el usuario final (el experto del dominio) usaría un lenguaje muy parecido al lenguaje natural.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Por lo que mostraron el tema está todavía muy verde, pero parece ir bien encaminado. Ya veremos a donde llega.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Tracing, profiling, debugging... recursos útiles para la salud de una aplicación&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Esperaba otra cosa, pensé que a lo mejor hacían algún anuncio, pero no, la charla fue un repaso de las distintas técnicas para analizar los distintos errores que se pueden presentar en la aplicación, con un enfoque sobre todo hacia .Net.&lt;br /&gt;
&lt;br /&gt;
Además de técnicas se mostraron algunas herramientas, unas integradas a GeneXus (como el trace o el debugger) y otras externas.&lt;br /&gt;
&lt;br /&gt;
Lo más interesante me resultó el profiler que tiene incorporado la versión Evolution 1, que permite medir los tiempos de ejecución de cada objeto GeneXus y dentro de cada objeto, los tiempos de cada sentencia.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Extender GeneXus programando en GeneXus&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Básicamente se presentó GX4GX, que es un conjunto de objetos externos que permiten acceder a la KB programando directamente en GeneXus. Es la tecnología con la que desarrollaron GeneXus Server.&lt;br /&gt;
&lt;br /&gt;
Además se mostró como será la forma de extender GeneXus Server.&lt;br /&gt;
&lt;br /&gt;
Muy interesante, habrá que probarlo...&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Collaborative proyects 2.0&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Se hizo el lanzamiento de la versión 2 de los collaborative projects.&lt;br /&gt;
&lt;br /&gt;
Además se presentaron algunas tecnologías que se pueden usar para trabajar en grupos dispersos geográficamente, con especial énfasis en Second Life. Se ve que todavía no entiendo muy bien cual es la ventaja de Second Life...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-4577504457281187013?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/1tjZVRdHCQQ/xix-encuentro-internacional-genexus.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/09/xix-encuentro-internacional-genexus.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-5848992900093495074</guid><pubDate>Thu, 27 Aug 2009 21:25:00 +0000</pubDate><atom:updated>2009-08-27T18:25:00.463-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">web 2.0</category><category domain="http://www.blogger.com/atom/ns#">música</category><category domain="http://www.blogger.com/atom/ns#">internet</category><title>Escuchar música en Internet</title><description>En Internet hay unos cuantos sitios que permiten escuchar música on-line. Últimamente he usado unos cuantos de estos servicios, así que dejo acá una reseña de cada uno.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pandora&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.pandora.com/images/logo_pandora.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.pandora.com/images/logo_pandora.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://www.pandora.com/"&gt;Pandora&lt;/a&gt; fue el primer servicio que usé, pero lamentablemente ahora no está disponible en Uruguay, así que hace tiempo que no lo uso.&lt;br /&gt;
&lt;br /&gt;
Uno podía elegir una canción o un artista, y reproducía música similar a la seleccionada. La coincidencia en su momento era muy buena, capaz que ahora lo comparo con los demás y no me parece nada espectacular.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;FineTune&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://cdn.finetune.com/images/nav/logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://cdn.finetune.com/images/nav/logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://www.finetune.com/"&gt;FineTune&lt;/a&gt; es un sitio que permite crear listas de reproducción eligiendo para cada una las canciones que quiero. Tiene dos restricciones: 1) las listas deben tener al menos 45 canciones, y 2) no pueden haber más de tres canciones de un determinado artista en la lista.&lt;br /&gt;
&lt;br /&gt;
Este servicio todavía lo sigo usando, tiene la ventaja que hay una aplicación de escritorio, con lo que no es necesario tener el navegador abierto en este sitio.&lt;br /&gt;
&lt;br /&gt;
Tiene una especie de recomendación, aunque siempre me pareció bastante malo, por la música que selecciona. La forma de obtener recomendaciones es crear una lista de menos de 45 temas, y pedirle que los complete.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Deezer&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_gG6tlx1eBKw/SpaAoeigeLI/AAAAAAAAA6s/GmBuwu2biHg/s1600-h/DeezerLogo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_gG6tlx1eBKw/SpaAoeigeLI/AAAAAAAAA6s/GmBuwu2biHg/s320/DeezerLogo.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://www.deezer.com/"&gt;Deezer&lt;/a&gt; tiene la ventaja que con respecto a los dos anteriores, que se pueden elegir las canciones a escuchar sin ningún tipo de restricción, salvo la evidente de que la canción esté disponible.&lt;br /&gt;
&lt;br /&gt;
Lo usé bastante poco porque me pasó varias veces seguidas que no encontré lo que estaba buscando, así que lo dejé de usar.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Last.fm &lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://cdn.last.fm/flatness/logo.6.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://cdn.last.fm/flatness/logo.6.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://last.fm/"&gt;Last.fm&lt;/a&gt; es un buen servicio enfocado más que nada a la parte social de escuchar música. Lo usé un tiempo, pero tenía algunas restricciones en la versión grátis, y como en realidad FineTune era una buena alternativa, no lo seguí usando.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;YouTube&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_gG6tlx1eBKw/SpZ_oKdEFwI/AAAAAAAAA6k/2yHTBqD7E5I/s1600-h/YouToubeLogo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_gG6tlx1eBKw/SpZ_oKdEFwI/AAAAAAAAA6k/2yHTBqD7E5I/s320/YouToubeLogo.png" /&gt;&lt;/a&gt;&lt;/div&gt;Técnicamente &lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt; no es para escuchar música, pero la realidad es que tiene mucha variedad, aunque para algunas cosas tiene restricciones de acceso.&lt;br /&gt;
&lt;br /&gt;
En realidad la mayor contra que tiene es que consume más ancho de banda que los demás servicios porque también muestra el video, pero puede ser una buena opción si se busca una canción determinada.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Grooveshark&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_gG6tlx1eBKw/SpaCOMkBGRI/AAAAAAAAA60/5FWxYiziGfI/s1600-h/GroovesharkLogo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_gG6tlx1eBKw/SpaCOMkBGRI/AAAAAAAAA60/5FWxYiziGfI/s320/GroovesharkLogo.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://listen.grooveshark.com/"&gt;Grooveshark&lt;/a&gt; hace poco que lo estoy usando, unas dos semanas, pero es el mejor servicio que he encontrado hasta ahora.&lt;br /&gt;
&lt;br /&gt;
Permite escuchar la música que quiera, en el orden que quiera, sin ningún tipo de restricción.&lt;br /&gt;
&lt;br /&gt;
Además tiene una funcionalidad de recomendación de música que es muy buena, al menos en los casos que he probado.&lt;br /&gt;
&lt;br /&gt;
No se cual es el negocio ni cuanto va a durar, pero por ahora, funciona muy bien.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conclusión&lt;/b&gt;&lt;br /&gt;
Sin duda que hay muchas opciones para quienes quieren escuchar música en Internet, y seguramente van a haber muchas más y cada vez con menos restricciones.&lt;br /&gt;
&lt;br /&gt;
Cada uno de los servicios mensionados tiene sus particularidades, algunos tienen cosas mejores que otros, pero todos son buenas opciones.&lt;br /&gt;
&lt;br /&gt;
¿Alguien escucha música en Internet? ¿Qué servicio usan?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-5848992900093495074?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/l-6VZSyHt4M/escuchar-musica-en-internet.html</link><author>noreply@blogger.com (Marcos Crispino)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_gG6tlx1eBKw/SpaAoeigeLI/AAAAAAAAA6s/GmBuwu2biHg/s72-c/DeezerLogo.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/08/escuchar-musica-en-internet.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-1683052012339236943</guid><pubDate>Wed, 05 Aug 2009 11:56:00 +0000</pubDate><atom:updated>2009-08-05T08:56:46.867-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sugerencias</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Pasaje de parámetros entre objetos GeneXus</title><description>Acá dejo dos sugerencias con respecto al pasaje de parámetros entre objetos GeneXus:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;parámetros opcionales&lt;/li&gt;
&lt;li&gt;parámetros nominados&lt;/li&gt;
&lt;/ul&gt;&lt;b&gt;Parámetros opcionales&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Muchas veces pasa que se agregan parámetros a un objeto GeneXus, porque se precisa pasarlos desde uno de los llamadores, pero no queremos que el resto de los programas llamadores cambien.&lt;br /&gt;
&lt;br /&gt;
Lo que hacemos hoy es modificar todos los llamadores, agregando un nuevo parámetro con un valor que sería el valor por defecto.&lt;br /&gt;
&lt;br /&gt;
Sería bueno tener la posibilidad de definir que un parámetro es opcional e indicarle cual es el valor por defecto. La definicón podría ser algo así:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; parm(in:&amp;amp;par1, in:&amp;amp;par2=0, out:&amp;amp;result);&lt;/tt&gt;&lt;/blockquote&gt;En este ejemplo el parámetro &amp;amp;par2 sería opcional, y si no se especifica el valor que se usaría en el objeto sería cero, que es el valor que se le da por defecto.&lt;br /&gt;
&lt;br /&gt;
La invocación podría ser así, si se quiere usar el valor por defecto:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; &amp;amp;result = Programa.udp(1)&lt;/tt&gt;&lt;/blockquote&gt;o así, si se quiere especificar otro valor:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; &amp;amp;result = Programa.udp(1, 2)&lt;/tt&gt;&lt;/blockquote&gt;&lt;b&gt;Parámetros nominados&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Otra característica que tienen los parámetros en los objetos GeneXus&amp;nbsp; es que son posicionales.&lt;br /&gt;
&lt;br /&gt;
Como está hoy no hay problema, pero si se permitiera tener parámetros opcionales, se podría plantear el problema que quiero pasarle solo uno de los N parámetros opcionales, lo que no se podría hacer a menos que justo le quiera pasar el primero de la lista.&lt;br /&gt;
&lt;br /&gt;
Algo así:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; parm(in:&amp;amp;par1=0, in:&amp;amp;par2=0, in:&amp;amp;par3=0);&lt;/tt&gt;&lt;/blockquote&gt;¿Cómo hago para pasarle un valor distinto de cero solo a la variable &amp;amp;par2?&lt;br /&gt;
&lt;br /&gt;
La solución podría ser indicarle el nombre del parámetro en la invocación. La sintaxis puede variar...&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; Programa.call(@&amp;amp;par2=1)&lt;/tt&gt;&lt;/blockquote&gt;La @ es para indicarle que es el nombre del parámetro y no una variable en el contexto del programa llamador...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-1683052012339236943?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/3qtojHrVeOo/pasaje-de-parametros-entre-objetos.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/08/pasaje-de-parametros-entre-objetos.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-6545921813835113569</guid><pubDate>Thu, 23 Jul 2009 22:01:00 +0000</pubDate><atom:updated>2009-07-23T19:01:01.823-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sugerencias</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Mensajes y formato de strings</title><description>Ahora que &lt;a href="http://blog.marcoscrispino.com/2009/06/formato-de-strings-funcion-format-vs.html"&gt;descubrí la función Format()&lt;/a&gt; en GeneXus y que la empecé a usar... creo que se le podría hacer una mejora.&lt;br /&gt;
&lt;br /&gt;
La mayoría de las veces, cuando armamos un string, lo queremos para mostrar un mensaje. Muchas veces es para pasárselo a la función msg() o a la función error().&lt;br /&gt;
&lt;br /&gt;
Algo así:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; &amp;amp;mensaje = Format('El pedido número %1 fue confirmado', PedidoId.ToString())&lt;br /&gt;
msg(&amp;amp;mensaje)&lt;/tt&gt;&lt;/blockquote&gt;o simplemente&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; msg( Format('El pedido número %1 fue confirmado', PedidoId.ToString()) )&lt;/tt&gt;&lt;/blockquote&gt;Sería más práctico e intuitivo, que las funciones msg() y error() recibieran una cantidad variable de parámetros y se comportaran como la función Format().&lt;br /&gt;
&lt;br /&gt;
El código quedaría entonces más simple:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; msg( 'El pedido número %1 fue confirmado', PedidoId.ToString() )&lt;/tt&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-6545921813835113569?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/MZsZfFSqJVQ/mensajes-y-formato-de-strings.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/07/mensajes-y-formato-de-strings.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-8162495184527187708</guid><pubDate>Mon, 13 Jul 2009 23:40:00 +0000</pubDate><atom:updated>2009-07-13T20:46:41.158-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">desarrollo</category><category domain="http://www.blogger.com/atom/ns#">c#</category><title>Mejoras al lenguaje en C# 3.0 y 4.0</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_gG6tlx1eBKw/SlOTZyYM6eI/AAAAAAAAA4A/3ad8qcSlvQc/s1600/LogoAspNet.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_gG6tlx1eBKw/SlOTZyYM6eI/AAAAAAAAA4A/3ad8qcSlvQc/s200/LogoAspNet.png" /&gt;&lt;/a&gt;&lt;/div&gt;Antes de empezar, conviene aclarar que no me considero un experto en C# ni mucho menos, pero sí tengo algo de experiencia con el lenguaje. De hecho podría decir que C# es mi segundo lenguaje después de GeneXus...&lt;br /&gt;
&lt;br /&gt;
El uso que le he dado principalmente ha sido para desarrollar extensiones de GeneXus o aplicaciones que usan GXPublic. Alguna vez hice algo en ASP.Net pero nada demasiado sofisticado.&lt;br /&gt;
&lt;br /&gt;
El tema es que para el uso que le doy habitualmente, me alcanza con la funcionalidad que tiene Visual Studio 2005, que funciona con C# 2.0, y por lo tanto me he estado perdiendo de las nuevas funcionalidades en C# 3.0 (VS2008) y 4.0 (VS2010, todavía en beta).&lt;br /&gt;
&lt;br /&gt;
Son varias las cosas nuevas en C# 3.0 (LINQ, object initializers, anonymous types, etc.), &lt;a href="http://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29"&gt;el artículo de Wikipedia sobre C#&lt;/a&gt; explica bastante bien que es cada una de estas cosas.&lt;br /&gt;
&lt;br /&gt;
Hay otras dos funcionalidades nuevas que me gustaron mucho cuando las leí &lt;a href="http://blogs.msdn.com/jomo_fisher/archive/2005/09/13/464884.aspx"&gt;en este artículo&lt;/a&gt; de Jomo Fisher (del año 2005, estoy un tanto atrasado): lambda expresions y extension methods. Vale la pena leerlo.&lt;br /&gt;
&lt;br /&gt;
Lo de las expresiones lambda (si reconocen el nombre es porque lo vieron en algún curso de programación funcional) viene como a confirmar lo que decía &lt;a href="http://www.paulgraham.com/index.html"&gt;Paul Graham&lt;/a&gt; en &lt;a href="http://www.amazon.com/gp/product/0596006624"&gt;Hackers and Painters&lt;/a&gt;: que los lenguajes de programación tienden a ir incorporando funcionalidades de LISP...&lt;br /&gt;
&lt;br /&gt;
La otra reflexión es que parece que ahora en C# se podría implementar el algoritmo &lt;a href="http://labs.google.com/papers/mapreduce.html"&gt;MapReduce de Google&lt;/a&gt;, como &lt;a href="http://www.joelonsoftware.com/items/2006/08/01.html"&gt;lo explica Joel Spolsky en su blog&lt;/a&gt;. También vale la pena leerlo.&lt;br /&gt;
&lt;br /&gt;
En C# 4.0 que por lo que se todavía está en beta, agregan soporte para tipos de datos dinámicos, para poder utilizar código generado a partir de lenguajes con tipado dinámico (como ser F# o IronPython). Básicamente el tipo dynamic lo que hace es posponer la resolución de tipos al momento de ejecución.&lt;br /&gt;
&lt;br /&gt;
Otra cosa que está buena son los parámetros opcionales y parámetros por nombre (named parameters, cada uno lo traduce lo mejor que puede...), que permite asignar valores por defecto a algunos de los parámetros que luego no son necesarios en la invocación, y permite pasar los parámetros en cualquier orden siempre que se indique cual es cual por su nombre.&lt;br /&gt;
&lt;br /&gt;
En fin... mucha cosa interesante, hay que tratar de mantenerse actualizado.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-8162495184527187708?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/hSsEx_DjRd4/mejoras-al-lenguaje-en-c-30-y-40.html</link><author>noreply@blogger.com (Marcos Crispino)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_gG6tlx1eBKw/SlOTZyYM6eI/AAAAAAAAA4A/3ad8qcSlvQc/s72-c/LogoAspNet.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/07/mejoras-al-lenguaje-en-c-30-y-40.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-2185957315158435828</guid><pubDate>Tue, 07 Jul 2009 18:27:00 +0000</pubDate><atom:updated>2009-07-13T20:40:47.700-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">desarrollo</category><category domain="http://www.blogger.com/atom/ns#">asp.net</category><category domain="http://www.blogger.com/atom/ns#">c#</category><title>Global.asax</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_gG6tlx1eBKw/SlOTZyYM6eI/AAAAAAAAA4A/3ad8qcSlvQc/s1600-h/LogoAspNet.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_gG6tlx1eBKw/SlOTZyYM6eI/AAAAAAAAA4A/3ad8qcSlvQc/s200/LogoAspNet.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;El problema&lt;/b&gt;&lt;br /&gt;
Estamos migrando un sitio que estaba generado en .Net en un Windows Server, a uno nuevo generado en Java en un Linux.&lt;br /&gt;
&lt;br /&gt;
El tema es que con el cambio, las URLs cambian, pasan de ser de tipo&lt;br /&gt;
&lt;blockquote&gt;http://host/sitio/pagina.aspx?parametros&lt;/blockquote&gt;a ser de tipo&lt;br /&gt;
&lt;blockquote&gt;http://host:puerto/sitio/servlet/pagina?parametros&lt;/blockquote&gt;&amp;nbsp;Entonces, como hacer la migración de forma razonable, sin que haya problemas con los links que llegan al sitio.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Posibles soluciones&lt;/b&gt;&lt;br /&gt;
Habían varias posibles soluciones:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;sacar el sitio viejo y en su lugar poner una página de error 404 (not found) con un link al sitio nuevo&lt;/li&gt;
&lt;li&gt;poner que el IIS haga un redirect al sitio nuevo, pero ahí no se si funciona cuando se accede a una URL que no es la página por defecto&lt;/li&gt;
&lt;/ul&gt;&lt;b&gt;La solución final&lt;/b&gt;&lt;br /&gt;
En APS.NET existe un archivo de nombre Global.asax, que define algunos métodos que se ejecutan en distintos momentos, como por ejemplo cuando se levanta el sitio, cuando llega un request de una página, cuando se termina de procesar un request, etc.&lt;br /&gt;
&lt;br /&gt;
En particular el evento que me interesa en este caso es el que se dispara cuando se hace un request a una página, ya que ahí puedo hacer el redireccionamiento con inteligencia, mandando al usuario a la página que quería ir con los parámetros que le pasó, pero en el otro sitio.&lt;br /&gt;
&lt;br /&gt;
El archivo Global.asax quedó algo así (*):&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; &amp;lt;%@ language="C#" %&amp;gt;&lt;br /&gt;
&amp;lt;script runat="server"&amp;gt;&lt;br /&gt;
void Application_BeginRequest(Object sender, EventArgs e)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string request = Request.Url.PathAndQuery;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int pos = request.LastIndexOf('/');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; request = request.Substring(pos+1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; request = request.Replace(".aspx", "");&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string url = @"http://host:8080/sitio/servlet/" + request;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.Redirect(url);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;
(*) En realidad es un poco más complicada la solución final ya que el host es distinto según se esté dentro de la intranet o fuera, pero eso no viene al caso...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-2185957315158435828?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/-RfUrOZi3zY/globalasax.html</link><author>noreply@blogger.com (Marcos Crispino)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_gG6tlx1eBKw/SlOTZyYM6eI/AAAAAAAAA4A/3ad8qcSlvQc/s72-c/LogoAspNet.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/07/globalasax.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-2426952729250957627</guid><pubDate>Tue, 30 Jun 2009 18:31:00 +0000</pubDate><atom:updated>2009-06-30T15:31:48.257-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sugerencias</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Valor "Empty" para atributos con dominio en GeneXus</title><description>Supongamos que tengo un dominio ESTADO, definido como Char(3), que puede tener valores {'ING', 'ABI', 'CER'} (ingresado, abierto, cerrado).&lt;br /&gt;
&lt;br /&gt;
Si fuera una KB nueva posiblemente usaría un dominio enumerado con {ingresado=0, abierto=1, cerrado=2}. Pero no es el caso, y además no siempre es posible elegir los valores que va a tener un dominio, puede depender de otra aplicación o ser una base de datos que ya tiene valores.&lt;br /&gt;
&lt;br /&gt;
El problema que tengo, es que si defino una variable o un atributo basados en ese dominio, el valor "empty" (como en IsEmpty() o en SetEmpty()) es '', que no es un valor válido para el dominio.&lt;br /&gt;
&lt;br /&gt;
Estaría bueno poder definir cual es el valor "empty" de un dominio... Este valor además sería el "initial value" por defecto para los campos nuevos basados en dicho dominio, y sería el valor con el que se graban los registros nuevos cuando no se referencia el atributo (y se tiene la propiedad "initialize not referenced attributes" en "yes").&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-2426952729250957627?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/QGB-RnrSihA/valor-empty-para-atributos-con-dominio.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/06/valor-empty-para-atributos-con-dominio.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-7310313721246786919</guid><pubDate>Mon, 29 Jun 2009 21:13:00 +0000</pubDate><atom:updated>2009-06-29T18:13:15.684-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">uruguay</category><category domain="http://www.blogger.com/atom/ns#">reflexiones</category><title>Tecnología de votación</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://coloniatotal.com.uy/images/notas19/Urnas.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://coloniatotal.com.uy/images/notas19/Urnas.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;En el día de ayer, en Uruguay tuvimos elecciones internas, donde cada partido político decide cual será el candidato a presidente en las próximas elecciones de octubre, así como la representación de cada sector dentro de cada partido.&lt;br /&gt;
&lt;br /&gt;
En estas elecciones había 17 candidatos a la presidencia en 8 partidos, y se presentaron unas 2.500 listas. Listas de papel, de las cuales la mayoría terminan en la basura. De algunas dicen que se imprimieron 2 millones...&lt;br /&gt;
&lt;br /&gt;
La votación se hace por circuito electoral, según el número de credencial de la persona. Creo que habían unos 6.000 circuitos habilitados para estas elecciones. Cada circuito tiene tres personas que integran la mesa, más un policía de custodia.&lt;br /&gt;
&lt;br /&gt;
La votación se realiza entre las 8:00 y las 19:30, y una vez terminada se abre la urna, se cuentan los votos, y se llevan al lugar designado por la Corte Electoral (en Montevideo el Estadio Centenario).&lt;br /&gt;
&lt;br /&gt;
Esa es una explicación bastante resumida de como funcionan las elecciones, a lo que quiero llegar, es que me resulta demasiado complejo, demasiado burocrático. La maquinaria que es necesario movilizar para hacer una elección es demasiado pesada.&lt;br /&gt;
&lt;br /&gt;
Hoy en día, con la tecnología que tenemos, ¿no se podría hacer de forma mucho más simple? Capaz que lo que sigue puede resultar disparatado para algunos, pero yo no lo veo tan difícil de implementar.&lt;br /&gt;
&lt;br /&gt;
Una opción sería hacer la votación por SMS... Sí, por SMS. ¿Por qué no? Que cada uno registre un número de celular ante la Corte Electoral, y que vote desde ese número. Para que el voto sea secreto, al momento que llega el mensaje a la corte se debería separar la persona que lo envía (que tiene que quedar registro que votó para que no vote dos veces) del voto en sí. (*)&lt;br /&gt;
&lt;br /&gt;
Otra opción sería tener terminales de votación en lugares de fácil acceso. Se me ocurre farmacias, locales de cobranza (Abitab, Red Pagos, etc.) o cajeros automáticos, que seguro hay en todas las ciudades del país. Habría que complementarlo con mesas de votación en las zonas rurales. La votación no sería un domingo como es ahora, sino que podría ser un día entre semana (o varios días) en el horario que están abiertos habitualmente estos locales. La Corte Electoral tendría que cambiar todas las credenciales por algo que tuviera una banda magnética o un chip con la información del votante.&lt;br /&gt;
&lt;br /&gt;
Puede haber otras opciones...&lt;br /&gt;
&lt;br /&gt;
Me parece que cualquier cosa que agilice el proceso de votación sería bueno. Gracias a que se evitaría toda la complejidad de la infraestructura de votación, se podría hacer algo mucho más dinámico. Se podrían hacer consultas a la ciudadanía sobre ciertos temas, con bastante frecuencia sin que eso genere gastos adicionales. Pasaríamos a tener un modelo de democracia mucho más directa.&lt;br /&gt;
&lt;br /&gt;
(*) Calculo que no sería algo así como "voto pepe", "voto qki" o "voto pedro", sería algo más formal...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-7310313721246786919?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/0MUyCxexlPc/tecnologia-de-votacion.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">10</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/06/tecnologia-de-votacion.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-5673969900640637030</guid><pubDate>Thu, 25 Jun 2009 18:48:00 +0000</pubDate><atom:updated>2009-06-25T15:56:44.309-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sugerencias</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Objetos que devuelven más de un valor en GeneXus</title><description>En GeneXus no tenemos el concepto de función como tenemos en Java o en C#, donde tiene que haber un tipo de datos que es el que devuelve, como en:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt;private int foo() { return 1; }&lt;br /&gt;
&lt;/tt&gt;&lt;/blockquote&gt;Por el contrario, en GeneXus los parámetros de un objeto pueden ser de entrada, salida o entrada/salida, en cualquier cantidad y orden. (*)&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, podría tener una función que dado un producto me devuelve el saldo en cantidad y en importe, de dicho producto en el depósito. (**)&lt;br /&gt;
&lt;br /&gt;
La regla parm sería por ejemplo:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt;parm(in:ProductoId, out:&amp;amp;SaldoCantidad, out:&amp;amp;SaldoImporte);&lt;/tt&gt;&lt;/blockquote&gt;Pero entonces, ¿cómo invoco ese programa?. Hay varias opciones, puede ser con &lt;i&gt;call&lt;/i&gt;, o incluso con &lt;i&gt;udp&lt;/i&gt;...&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt;call(PGetSaldoProducto, ProductoId, &amp;amp;SaldoCantidad, &amp;amp;SaldoImporte)&lt;br /&gt;
o&lt;br /&gt;
&amp;amp;SaldoImporte = udp(PGetSaldoProducto, ProductoId, &amp;amp;SaldoCantidad)&lt;/tt&gt;&lt;/blockquote&gt;En una nota hace un tiempo, &lt;a href="http://blog.marcoscrispino.com/2009/02/mejorando-la-legibilidad-del-codigo.html"&gt;hablando sobre la legibilidad del código&lt;/a&gt;, comentaba sobre la ventaja de usar &lt;i&gt;udp&lt;/i&gt; en vez de &lt;i&gt;call&lt;/i&gt;... Pero en este caso las dos opciones son malas.&lt;br /&gt;
&lt;br /&gt;
Creo que sería bueno tener una sintaxis como tiene por ejemplo Python para asignar listas de valores... En Python una lista separada por comas es una tupla, que se puede devolver en una función o asignar. Por ejemplo:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt;# defino la funcion&lt;br /&gt;
def foo():&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; a = 1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; b = 2&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; c = 3&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return a,b,c&lt;br /&gt;
&lt;br /&gt;
# la invoco&lt;br /&gt;
d, e, f = foo()&amp;nbsp;&amp;nbsp; # resultado: d=1, e=2, f=3&lt;/tt&gt;&lt;/blockquote&gt;En GeneXus, si tuvieramos la posibilidad de usar esta notación, podríamos escribir:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; &amp;amp;SaldoImporte, &amp;amp;SaldoCantidad = udp(PGetSaldoProducto, ProductoId)&lt;/tt&gt;&lt;/blockquote&gt;lo que deja bien claro que la intención de la invocación es cargar el valor de las dos variables de la izquierda...&lt;br /&gt;
&lt;br /&gt;
---------------------------------------&lt;br /&gt;
(*) Si bien los parámetros pueden tener cualquier orden, creo que es altamente recomendable dejar los parámetros de salida al final.&lt;br /&gt;
&lt;br /&gt;
(**) Los motivos para tener una función que devuelve más de un valor pueden ser muchos y muy variados. En este caso también se podrían hacer dos funciones, con lógica muy parecida, pero que devolviera una la cantidad y otra el importe. La ventaja de tenerlo así es que se optimiza la performance, porque hay que hacer la recorrida en la base de datos una sola vez.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-5673969900640637030?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/4iUmLNePEWo/objetos-que-devuelven-mas-de-un-valor.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/06/objetos-que-devuelven-mas-de-un-valor.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-2093526746565470046</guid><pubDate>Tue, 23 Jun 2009 18:37:00 +0000</pubDate><atom:updated>2009-06-23T15:37:57.993-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">útiles</category><category domain="http://www.blogger.com/atom/ns#">reflexiones</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Formato de strings: función Format vs concatenación</title><description>Algo que hago con bastante frecuencia, es armar textos que se componen de una parte fija y otra que toma valores de variables o atributos. Por ejemplo, cuando se quiere mostrar un mensaje.&lt;br /&gt;
&lt;br /&gt;
En GeneXus hay por lo menos dos opciones para generar estos textos:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;usando la concatenación de strings con el operador +&lt;/li&gt;
&lt;li&gt;usando la &lt;a href="http://wiki.gxtechnical.com/commwiki/servlet/hwikibypageid?8406"&gt;función Format&lt;/a&gt;, que creo que se agregó en GeneXus 9.0&lt;/li&gt;
&lt;li&gt;hay una tercer forma que descarto de entrada, que es con la &lt;a href="http://wiki.gxtechnical.com/commwiki/servlet/hwikibypageid?8352"&gt;función Concat&lt;/a&gt;...&lt;/li&gt;
&lt;/ol&gt;Pero entonces, ¿cuál es la mejor opción?&lt;br /&gt;
&lt;br /&gt;
Con respecto a la legibilidad del código, creo que ambas opciones son buenas, puede haber algún caso que una de las dos quede mejor que la otra.&lt;br /&gt;
&lt;br /&gt;
La ventaja que tiene la función Format es cuando tenemos que traducir la aplicación usando el objeto Language, porque queda todo el texto en un solo item del objeto.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, el texto "El pedido número NNN fue confirmado", usando la concatenacion de strings queda&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt;&amp;amp;mensaje = 'El pedido número ' + PedidoId.ToString() + ' fue confirmado'&lt;/tt&gt;&lt;/blockquote&gt;con lo que al traducirlo tenemos que traducir los dos textos por separado:&amp;nbsp; 'El pedido número ' y ' fue confirmado'...&lt;br /&gt;
&lt;br /&gt;
Si usamos la función Format, nos queda&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt;&amp;amp;mensaje = Format('El pedido número %1 fue confirmado', PedidoId.ToString())&lt;/tt&gt;&lt;/blockquote&gt;con lo cual tenemos un solo literal.&lt;br /&gt;
&lt;br /&gt;
Puede haber algún caso donde tal vez no se pueda usar la función Format, por ejemplo en una regla error() en una transacción, pero en todos casos donde se pueda, creo que conviene usar la fución Format...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-2093526746565470046?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/oxLxG7PoYfM/formato-de-strings-funcion-format-vs.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/06/formato-de-strings-funcion-format-vs.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-7376087320638105034</guid><pubDate>Fri, 12 Jun 2009 14:20:00 +0000</pubDate><atom:updated>2009-06-12T11:20:56.907-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sugerencias</category><category domain="http://www.blogger.com/atom/ns#">reflexiones</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>When duplicate y campos con índice unique</title><description>Si en GeneXus (9.0) se tiene una tabla con un índice unique y se hace un &lt;i&gt;for each&lt;/i&gt; que actualiza el campo del índice, al especificar da un warning que dice:&lt;br /&gt;
&lt;blockquote&gt;spc0070: No When duplicate code found to handle possible duplicate condition when updating [Atributo]&lt;/blockquote&gt;La &lt;a href="http://wiki.gxtechnical.com/commwiki/servlet/hwikibypageid?6348"&gt;documentación del comando for each&lt;/a&gt; en el Wiki, dice lo siguiente con respecto al &lt;i&gt;when duplicate&lt;/i&gt;:&lt;br /&gt;
&lt;blockquote&gt;&lt;b&gt;When duplicate&lt;/b&gt;: This clause only makes sense in procedures (because it has to do with updates); it is analyzed below. This clause will be executed if, within the body of the For Each (code1), you try to update an attribute that is a candidate key (it has a unique index) and a record with that value already exists. GeneXus uses the unique index to ensure the uniqueness of that candidate key and in case it finds duplicates, if this clause is programmed in the For Each command, it will execute its code: code2. If the clause is not included, and you try to update an attribute that is a candidate key and a record with that value already exists, no code will be executed.&lt;/blockquote&gt;El problema con esto, es que en un mismo for each puedo estar actualizando más de un campo que tenga índice unique, con lo cual no se cual es el campo donde dio el error.&lt;br /&gt;
&lt;br /&gt;
El código para manejar este error, entonces debería primero hacer otro for each filtrando por cada uno de los campos con índice unique para ver cual es el que falló, y luego hacer nuevamente el update de todos los demás campos. La lógica puede quedar bastante complicada...&lt;br /&gt;
&lt;br /&gt;
Una alternativa a esto que se me ocurre, es que el &lt;i&gt;when duplicate&lt;/i&gt; pueda tener una lista de atributos que componen un índice unique, y que cuando se trata de grabar una tupla y da clave duplicada, vaya al &lt;i&gt;when duplicate&lt;/i&gt; que corresponda.&lt;br /&gt;
&lt;br /&gt;
Es más, GeneXus podría ser más inteligente, y que cada &lt;i&gt;when duplicate&lt;/i&gt; sea un manejador de errores, que se llame para cambiar los valores de los atributos involucrados en ese &lt;i&gt;when duplicate&lt;/i&gt; antes de hacer el update...&lt;br /&gt;
&lt;br /&gt;
Capaz que la idea no quedó muy clara, voy a poner un ejemplo...&lt;br /&gt;
&lt;br /&gt;
Tengo una tabla con campos:&lt;br /&gt;
(A* &lt;br /&gt;
&amp;nbsp;B&lt;br /&gt;
&amp;nbsp;C&lt;br /&gt;
&amp;nbsp;D)&lt;br /&gt;
que tiene índices unique por {B} y {C,D}.&lt;br /&gt;
&lt;br /&gt;
Podría tener el siguiente comando &lt;i&gt;for each&lt;/i&gt;:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; for each&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; where A = &amp;amp;A&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; B = &amp;amp;B&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; C = &amp;amp;C&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; D = &amp;amp;D&lt;br /&gt;
when duplicate B&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; B += 1&lt;br /&gt;
when duplicate C, D&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; C = &amp;amp;D&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; D = &amp;amp;C&lt;br /&gt;
endfor&lt;/tt&gt;&lt;/blockquote&gt;¿Qué haría este código? Intenta hacer el update con valores [&amp;amp;B, &amp;amp;C, &amp;amp;D]. Si no puede porque B está repetido, entonces va al &lt;i&gt;when duplicate B&lt;/i&gt;, calcula el nuevo valor de B, e intenta hacer el update con [&amp;amp;B+1, &amp;amp;C, &amp;amp;D]. Así hasta que no falle más por B... Si además falla porque los campos C, D están repetidos, entonces va al &lt;i&gt;when duplicate C, D&lt;/i&gt;, e intenta hacer el update con [&amp;amp;B, &amp;amp;D, &amp;amp;C].&lt;br /&gt;
&lt;br /&gt;
Hoy no hay una forma medianamente elegante de hacer esto. Porque en el &lt;i&gt;when duplicate&lt;/i&gt; primero tengo que identificar que campo fue el que dio el error, y después volver a hacer el nuevo update con los nuevos valores, por lo que quedaría una especie de actualización recursiva.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-7376087320638105034?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/QLppRbWQuis/when-duplicate-y-campos-con-indice.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/06/when-duplicate-y-campos-con-indice.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-2193511252662113738</guid><pubDate>Wed, 03 Jun 2009 17:53:00 +0000</pubDate><atom:updated>2009-06-03T14:53:40.299-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">desarrollo</category><category domain="http://www.blogger.com/atom/ns#">reflexiones</category><title>No hay peor comentario que el comentario que está equivocado</title><description>¿Qué tiene mal este código?&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; for each // Me fijo cantidad de la entrada&lt;br /&gt;
where MstId = &amp;amp;MstId2&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if MstTpo = 'R'&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;MstCntR = MstCnt&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;MstCntS = MstCnt&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; endif&lt;br /&gt;
endfor&lt;/tt&gt;&lt;/blockquote&gt;Para el que lo ve así, a simple vista, no tiene nada mal. Los que leyeron el título de la nota pueden tener alguna pista.&lt;br /&gt;
&lt;br /&gt;
¡Lo que está mal es el comentario! Porque &amp;amp;MstId2 no es una ENTRADA, es una SALIDA. Claro que el que no conoce el contexto no tiene forma de saberlo, y ahí está el peligro.&lt;br /&gt;
&lt;br /&gt;
Yo estoy a favor de poner comentarios que expliquen lo que hace el programa, pero los comentarios tienen que estar bien, si no, es peor tener comentarios que no tenerlos.&lt;br /&gt;
&lt;br /&gt;
Porque alguien podría leer el for each y quedarse con la idea que toma la cantidad de la entrada, cuando en realidad se queda con la de la salida.&lt;br /&gt;
&lt;br /&gt;
En conclusión, más vale no tener comentarios que tener comentarios equivocados...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-2193511252662113738?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/xXGSxHT_L-o/no-hay-peor-comentario-que-el.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/06/no-hay-peor-comentario-que-el.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-4708010403985473255</guid><pubDate>Tue, 02 Jun 2009 19:03:00 +0000</pubDate><atom:updated>2009-06-03T08:55:47.107-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">web 2.0</category><category domain="http://www.blogger.com/atom/ns#">desarrollo</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>GeneXus Server</title><description>Ayer &lt;a href="http://blog.genexus.com/guscarr"&gt;Gustavo Carriquiry&lt;/a&gt; publicó en su blog &lt;a href="http://blog.genexus.com/guscarr/?p=278"&gt;algunas fotos de pantalla del nuevo GeneXus Server&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Hoy ya está on-line para probarlo en &lt;a href="http://gxserver.genexusx.com/genexusserver"&gt;http://gxserver.genexusx.com/genexusserver&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
La verdad que está muy bueno. Se puede navegar por la KB (aunque por ahora no se puede editar) y ver los objetos y sus propiedades.&lt;br /&gt;
&lt;br /&gt;
No se si está basado en el &lt;a href="http://www.citrusproject.com/"&gt;Citrus Proyect&lt;/a&gt;, pero parecería como que sí.&lt;br /&gt;
&lt;br /&gt;
Es bueno ver como &lt;a href="http://blog.marcoscrispino.com/2006/09/genexus-en-la-onda-web-20.html"&gt;una idea que había propuesto en el 2006 en este blog&lt;/a&gt; parece ir tomando forma :)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Actualización (3/5/09 8:54)&lt;/b&gt;: Gastón Milano publicó &lt;a href="http://behindgenexus.blogspot.com/2009/06/you-can-do-it-using-genexus.html"&gt;una nota en su blog&lt;/a&gt; contando que la interfaz Web para GX Server la implementaron con GeneXus. ¡Espectacular!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-4708010403985473255?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/eNuqTs74W2I/genexus-server.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/06/genexus-server.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-100455522363185034</guid><pubDate>Fri, 22 May 2009 14:49:00 +0000</pubDate><atom:updated>2009-05-22T11:50:09.627-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">útiles</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Tiempos de compilación en Java y la versión del NMake</title><description>&lt;img align="left" border="0" height="120" src="http://1.bp.blogspot.com/_gG6tlx1eBKw/Sha53dlr_-I/AAAAAAAAA2o/Gs2y1xkLsqQ/s320/GXLogo.gif" style="display: inline;" width="120" /&gt;&lt;br /&gt;
En una KB estaba teniendo demoras en la compilación de varios minutos, lo cual no era para nada razonable.&lt;br /&gt;
&lt;br /&gt;
Es una KB con GeneXus 9.0 U4, generando Java, y compilando con jikes de IBM y el nmake de Microsoft.&lt;br /&gt;
&lt;br /&gt;
Analizando un poco, lo que encontré fue que cada vez que compilaba estaba copiando todas las clases al directorio del Tomcat. El .mak en cuestión hace referencia a más de 1.000 clases, con un tamaño de más de 500MB.&lt;br /&gt;
&lt;br /&gt;
En otro PC, compilar el mismo objeto en la misma KB, no demoraba nada... Así que comparando las versiones de los ejecutables en cuestión, encontré que el que estaba distinto era el nmake.exe&lt;br /&gt;
&lt;br /&gt;
La versión que yo tenía, era la 8.0.50727.762. La versión con la que funciona bien es la 7.10.3077.0...&lt;br /&gt;
&lt;br /&gt;
Así que ahora por suerte volví a tiempos razonables de unos pocos segundos en la compilación.&lt;br /&gt;
&lt;br /&gt;
Un tip: si alguien necesita ver que es lo que está haciendo la compilación, lo que hay que hacer es:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;en el archivo callmake.bat (en el directorio data002 o en el web según sea el caso), hay que comentar la primer línea que dice "@echo off"&lt;/li&gt;
&lt;li&gt;en el archivo .mak, cuando copia los archivos al directorio del Tomcat, lo hace con "@copy" que no imprime nada a pantalla; para ver lo que se está copiando hay que cambiarlos todos por "copy"&lt;/li&gt;
&lt;/ol&gt;El callmake.bat no cambia a menos que se cambie de versión del generador, por lo que después hay que volver a dejarlo como estaba. El .mak cambia cuando cambia el árbol de llamadas, así que vuelve solo a su estado normal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-100455522363185034?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/fB4pJgmZkUU/tiempos-de-compilacion-en-java-y-la.html</link><author>noreply@blogger.com (Marcos Crispino)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_gG6tlx1eBKw/Sha53dlr_-I/AAAAAAAAA2o/Gs2y1xkLsqQ/s72-c/GXLogo.gif" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/05/tiempos-de-compilacion-en-java-y-la.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-11570155635984305</guid><pubDate>Thu, 21 May 2009 13:57:00 +0000</pubDate><atom:updated>2009-06-12T11:25:21.474-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sugerencias</category><category domain="http://www.blogger.com/atom/ns#">reflexiones</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Comando "do case" en GeneXus</title><description>El comando &lt;i&gt;do case&lt;/i&gt; de GeneXus tiene una sintaxis que no me termina de convencer...&lt;br /&gt;
&lt;br /&gt;
El problema es que las condiciones de cada &lt;i&gt;case&lt;/i&gt; pueden ir sobre variables distintas. Más que un &lt;i&gt;do case&lt;/i&gt;, la sintaxis permite usarlo como un &lt;i&gt;if-elseif&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
En Java y C#, el comando equivalente es el &lt;i&gt;switch&lt;/i&gt;, que discrimina según los valores que toma una variable dada. Por ejemplo:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; switch (variable) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; case 1:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para el valor 1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; case 2:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para el valor 2&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; default:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para los demás valores&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;
}&lt;/tt&gt;&lt;/blockquote&gt;En GeneXus, el &lt;i&gt;do case&lt;/i&gt; me permite hacer cosas como&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; do case {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; case &lt;span style="color: red;"&gt;&amp;amp;variable = 1&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para el valor 1 de &amp;amp;variable&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; case &lt;span style="color: red;"&gt;&amp;amp;otra_variable = 2&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para el valor 2&lt;/tt&gt;&lt;tt&gt; de &amp;amp;otra_variable&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; otherwise:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para los demás valores&lt;br /&gt;
endcase&lt;br /&gt;
&lt;/tt&gt;&lt;/blockquote&gt;Me gustaría más tener un comando &lt;i&gt;if-elseif&lt;/i&gt; que me permitiera hacer:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; if &lt;span style="color: red;"&gt;&amp;amp;variable = 1&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para el valor 1 de &amp;amp;variable&lt;br /&gt;
elseif &lt;span style="color: red;"&gt;&amp;amp;otra_variable = 2&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para el valor 2&lt;/tt&gt;&lt;tt&gt; de &amp;amp;otra_variable&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para los demás valores&lt;br /&gt;
endif&lt;br /&gt;
&lt;/tt&gt;&lt;/blockquote&gt;y un comando &lt;i&gt;do case&lt;/i&gt; que fuera sobre los valores de una sola variable, algo así:&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt; do case &lt;/tt&gt;&lt;tt&gt;&lt;span style="color: red;"&gt;&amp;amp;variable&lt;/span&gt;&lt;/tt&gt;&lt;tt&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; case &lt;span style="color: red;"&gt; 1&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para el valor 1 de &amp;amp;variable&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; case &lt;span style="color: red;"&gt; 2&lt;/span&gt;:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para el valor 2&lt;/tt&gt;&lt;tt&gt; de &amp;amp;variable&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; otherwise:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // hago algo para los demás valores&lt;br /&gt;
endcase&lt;br /&gt;
&lt;/tt&gt;&lt;/blockquote&gt;Creo que nos forzaría a que el código quede más prolijo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-11570155635984305?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/1f2MIADhEp0/comando-do-case-en-genexus.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/05/comando-do-case-en-genexus.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-6468457494565702889</guid><pubDate>Wed, 13 May 2009 14:11:00 +0000</pubDate><atom:updated>2009-05-13T11:11:51.683-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">testeo</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Testeos de regresión de aplicaciones que usan bases de datos</title><description>El tema de testeo es un tema complicado en general, y más complicado todavía cuando involucra aplicaciones que usan base de datos, como lo son las aplicaciones generadas con GeneXus.&lt;br /&gt;
&lt;br /&gt;
Por suerte están surgiendo herramientas como &lt;a href="http://www.abstracta.com.uy/"&gt;GXTest&lt;/a&gt; o &lt;a href="http://wiki.gxtechnical.com/commwiki/servlet/hwiki?GXUnit"&gt;GXUnit&lt;/a&gt; que pretenden resolver el problema, aunque (por lo que se) todavía no han madurado demasiado. Creo que el testeo es un tema que está en el debe de la comunidad GeneXus en general.&lt;br /&gt;
&lt;br /&gt;
Ya de paso &lt;a href="http://ealmeida.blogspot.com/2009/04/que-les-gustaria-para-el-proximo.html"&gt;le respondo a Enrique&lt;/a&gt;, una charla que estaría buena para el encuentro GeneXus, es alguien que tenga medianamente resuelto el problema del testeo, que cuente su experiencia.&lt;br /&gt;
&lt;br /&gt;
En esta oportunidad quería comentar sobre un caso particular con el que me tocó enfrentarme.&lt;br /&gt;
&lt;br /&gt;
Tenemos una base de conocimiento que tiene un proceso bastante complicado (tiene varios, uno en particular...), por la cantidad de casos particulares que hay que manejar. Cada vez que hay que hacer algo en ese proceso, terminamos rompiendo alguno de los casos particulares que ya estaban funcionando.&lt;br /&gt;
&lt;br /&gt;
Tipico caso en el que se necesitan &lt;a href="http://en.wikipedia.org/wiki/Regression_testing"&gt;tests de regresión&lt;/a&gt;...&lt;br /&gt;
&lt;br /&gt;
Hacer el testeo a mano de este proceso es bastante engorroso, porque involucra varios pasos previos (hay que crear varias entidades: cotización, carpeta, uno o más documentos, una o más órdenes de trabajo, etc.). Cada caso de prueba, dependiendo de la complejidad, puede llevar entre 5 y 10 minutos aproximádamente.&lt;br /&gt;
&lt;br /&gt;
Entonces lo que estamos haciendo para automatizarlo es:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;tenemos una base de datos que se usa solo para el testeo automático, que tiene todos los datos básicos cargados.&lt;/li&gt;
&lt;li&gt;hay un script que borra (truncate table) todas las tablas operativas del sistema, para poder ejecutar cada caso en una base en blanco&lt;/li&gt;
&lt;li&gt;se diseña y ejecuta a mano el caso de prueba que se quiere registrar, hasta llegar al paso previo a presionar el botón que larga el proceso que queremos testear&lt;/li&gt;
&lt;li&gt;llegado a este punto, se genera (mediante un script SQL) un script SQL que genera todos los insert necesarios para dejar la base de datos en ese estado y se salva como script de inicialización para el caso de prueba&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;se ejecuta el proceso y se verifica a mano que esté bien, y si es así se graba el resultado (el proceso genera información en una sola tabla...)&lt;/li&gt;
&lt;li&gt;se hace un procedimiento en GeneXus que carga un SDT con los valores esperados (los obtenidos en el paso anterior) y otro SDT con los valores reales haciendo un for each a la tabla, y se llama a otro que compara los SDTs campo a campo&lt;/li&gt;
&lt;li&gt;se agrega el caso de prueba al programa main de testeo.&lt;/li&gt;
&lt;/ol&gt;Una vez hechos todos esos pasos, se puede ejecutar el caso de prueba todas las veces que se quiera, lo que es prácticamente instantaneo.&lt;br /&gt;
&lt;br /&gt;
Por ahora es algo con lo que estamos experimentando. Desarrollar todo este procedimiento de testeo llevó algún tiempo, así como hacer los programas la primera vez, pero ahora el costo de agregar un nuevo caso de prueba es relativamente bajo, en relación al tiempo de testeo que va a ahorrar y la tranquilidad que nos da.&lt;br /&gt;
&lt;br /&gt;
Creo que como experiencia sirvió, lo que no logro ver todavía es como extender esto a N situaciones distintas, porque por ahora es solo un proceso el que estamos testeando...&lt;br /&gt;
&lt;br /&gt;
¿Alguien tiene experiencia de testeo con bases de datos? ¿Alguien más hace testeo automático?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-6468457494565702889?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/JaTvmOIpEQs/testeos-de-regresion-de-aplicaciones.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/05/testeos-de-regresion-de-aplicaciones.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-3271653340161857848</guid><pubDate>Fri, 08 May 2009 15:37:00 +0000</pubDate><atom:updated>2009-06-12T11:25:34.061-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sugerencias</category><category domain="http://www.blogger.com/atom/ns#">reflexiones</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>Bloques de reglas en transacciones GeneXus</title><description>Una cosa que me gustaría tener en GeneXus, son bloques de reglas.&lt;br /&gt;
&lt;br /&gt;
Muchas veces pasa que tenemos varias reglas en una transacción que se ejecutan con las mismas condiciones.&lt;br /&gt;
&lt;br /&gt;
Un ejemplo sencillo:&lt;br /&gt;
&lt;blockquote&gt;msg('Atención: el atributo Att queda con valor "valor"') If [condiciones] on AfterValidate;&lt;br /&gt;
Att = "valor" If [condiciones] on AfterValidate;&lt;/blockquote&gt;Me gustaría poder escribir estas líneas como:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;{&lt;br /&gt;
msg('Atención: el atributo Att queda con valor "valor"');&lt;br /&gt;
Att = "valor";&lt;br /&gt;
}&lt;br /&gt;
If [condiciones] on AfterValidate;&lt;/blockquote&gt;El inicio y fin de bloque no tienen por que ser con { y }, es solo un ejemplo. &lt;br /&gt;
&lt;br /&gt;
Me parece que el código quedaría mucho más fácil de leer, sobre todo teniendo en cuenta que ahora las reglas pueden estar separadas por otras reglas en el código.&lt;br /&gt;
&lt;br /&gt;
Otra cosa que estaría bueno es poder decirle a GeneXus que las reglas de un determinado bloque se ejecuten en el orden que están escritas, pero eso ya me parece más difícil de conseguir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-3271653340161857848?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/HcVGxc581uk/bloques-de-reglas-en-transacciones.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/05/bloques-de-reglas-en-transacciones.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-33066466.post-8845329075392015521</guid><pubDate>Thu, 30 Apr 2009 15:02:00 +0000</pubDate><atom:updated>2009-04-30T12:02:45.120-03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">twitter</category><category domain="http://www.blogger.com/atom/ns#">genexus</category><title>¿Qué se dice de GeneXus en Twitter?</title><description>Ayer Armin escribió un artículo &lt;a href="http://arminbachmann.blogspot.com/2009/04/twitter-por-que-y-como-experiencias.html"&gt;contando como usa Twitter&lt;/a&gt; para enterarse de las cosas que se dicen de &lt;a href="http://www.gxtechnical.com/"&gt;GeneXus&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Pero entonces, ¿qué se dice de GeneXus en Twitter?&lt;br /&gt;
&lt;br /&gt;
Se puede buscar el término &lt;a href="http://search.twitter.com/search?q=genexus"&gt;"genexus" en Twitter Search&lt;/a&gt;, que además permite suscribirse a los resultados por RSS (ya lo hice), con lo cual es fácil monitorear lo que se está diciendo. La técnica sirve para cualquier otra búsqueda...&lt;br /&gt;
&lt;br /&gt;
Los "twiteos" (gorjeos?) de la última semana, sacando los de los usuarios &lt;a href="http://twitter.com/genexus"&gt;@genexus&lt;/a&gt; y &lt;a href="http://twitter.com/GXnews_"&gt;@gxnews_&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/horaciosoca" onclick="pageTracker._trackPageview('/exit/to/horaciosoca');" target="_blank"&gt;horaciosoca&lt;/a&gt;: &lt;span class="msgtxt es" id="msgtxt1657123109"&gt;&lt;b&gt;GeneXus&lt;/b&gt; (&lt;b&gt;genexus&lt;/b&gt;.com) comunica novedades &amp;amp; soporte de productos en Twitter (un buen "enfoque" del asunto) &lt;a href="http://tr.im/k4TW" onclick="pageTracker._trackPageview('/exit/link/1657123109')" rel="nofollow" target="_blank"&gt;http://tr.im/k4TW&lt;/a&gt;&lt;/span&gt;   &lt;/div&gt;about 6 hours ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/apanizza" onclick="pageTracker._trackPageview('/exit/to/apanizza');" target="_blank"&gt;apanizza&lt;/a&gt;: &lt;span class="msgtxt en" id="msgtxt1654930736"&gt;Armin is tweeting gx news: &lt;a href="http://twitter.com/arminbachmann" onclick="pageTracker._trackPageview('/exit/to/arminbachmann')" target="_blank"&gt;@arminbachmann&lt;/a&gt; &lt;a href="http://bit.ly/5p7u6" onclick="pageTracker._trackPageview('/exit/link/1654930736')" rel="nofollow" target="_blank"&gt;http://bit.ly/5p7u6&lt;/a&gt; &lt;span class="expand"&gt;(&lt;a class="lit" href="http://search.twitter.com/search?q=genexus#" onclick="decodeUrl(this); return false;"&gt;expand&lt;/a&gt;&lt;img alt="" src="http://search.twitter.com/images/search/expanding.gif?1241050657" style="display: none;" /&gt;)&lt;/span&gt;, also check  &lt;a href="http://twitter.com/genexus" onclick="pageTracker._trackPageview('/exit/to/genexus')" target="_blank"&gt;@&lt;b&gt;genexus&lt;/b&gt;&lt;/a&gt; for news going into the XIX user meeting !&lt;/span&gt;   &lt;/div&gt;about 11 hours ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/arminbachmann" onclick="pageTracker._trackPageview('/exit/to/arminbachmann');" target="_blank"&gt;arminbachmann&lt;/a&gt;: &lt;span class="msgtxt es" id="msgtxt1648782171"&gt;&lt;a href="http://twitter.com/arielmilani" onclick="pageTracker._trackPageview('/exit/to/arielmilani')" target="_blank"&gt;@arielmilani&lt;/a&gt; ... pq no trabajas con &lt;b&gt;GeneXus&lt;/b&gt; X? es muuuucho mejor. hay una trial de la X con menos limites que la 9.&lt;/span&gt;   &lt;/div&gt;about 23 hours ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/jean_dreyer" onclick="pageTracker._trackPageview('/exit/to/jean_dreyer');" target="_blank"&gt;jean_dreyer&lt;/a&gt;: &lt;span class="msgtxt es" id="msgtxt1644430340"&gt;Estudando &lt;b&gt;GENEXUS&lt;/b&gt;!&lt;/span&gt;   &lt;/div&gt;1 day ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/asantibanez" onclick="pageTracker._trackPageview('/exit/to/asantibanez');" target="_blank"&gt;asantibanez&lt;/a&gt;: &lt;span class="msgtxt es" id="msgtxt1642661838"&gt;dolor de cabeza con &lt;b&gt;Genexus&lt;/b&gt;.. queriendo ir a casa..&lt;/span&gt;   &lt;/div&gt;1 day ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/arminbachmann" onclick="pageTracker._trackPageview('/exit/to/arminbachmann');" target="_blank"&gt;arminbachmann&lt;/a&gt;: &lt;span class="msgtxt es" id="msgtxt1640719009"&gt;&lt;a href="http://twitter.com/arielmilani" onclick="pageTracker._trackPageview('/exit/to/arielmilani')" target="_blank"&gt;@arielmilani&lt;/a&gt; No entiendes algo de &lt;a href="http://twitter.com/GeneXus" onclick="pageTracker._trackPageview('/exit/to/GeneXus')" target="_blank"&gt;@&lt;b&gt;GeneXus&lt;/b&gt;&lt;/a&gt;? puedo ayudarte?&lt;/span&gt;   &lt;/div&gt;1 day ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/arielmilani" onclick="pageTracker._trackPageview('/exit/to/arielmilani');" target="_blank"&gt;arielmilani&lt;/a&gt;: &lt;span class="msgtxt pt" id="msgtxt1639164260"&gt;&lt;b&gt;Genexus&lt;/b&gt;... i hate you &lt;a href="http://search.twitter.com/search?q=%23caralhofilhadaputa"&gt;#caralhofilhadaputa&lt;/a&gt;&lt;/span&gt;   &lt;/div&gt;2 days ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/calcetin_huacho" onclick="pageTracker._trackPageview('/exit/to/calcetin_huacho');" target="_blank"&gt;calcetin_huacho&lt;/a&gt;: &lt;span class="msgtxt es" id="msgtxt1634094303"&gt;yap, &lt;b&gt;genexus&lt;/b&gt; time.&lt;/span&gt;   &lt;/div&gt;2 days ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/pedrogk" onclick="pageTracker._trackPageview('/exit/to/pedrogk');" target="_blank"&gt;pedrogk&lt;/a&gt;: &lt;span class="msgtxt es" id="msgtxt1633012157"&gt;congreso de &lt;b&gt;Genexus&lt;/b&gt; del 6 de mayo en Ciudad de México se pospone hasta nuevo aviso&lt;/span&gt;   &lt;/div&gt;2 days ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/ealmeida" onclick="pageTracker._trackPageview('/exit/to/ealmeida');" target="_blank"&gt;ealmeida&lt;/a&gt;: &lt;span class="msgtxt es" id="msgtxt1629131450"&gt;Malhumorado, porque no logro un night build que funcione en la &lt;b&gt;GeneXus&lt;/b&gt; X Ev1 (beta) y queria probar a fondo las K2bTools&lt;/span&gt;   &lt;/div&gt;3 days ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/apanizza" onclick="pageTracker._trackPageview('/exit/to/apanizza');" target="_blank"&gt;apanizza&lt;/a&gt;: &lt;span class="msgtxt en" id="msgtxt1610046210"&gt;Late in a friday at the &lt;b&gt;genexus&lt;/b&gt; office: &lt;a href="http://bit.ly/o4wp9" onclick="pageTracker._trackPageview('/exit/link/1610046210')" rel="nofollow" target="_blank"&gt;http://bit.ly/o4wp9&lt;/a&gt; &lt;span class="expand"&gt;(&lt;a class="lit" href="http://search.twitter.com/search?max_id=1659362586&amp;amp;page=3&amp;amp;q=genexus#" onclick="decodeUrl(this); return false;"&gt;expand&lt;/a&gt;&lt;img alt="" src="http://search.twitter.com/images/search/expanding.gif?1241050657" style="display: none;" /&gt;)&lt;/span&gt;&lt;/span&gt;   &lt;/div&gt;5 days ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/gxsoft" onclick="pageTracker._trackPageview('/exit/to/gxsoft');" target="_blank"&gt;gxsoft&lt;/a&gt;: &lt;span class="msgtxt en" id="msgtxt1607104670"&gt;DBF+CDX to SQL Finished, ready to DBRet 1.2 (&lt;b&gt;GeneXus&lt;/b&gt; Tool)&lt;/span&gt;   &lt;/div&gt;5 days ago&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div class="msg"&gt;         &lt;a href="http://twitter.com/ealmeida" onclick="pageTracker._trackPageview('/exit/to/ealmeida');" target="_blank"&gt;ealmeida&lt;/a&gt;: &lt;span class="msgtxt eo" id="msgtxt1585146984"&gt;Jugando con MSBuilds Task y &lt;b&gt;GeneXus&lt;/b&gt; X.&lt;/span&gt;   &lt;/div&gt;7 days ago&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33066466-8845329075392015521?l=blog.marcoscrispino.com'/&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/mcrispino/~3/k-kwPzGKYf4/que-se-dice-de-genexus-en-twitter.html</link><author>noreply@blogger.com (Marcos Crispino)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.marcoscrispino.com/2009/04/que-se-dice-de-genexus-en-twitter.html</feedburner:origLink></item></channel></rss>
