Blog de Federico Varela
Crónica Malvín 10K
Noviembre 30th, 2011 - [Enlace local]
Se fue la penúltima del año, el sábado 26 de noviembre corrimos una nueva 10k organizada por el Club Malvín con el auspicio de Antel. El recorrido incluyó los barrios de Malvín, Punta Gorda y Carrasco.La largada estaba programada a las 18:30 hs, luego de unos minutos de atraso comienza la prueba desde el Club con dirección a la Rambla.A los pocos metros nos encontramos con el "repecho" de Coimbra
» Leer más, comentarios, etc...
Preparando SCJP
Control del Flujo: Bucles
Noviembre 30th, 2011 - [Enlace local]
Los bucles nos permiten alterar el flujo de ejecución de un programa ejecutando repetidamente una sentecia o grupo de sentencias.
En Java 6 tenemos tres opciones distintas a la hora de realizar iteraciones:
- while,
- do while,
- for (normal y mejorado)
Vamos a ver cada una de ellas en detalle.
While
Es el bucle indicado cuando no se sabe de antemano cuántas veces se va a ejecutar el bucle. Simplemente queremos que se repitan ciertas acciones mientras la condición del bucle sea cierta.
//inicialización de variables
while (condicion){ //La condicion debe evaluarse a boolean
//codigo //Puede no ejecutarse ninguna vez
}
Cómo funciona:

Al entrar en el while se comprueba la condicion por primera vez.
Si resulta falsa no llega a ejecutar el código y se prosigue la ejecución fuera del bucle.
Si es cierta se ejecuta el código y se vuelve a comprobar la condición.
Así sucesivamente hasta que la condición devuelva falso y salgamos del bucle.
Como veremos la última sentencia que se ejecutará en un bucle siempre será la comprobación de la condición.
Por ejemplo:
En este código la variable i vuelve a incrementarse en la última comprobación de la condición del bucle, cuando ésta ya es falsa.
public class EjemWhile1{
public static void main (String[] args){
int i = -1;
boolean encontrado = false;
int[] medidas = {10, 30, 40, 50, 70};
while (++i < 5 && !encontrado){
if(medidas[i] == 40){
encontrado = true;
}
}
System.out.println(i);
}
}
En los bucles while estar atento a:
- Declaración de variables en la condición del while. No se puede, deben estar declaradas con anterioridad.
- Expresiones en la condición del while que no sean boolean.
Por ejemplo: enteros en lugar de boolean o asignaciones en lugar de comparaciones, darán error de compilación.
Do While
En estos bucles primero se ejecuta el código y luego se comprueba la condición, por lo que tenemos asegurado que el código se ejecuta al menos una vez.
do{
elem = pila.obtener();
System.out.println("elem: " + elem);
} while (!pila.esVacia());
Cómo funciona:
En primer lugar se ejecuta el código del bucle.
A continuación se comprueba la condición. Si esta es falsa se prosigue la ejecución fuera del bucle. Si es verdadera se ejecuta el código y se vuelve a comprobar la condición.
Estar atento a las mismas consideraciones que en el while.
For
Es el bucle que solemos utilizar cuando sabemos cuántas veces queremos ejecutar cierto código.
En su sintaxis podemos destacar tres partes importantes:
- declaración e inicialización de variables
- condición
- incremento.
Aunque ninguna de ellas son obligatorias.
Ejemplo de bucle mínimo for:
for ( ; ; ){ //sin inicializacion, condición ni incremento. Sería un bucle infinito.
//infinito
}
Ejemplo de un bucle for que equivaldría a un while:(sin inicialización ni incremento)
int i = 0;
for ( ; i<10 ; ){
i++;
}
Ejemplo de un bucle for típico:
for (int i=0;i<10;i++){
//declaración e inicializacion "int i=0"
//condicion "i<10"
//incremento "i++"
System.out.println("i: " + i);
}
Cómo funciona:

La inicialización de la variable se ejecuta al principio una sola vez.
A continuación se comprueba la condición y si es falsa se prosigue la ejecución fuera del bucle.
Si resulta cierta se ejecuta el código, se incrementa la variable y se vuelve a comprobar la condición.
Consideraciones del For.
Declaración e inicialización:
- Se pueden declarar 0, 1 o más variables del mismo tipo. Si hay más de una se separan por comas.
- Las variables declaradas en el for pierden su ámbito al salir del bucle for.
- Esta parte sólo se ejecuta una vez, al principio de la ejecución del bucle.
Condición:
- Sólo se puede comprobar una condición no varias.
Incremento:
- Se ejecuta despúes de que se ejecute el código del for.
For “Mejorado”
Simplifica recorrer un array o una colección. Tiene dos partes, la declaración y el elemento a recorrer.
int[] array = {10,20,30,50};
for (int elem: array){
System.out.println("elem: " + elem);
}
En la declaración: hay que declarar una variable compatible con el tipo de los elementos del array o de la colección.
En la expresión: será una variable array, colección o un método que las retorne.
Filed under: Estudio, Tema 5 Tagged: bucles, Certificacion Java, Control del flujo, do while, for, Java, ocpjp, SCJP, while
» Leer más, comentarios, etc...
MadeInFlex
Flex 4.6 y Flash Builder 4.6
Noviembre 30th, 2011 - [Enlace local]
Ya han salido las nuevas actualización de Flex y Flash Builder 4.6.
Recordad que se recomienda desinstalar las versiones antiguas. La licencia de las versiones 4.5 o 4.5.1 es totalmente valida.
» Leer más, comentarios, etc...
Koalite's blog
Tipos de repositorio: El repositorio concreto
Noviembre 30th, 2011 - [Enlace local]
En el post anterior hablaba sobre el repositorio genérico y, para variar, me quejaba de algunas cosas. Las que menos me gustan del repositorio genérico son:
- Contamina el dominio: se exponen al dominio los mismos métodos para todas las entidades, permitiendo realizar operaciones que quizá no fuesen deseables.
- Los métodos
FindXXXque devuelven varias entidades muchas veces generan problemas de eficiencia en el acceso a datos.
Para solventar el primer punto, hay una solución muy sencilla:
El repositorio concreto
No sabía muy bien como llamarlo, pero por contraposición al genérico, concreto me ha parecido un buen nombre. Un repositorio concreto se define para una sóla entidad y únicamente con los métodos necesarios para esa entidad. Un ejemplo típico:
public interface ICustomerRepository
{
Customer FindById(Guid id);
void Add(Customer customer);
IEnumerable FindPreferred();
IEnumerable FindWithOrdersInTheLastMonth();
}
La ventaja de esta implementación es que nos permite controlar exactamente qué se puede hacer con cada entidad y gana en expresividad porque se puede utilizar el lenguaje ubicuo para nombrar los métodos del repositorio.
Un inconveniente es que obliga a definir un interface diferente para el repositorio de cada entidad. En mi opinión esto no debería ser un problema porque realmente cada entidad va a tener operaciones diferentes y no debería ser necesario duplicar mucho más que el método FindById.
Un factor muy importante a tener en cuenta al implementar este tipo de repositorios es que el hecho de utilizar interfaces concretos no quiere decir que no podamos aprovechar una implementación genérica. Al usar este tipo de repositorios, en la implementación se puede encapsular un repositorio genérico con lo que se consigue reutilizar gran parte del código:
public class CustomerRepository : ICustomerRepository
{
private readonly Repository repository;
// Constructor para inyectar repository
public void Add(Customer customer)
{
repository.Add(customer);
}
public IEnumerable FindPreferred()
{
return repository.Find(Query.For(customer => customer.IsPreferred));.
}
// Resto de métodos . . .
}
Aunque esta implementación me gusta bastante más que el repositorio genérico, sigue teniendo sus problemas. Una parte que no me acaba de gustar es que muchas veces el repositorio concreto lo único que hace es redirigir llamadas a los métodos del repositorio genérico que encapsula.
Además, seguimos sin resolver el problema de los FindXXX, especialmente en lo referente a leer información para la capa de presentación, porque seguimos cargando siempre entidades completas, sin tener en cuenta si queremos precargar o no sus relaciones y eso puede dar muchos problemas de eficiencia que luego son complicados de resolver con esta arquitectura.
En el siguiente post empezaremos con la parte interesante de toda esta historia sobre repositorios viendo otra alternativa a la implementación de los repositorio: El no-repositorio.
» Leer más, comentarios, etc...
Escuela De Codigo
El mejor curriculum de un programador: el Open Source
Noviembre 30th, 2011 - [Enlace local]
Buscas en los periódicos ofertas de empleo o en las bolsas de trabajo en la web, encuentras el puesto de tus sueños: “Analista Programador Senior En La ultima tecnología del momento”, el salario no te garantiza una vida de magnate de playboy pero, es lo suficiente atractivo como para ponerte a soñar despierto sobre las compras que harás en fin de año, así que preparas tu hoja de vida, tu curriculum, con una foto reciente donde salgas bien peinado, tus datos personales, un poco de tu historia académica (solo lo mas reciente, a nadie le importa donde estudiaste la primaria) luego tu perfil técnico, expones tus virtudes como si cortejando a una mujer estuvieras, exagerando donde hay algo bueno y ocultando lo que aun no es prudente mostrar, un par de referencias de personas que puedan decir: “Ese es el programador que busca!” y listo. Lo envías, a los días te llaman, el nerviosismo de la entrevista, las preguntas para evaluar que no estes loco de remate, saludo y despedida con el entrevistador. Aun no lo sabes pero, ya no volveras a ver a esa persona en toda tu vida. El de seguro vio tu curriculum y se pregunto: ¿Y como se que es cierto que sabe programar en [poner el lenguaje de tu eleccion aqui]? Algo fallo, ¿aun no sabes que? es fácil, tu curriculum no demuestra nada.
¿Que te han dicho toda la vida que debe poseer tu curriculum?
Yo recuerdo unas cuantas cosas
- Una foto reciente ( y de cuerpo completo si tienes algo agradable que mostrar y bueno si trabajo de modelo andas buscando)
- Tus datos personales
- Donde contactarte
- Tus estudios recientes (nada de tonterías de primaria)
- Tus habilidades técnicas
- Y referencias de trabajos anteriores
Inicialmente puede parecer que estas cosas son mas que suficientes pero, si tomamos en cuenta que el único fin y propósito de un curriculum es mostrarle a alguien que no nos conoce, los datos suficientes para determinar si somos la persona indicada para el trabajo que ofrece, es ahi donde empezamos a ver las deficiencias de un curriculum tradicional, sobre todo para trabajos tan técnicos como lo es el del programador (y tambien el de diseñador): porque un poco de papel no demuestra absolutamente nada de lo que sabes hacer
Y escribir en una hoja de papel todo lo que sabes, sin dar mayor evidencia de que en verdad lo sabes, te coloca solo a un paso de ser un completo presumido que no tiene razón de ser presumido.
Programador demuestra que sabes programar
En algunas tribus antiguas, el joven se volvia hombre hasta que demostraba que era capaz de sobrevivir a duras condiciones, hasta que era capaz de cazar y matar a su presa sin ayuda de nadie, hasta que era capaz de enfrentar a la muerte y sobrevir para luego carcajearse en su cara, hoy hemos evolucionado un poco pero, siempre debemos demostrar nuestro valor ante los demas para conseguir algo muy valioso: respeto y admiracion.
Un programador es reconocido como programador hasta que otro de sus iguales lo ve como tal, hasta que su tribu tiene evidencia de que el “nuevo” sabe de lo que habla y conoce muy bien lo que hace, ya que no podemos organizar todos los fin de semana excursiones para ir a cazar fieras salvajes (supongo que muchos no se apuntarian) un programador tiene una forma (aunque no la única) de mostrar al mundo que el sabe de lo que habla: el Open Source
Hagamos Open Source
Open Source basicamente es: mi código lo regalo para que el mundo lo use como quiera
Colaborar en un proyecto open source, crear nuevos proyectos, compartir tu código con el mundo trae varias ventajas que abonan mucho con el propósito que andamos buscando: demostrar que si sabes lo que has puesto en tu curriculum
- Tu código esta a la vista de todos. Por lo que si es bueno no tardaran en llegar los elogios y si es malo no tardaran de llegar las sugerencias, sea como sea tu ganas.
- Ayudas a una comunidad, nada mejor para el alma que ayudar a tu prójimo, aunque sea con un buen trozo de código.
- Cuando programas sin obtener beneficio económico demuestras pasión por lo que haces, una gran virtud que es apreciada en los buenos trabajos.
- Si alguien quiere referencias tuyas de lo que sabes hacer, con unas cuantas búsquedas en Google tendrá mas que suficientes.
Puntualmente participar activamente en algún proyecto open source (ya se propio o de alguien mas) te hace visible en la web, te da personalidad, te permite mostrar que lo que dice en tu curriculum es cierto! Tu sabes programar en [coloca tu lenguaje favorito aquí] tan bien que hasta otros usan tu código en sus proyectos!!
Llegara el día en que solo necesitaras mostrar cuales son tus proyectos open source para que los empleadores te acepten o rechazen pero, mientras eso pasa, tu curriculum se vera mucho mejor, mas completo y veraz con unas cuantas paginas haciendo referencia a ese Open Source en el que estas trabajando.
Dando el ejemplo
Y como no me gusta hablar lo que no practico, aquí les dejo unos enlances a unos cuantos proyectos de mi creación:
http://hkadejo.github.com/NoTecladoVirtual/
http://hkadejo.github.com/jquery-ui-muni14/
https://github.com/escueladecodigo/wpinstaller
Si se que son pocos pero, ya vienen mas en camino!!
¿Y los tuyos cuales son? Compártelos!
» Leer más, comentarios, etc...
Picando Código
Meetup del concurso Desarrollando América Latina en Montevideo
Noviembre 29th, 2011 - [Enlace local]
Se organizó una reunión para los participantes de Desarrollando América Latina en Uruguay. La convocatoria es para este miércoles 30 de Noviembre a las 20 horas en CoworkingMVD: Bulevar España 2529 esquina Libertad.
La idea de la reunión es que los participantes nos vayamos conociendo, contar cómo va a estar organizado el fin de semana para el concurso, mostrar conjuntos de datos disponibles, y armar grupos para quienes no tengan.
También se van a estar mostrando algunas ideas que se han ido recolectando para quienen estén buscando proyecto a realizar.
Les recuerdo que Desarrollando América Latina es un concurso de aplicaciones web usando Datos Abiertos. Durante el fin de semana del 3 y 4 de diciembre, desarrolladores de 6 países latinoamericanos tendrán una maratón de 30 horas consecutivas de desarrollo. El objetivo es encontrar soluciones digitales a problemas sociales haciendo uso de datos abiertos.
¡Nos vemos ahí!
» Leer más, comentarios, etc...
Variable not found
Mamá, ¿de dónde vienen los metadatos?
Noviembre 29th, 2011 - [Enlace local]
En ASP.NET MVC normalmente utilizamos atributos para aportar información adicional a las propiedades del Modelo, incluyendo detalles como su descripción textual, formato de presentación, tipo de datos, etc. Esta información puede ser utilizada desde la capa vista para generar etiquetas, editores y, en algunos casos, incluso lógica de edición o presentación en la página.
Sin embargo, los atributos en el propio código de la clase no son la única vía para especificar metadatos en el framework. En este post veremos cómo extender el framework para crear nuevas vías para especificar esta información.
1. Proveedores de metadatos
Como decíamos, ASP.NET MVC viene de fábrica con componentes que nos permiten introducir anotaciones directamente sobre las propiedades de las clases que manejamos. En el siguiente ejemplo podemos ver una entidad en la que se están introduciendo metadatos según este mecanismo:public class Friend
{
[Required]
[Display(Name="Full name")]
public string FullName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string EmailAddress { get; set; }
[Required]
[DataType(DataType.Url)]
[Display(Name = "Blog url")]
public string BlogUrl { get; set; }
[Display(Name="Birth year")]
public int BirthYear { get; set; }
}
Cuando el framework necesita obtener los metadatos relativos a una clase, utiliza un metadata provider, un componente que se encarga de obtener los metadatos desde donde se encuentren definidos. El proveedor usado por defecto se llama DataAnnotationsModelMetadataProvider, y es el responsable de leer los atributos desde la definición de la clase, pero podemos sustituirlo fácilmente por otro proveedor que obtenga los metadatos desde otros orígenes, como archivos de configuración, bases de datos, o simplemente introducir lógica durante la generación de los mismos.
Sea cual sea su origen, los metadatos siempre se representan como objetos del tipo ModelMetadata, cuya estructura podéis ver a la derecha. Los providers deben incluir la lógica para obtener los metadatos desde donde corresponda, pero siempre retornarán objetos ModelMetadata, en los que, entre otra información, podemos encontrar los siguientes datos:- descripción del elemento,
- cadena de formato cuando es visualizado,
- tipo de datos que contiene (emails, urls, fechas, horas, etc.),
- orden en el que debe aparecer la propiedad si se generan interfaces de edición o visualización de la entidad,
- representación textual para los nulos,
- si el dato es obligatorio, o de sólo lectura,
- si debe ser mostrado en edición, o en visualización,
- la plantilla de edición o visualización que debe utilizarse,
- … y muchos más. Podéis consultar la referencia completa en MSDN.
¿Y cómo determina el framework MVC qué proveedor de metadatos utilizar?
En primer lugar, intenta utilizar el dependency resolver para obtener una instancia de un tipo que implemente
ModelMetadataProvider , que es la clase base para todos los proveedores. Este punto de extensión permite definir un proveedor personalizado muy fácilmente, y sobre todo si utilizamos contenedores IoC.Si no ha sido posible obtener un proveedor desde el dependency resolver, el framework utilizará el establecido en la propiedad
ModelMetadataProviders.Current. Por defecto, esa propiedad contiene una un objeto de la clase DataAnnotationsModelMetadataProvider, pero podemos sustituirlo por cualquier otro descendiente de ModelMetadataProvider .Por tanto, para crear un proveedor personalizado de metadatos, basta con:
- crear una clase descendiente de
ModelMetadataProvider. Por comodidad, usaremos normalmente como base algunos de los siguientes tipos, más concretos:DataAnnotationsModelMetadataProvider, si lo que pretendemos es extender el sistema por defecto, basado en la captura de metadatos desde las anotaciones (atributos) de la clase.AssociatedMetadataProvider, si lo que queremos es saltarnos por completo la obtención de metadatos desde la propia clase e implementar otros mecanismos.
- indicar al framework que debe utilizar nuestro nuevo proveedor, que podemos hacerlo:
- o bien usando el dependency resolver,
- o bien estableciendo una instancia del nuevo provider en
ModelMetadataProviders.Current.
2. Creando un metadata provider
Vamos a implementar un proveedor de metadatos sencillo con objeto de que podáis entender su funcionamiento.Como sabéis, al mostrar en una vista las etiquetas (labels) asociadas a una propiedad del Modelo, el texto que aparece es obtenido desde los metadatos de la entidad, desde el atributo
Display o DisplayName (en ese orden); en caso de no existir, se asume como descripción el nombre de la propiedad.Pues bien, nuestro objetivo es conseguir generar de forma automática estas las descripciones (
DisplayName) de cada campo partiendo del nombre de la propiedad, y teniendo en cuenta el “camel casing”, de forma que podremos ahorrarnos el teclear esta descripción en muchos casos. Por ejemplo, a una propiedad que se llame FullName se le asociará automáticamente la descripción “Full Name”, o EmailAddress se describirá como “Email Address”. De esta forma la entidad anterior podremos simplificarla un poco:
public class Friend
{
[Required]
public string FullName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
[Required]
[DataType(DataType.Url)]
public string BlogUrl { get; set; }
public int BirthYear { get; set; }
}
Fijaos que hemos eliminado los atributos [Display], y el resultado en ejecución de un editor de esta entidad se mostrará como en la captura de pantalla lateral, donde las etiquetas de cada campo han sido generadas automáticamente.Para ello, dado que queremos conservar el comportamiento del proveedor por defecto
DataAnnotationsModelMetadataProvider, lo extenderemos y añadiremos la lógica deseada a su método CreateMetadata(), que es el invocado para obtener los metadatos de la entidad y cada una de las propiedades:public class DisplayNameModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes, Type containerType,
Func<object> modelAccessor, Type modelType, string propertyName)
{
var metadata = base.CreateMetadata(attributes, containerType,
modelAccessor, modelType, propertyName);
if (metadata.PropertyName != null && metadata.DisplayName == null)
{
metadata.DisplayName = splitCamelCase(metadata.PropertyName);
}
return metadata;
}
static string splitCamelCase(string input)
{
return Regex.Replace(input, "([A-Z])", " $1",
System.Text.RegularExpressions.RegexOptions.Compiled).Trim();
}
}
La implementación del método CreateMetadata() no es nada del otro mundo:- En primer lugar, llamamos a la clase antecesora para obtener los metadatos a partir de las anotaciones del modelo.
- A continuación, si no se ha obtenido ningún valor de metadatos para el
DisplayName, y siempre que se esté evaluando una propiedad, la establecemos, generándola mediante el métodosplitCamelCase(). - El método
splitCamelCase()no tiene mucho misterio (bueno, sí, usa expresiones regulares ;-)), y lo único que hace es buscar las letras mayúsculas e insertar delante de ellas un espacio. Es algo tosco, pero me vale para no desviar la atención del post a este detalle sin importancia (y por cierto, el mérito de este método no es mío, sino de Jon Galloway).
2.1. Registro del proveedor directamente
La fórmula más rápida y sencilla consiste en establecer directamente una instancia del nuevo proveedor en la propiedadModelMetadataProviders.Current, durante la inicialización de la aplicación, por ejemplo así: protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelMetadataProviders.Current = new DisplayNameModelMetadataProvider();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
Esto es todo lo que necesitamos hacer para que nuestro flamante proveedor entre en funcionamiento.2.2. Registro del proveedor usando el dependency resolver
Si estáis utilizando un contenedor de IoC, quizás sea más coherente introducir la resolución de este proveedor en el mismo.Cuando el framework intenta obtener el proveedor de metadatos actual, antes de nada intenta localizarlo utilizando el dependency resolver. Si estamos utilizando un contenedor IoC como Unity o StructureMap, podemos utilizarlos para gestionar esta dependencia, asociando la clase abstracta
ModelMetadataProvider al tipo concreto DisplayNameModelMetadataProvider.Por ejemplo, en el caso de Unity, lo más sencillo es instalar el paquete Unity.MVC3 desde Nuget, y ya simplemente tendríamos que incluir la siguiente línea en el registro de tipos (en el archivo bootstrapper.cs):
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
container.RegisterType<ModelMetadataProvider, DisplayNameModelMetadataProvider>();
container.RegisterControllers();
return container;
}
Una vez registrado el provider, sea directamente o mediante este último mecanismo, el sistema obtendrá los metadatos desde éste. Así, tendríamos el siguiente resultado:| Clase del Modelo | Vista | Resultado |
public class Friend
{
[Required]
public string FullName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string EmailAddress
{ get; set; }
[Required]
[DataType(DataType.Url)]
public string BlogUrl { get; set; }
public int BirthYear { get; set; }
}
| @using (Html.BeginForm())
{
@Html.EditorForModel()
<div>
<input type="submit" />
</div>
}
| ![]() |
En definitiva, en este post hemos visto que en ASP.NET MVC los metadatos no proceden de una ubicación fija, sino que son obtenidos a través de un proveedor configurable. Esto nos permite modificar el comportamiento por defecto del framework y adaptarlo a nuestras necesidades, generarlos de forma dinámica, como en el ejemplo que hemos visto, u obtenerlo desde algún almacén de persistencia (como podría ser un archivo de configuración o una bases de datos), y siempre de forma muy sencilla aprovechando la magnífica extensibilidad del marco de trabajo :-)
Publicado en: Variable not found.
» Leer más, comentarios, etc...
Preparando SCJP
Control del Flujo: If y Switch
Noviembre 28th, 2011 - [Enlace local]
Las sentencias condicionales permiten ejecutar código de forma selectiva.
En Java tenemos las sentencias condicionales if y switch.
Sentencia If:
La sintaxis más sencilla de una sentencia if es:
if (expresionLogica) //Si expresionLogica se evalúa a true entonces se ejecuta codigo. codigo
Si se tiene una sola sentencia de código no es obligatorio encerrarla entre llaves pero siempre es recomendable por legibilidad.
Ejemplo:
if (precio < 100){
comprar(); //Mas legible entre llaves.
}
Si nos encontramos un if sin llaves debemos recordar que solo aplica a la primera sentencia.
if (precio < 100)
comprar(); //Solo esta sentencia forma parte del if.
salirTienda(); //No forma parte del código del if. Siempre se ejecuta.
volverACasa(); //No forma parte del código del if. Siempre se ejecuta.
La cláusula else es opcional. Se incluye cuando queremos que se ejecute código en el caso de que no se cumpla la condición en el if.
if (precio < 100){
comprar();
}
else{
System.out.println("Yo no soy tonto.");
}
También podemos tener una estructura if, else-if, else. Se da en los casos en los que queremos comprobar varias condiciones.
if (precio < 100){
comprar();
}
else if (price < 2000 && tengoCredito){
comprarConTarjeta();
}
else{
System.out.println("Yo no soy tonto.");
}
En las sentencias If se cumplirá:
- Habrá 0 o muchos else-if y precederán a la cláusula else.
- Habrá 0 o 1 else e irá a continuación de todas las cláusulas else-if.
- Cuando una condición se cumple el resto no se comprueba.
- Si tenemos un else y no sabemos a que if corresponde será el más cercano sin else.
- La asignación en una condición no da error si se trata de un lógico: if(indicador=true)
Switch
Con esta sentencia vamos a evaluar una expresión y dependiendo de su valor ejecutaremos un código u otro:
switch (expresion){
case constante1: codigo1
case constante2: codigo2
case constante3: codigo3
default: codigo
}
Si expresion coincide con alguna de las constantes se ejecutará el código de ese case y se seguirá ejecutando el código de los siguientes case hacia abajo hasta que se encuentre una sentencia break.
La sentencia default es opcional y se puede especificar cuando queremos que se ejecute un código para cualquier valor que sea distinto a los especificados en los case.
En los siguientes ejemplos podemos comprobar cómo afecta al resultado la existencia y posición de las sentencias breaks y default:
1. Ejemplo de un Switch Típico.
Switch con breaks en cada case y una clásula default al final.
Recorremos el array niveles. Cada valor entra en su case correspondiente y para al tener la sentencia break. Al estar la cláusula default al final no hace falta que tenga break.
public class EjemploSwitch1{
public static void main (String[] args){
int[] niveles = {1, 2, 3, 0};
System.out.println("\nEjecucion Switch Tipico (breaks y default al final): " );
for (int i=0; i < niveles.length; i++){ {
System.out.println("Nivel: " + niveles[i]);
switch (niveles[i]){
case 1: System.out.println("\tNivel Basico.");
break;
case 2: System.out.println("\tNivel Intermedio.");
break;
case 3: System.out.println("\tNivel Avanzado.");
break;
default: System.out.println("\tNivel no informado.");
}
}
}
}
Resultado:

2. Sentencia Default No al Final.
En este caso hemos colocado la sentencia default sin break después del primer case. Todos los case tienen break. Cuando niveles[i] es igual a 0, ejecuta el código asociado a default. Al no tener break pasa al case 2, ejecuta su código y entonces sí para al tener break.
public class EjemploSwitch2{
public static void main (String[] args){
int[] niveles = {1, 2, 3, 0};
System.out.println("\nEjecucion Switch con Breaks Default enmedio sin break: " );
for (int i=0; i < niveles.length; i++) {
System.out.println("Nivel: " + niveles[i]);
switch (niveles[i]){
case 1: System.out.println("\tNivel Basico.");
break;
default: System.out.println("\tNivel no informado.");
case 2: System.out.println("\tNivel Intermedio.");
break;
case 3: System.out.println("\tNivel Avanzado.");
break;
}
}
}
}
Ejecución:

3. Sentencias Case sin Break (Ejemplo en el que no tiene lógica aplicarlo).
En este Switch comprobamos qué ocurre si no colocamos ningún break. Para cada valor de niveles se ejecutan todos los case y default.
public class EjemploSwitch3{
public static void main (String[] args){
int[] niveles = {1, 2, 3, 0};
System.out.println("\nEjecucion Switch sin Breaks (entra en todos los case cada vez): ");
for (int i=0; i < niveles.length; i++)
{
System.out.println("Nivel: " + niveles[i]);
switch (niveles[i])
{
case 1: System.out.println("\tNivel Basico.");
case 2: System.out.println("\tNivel Intermedio.");
case 3: System.out.println("\tNivel Avanzado.");
default: System.out.println("\tNivel no informado.");
}
}
}
}
Ejecución:

4. Sentencias Case Sin Break (Ejemplo en el que sí podría ser útil).
En este caso comprobamos cómo a veces puede tener lógica para nuestro código dejar los case sin break. Hemos cambiado el orden de las constantes en los case.
public class EjemploSwitch4{
public static void main (String[] args){
int[] niveles = {1, 2, 3, 0};
System.out.println("\nEjecucion Switch sin Breaks (con logica que podria ser correcta): ");
for (int i=0; i < niveles.length; i++)
{
System.out.println("Nivel: " + niveles[i]);
switch (niveles[i])
{
case 3: System.out.println("\tNivel Avanzado.");
case 2: System.out.println("\tNivel Intermedio.");
case 1: System.out.println("\tNivel Basico.");
break;
default: System.out.println("\tNivel no informado.");
}
}
}
}
Ejecución:

En el switch se debe cumplir:
- La expresión evaluará a char, byte, short, int o enum.
- Las constantes deben ser constantes en tiempo de compilación.
- Hay que usar break cuando se necesite parar evitar la ejecución de los case posteriores.
- La cláusula default no tiene por qué ser la última.
- No puede haber dos case comprobando el mismo valor. No compilará.
- No se pueden omitir las cláusulas case ni los ‘:’
Filed under: Estudio, Tema 5 Tagged: Certificacion Java, Control del flujo, Flujo de Control, if, Java, ocpjp, SCJP, switch
» Leer más, comentarios, etc...
Javier Pérez
Cómo promocionar un blog: Analítica Web
Noviembre 28th, 2011 - [Enlace local]
Analítica Web
Llegamos casi al final de este pequeño curso de marketing online aplicado a la promoción de blogs, entrando en materia en un aspecto que los blogueros principiantes suelen obviar: la analítica web.
Analizar nuestras visitas, para empezar, no nos va a traer más lectores al blog. Lo que nos puede traer más lectores es lo que extraigamos de ese análisis y lo que hagamos en consecuencia.
Hay quien cree que eso de la analítica web es simplemente ver una gráfica con las visitas que hemos tenido en un periodo de tiempo determinado, y aunque en parte sea así, es la parte menos importante de todas.
La analítica web sirve fundamentalmente para medir. ¿Medir qué? Por ejemplo:
- Los artículos que no interesan ni al tato (porcentaje de salidas).
- …y los que más interesan a mis lectores.
- Capacidad de retener a mis lectores cuando entran en mi blog (bounce rate / porcentaje de rebote).
- Las redes sociales que más tráfico me traen.
- Los anuncios más rentables que he puesto.
- El tiempo medio que mis lectores habituales pasan leyendo mis artículos.
Una vez hemos analizado y medido, lo siguiente es obrar en consecuencia, reaccionar. Por ejemplo:
- Los artículos en los que hablo de la sexualidad del escarabajo pelotero no interesan a nadie. Así que escribiré sobre otras cosas que también me interesen.
- El artículo en el que hablé sobre la sexualidad de Scarlett Johansson tiene millones de visitas. Mira… ya tengo una idea para mis próximos artículos.
- Mi porcentaje de rebote es demasiado alto, lo que quiere decir que los lectores que entran no leen mis otros artículos. Quizás deba volver a leerme el artículo sobre usabilidad y colocar mejor un bloque de enlaces a mis otros artículos en un lugar estratégico.
- Veo que han subido bastante las visitas desde Google+, quizás sea hora de tomarme más en serio esa red social y participar más siguiendo los consejos del artículo sobre social media.
- Ese anuncio que puse en una web sobre música alternativa por el que pago 10 € al mes me trae el 10% de mis visitas. Quizás sea buena idea añadir más anuncios en esa web.
- Mis lectores habituales (visitas recurrentes) suelen pasar en mi blog más de dos minutos. Seguro que les gustará ese artículo bien extenso y completo que nunca me atrevo a publicar.
Por lo tanto, la analítica web es un proceso constante de medir y reaccionar. Puedes empezar midiendo las temáticas que más interesan a tus lectores, para seguir escribiendo sobre esos temas, y obviar los temas que no interesan.
Además, la métrica nos ofrece otras tantas utilidades, como saber si el servidor se ha caído o tiene algún problema (disminución drástica de visitas), o incluso crear alertas para informarme de eventos, como por ejemplo si hemos sido enlazados en menéame (en la imagen, la creación de la alerta en Google Analytics).

¿Cómo consigo estadísticas para mi blog? Hay multitud de herramientas que realizan estadísticas de tus visitas, pero como aquí nos interesan más las métricas (medir), la mejor herramienta por relación calidad/precio (buenísima/gratis) es Google Analytics.
Para WordPress te puedo recomendar dos plugins muy interesantes:
- Google Analytics for WordPress: Lo hace todo, desde incluirte el código de Analytics en tu blog, hasta crearte variables personalizadas por categoría, tags, o autor. Y todo sin salir de WordPress. Imprescindible.
- Google Analytics Dashboard: Te crea un widget en el dashboard (escritorio) de WordPress con las estadísticas generales, y una columna con estadísticas individuales en los listados de entradas. Muy útil para echar un vistazo rápido a tus visitas.
No tengo espacio aquí para explicar todas las funcionalidades de Google Analytics. Es un tema que daría para un libro, y de hecho los hay patadas. Yo te recomiendo el último de Avinash Kaushik, un auténtico gurú de la analítica web, así como el blog de Gemma Muñoz, una de sus más fervientes seguidoras.
Si tienes alguna pregunta la puedes hacer por email (respondiendo al email si estás viendo esto por suscripción por email) o en un comentario, y en la medida de mis posibilidades te responderé lo antes posible. Además, si necesitas ayuda profesional, puedes contar conmigo.
¿Te ha resultado interesante este artículo? La próxima semana terminamos este pequeño curso, hablando sobre marketing de afiliación.
ÍNDICE
0. Introducción
1. SEO
2. SEM
3. Social Media
4. Emailing
5. Usabilidad
6. Analítica Web
7. Afiliación
» Leer más, comentarios, etc...
Koalite's blog
Repositorios: El repositorio genérico
Noviembre 28th, 2011 - [Enlace local]
A algunos les gustan gordos. Otros los prefieren más pequeños. Los hay que los preferían gordos y ahora directamente ya no les gustan. Estoy hablando, claro está, de los repositorios. Aunque todos persiguen el mismo objetivo, hay diversas formas de implementarlos y hoy vamos a ver una de las más extendidas.
El repositorio genérico
Ahora está más cuestionado, pero durante mucho tiempo fue el rey de los repositorios. Surge con la esperanza de escribir la herramienta definitiva de acceso a datos combinando el uso de generics con un buen ORM. Suele tener una pinta parecida a esta:
public interface IRepository{ TEntity FindById(TId id); void Delete(TEntity entity); void Save(TEntity entity); IEnumerable FindAll(); IEnumerable FindBy(Query query); // Unas cuantas sobrecargas para buscar con paginación ... // Otras sobrecargas más para indicar la ordenación ... }
Esto es una especie de navaja suiza capaz de lanzar todo tipo de consultas a la base de datos. Para sus defensores, su principal ventaja es que permite usar la misma implementación para todas las entidades, evitando crear nuevas clases cuando aparecen nuevas entidades.
Si queremos añadir métodos específicos para alguna entidad la solución es sencilla. Sólo hace falta heredar del interface genérico y añadir los métodos que queramos:
public IUserRepository : IRepository{ User FindByEmail(string email); }
Como todo, esta solución también tiene sus problemas:
Expone demasiados métodos, y siempre expone los mismos métodos para todas las entidades. Sí, son justo las ventajas que le ven otros: un interface completo y flexible que se puede usar genéricamente con cualquier entidad. Esto no es bueno porque no todas las entidades son iguales ni queremos que se puedan tratar por igual.
El ejemplo que veo más claro de esto es el borrado y la creación. Hay entidades que, generalmente, no pueden ser borradas, como una factura, que una vez emitida debe quedar registrada para siempre. Otras entidades no son creadas en nuestra aplicación (simplemente existen porque llegan a la base de datos por otro camino), y no tiene sentido que el repositorio pueda añadir nuevas entidades.
En la mayoría de los casos, los métodos Find son problemáticos. ¿Para qué querríamos buscar más de una entidad? Los dos casos más frecuentes son para mostrarlas en el interfaz de usuario o para realizar un proceso por lotes con ellas.
Si estamos usando un método Find para llevar datos a la capa de presentación, seguramente estamos haciendo algo ineficiente. Es casi seguro que estamos cargando de la base de datos más información de la que necesitamos para luego, usando una capa de Mappers, generar los DTOs o Models que mandamos a la capa de presentación. Esto abre la puerta a bastantes problemas de eficiencia si no somos cuidadosos (select n+1, distintas estrategias de fetching).
Si lo que estamos haciendo es un proceso por lotes de las entidades, cuidado. Muchas veces al tener un ORM delante no nos damos cuenta del coste de lo que estamos haciendo, y en lugar de lanzar un update Customer set blocked = 1 where ... acabamos cargando 300 objetos Customer con su lista de Orders solo para marcarlos como bloqueados.
Existen variantes de este repositorio que devuelven IQueryable en lugar de IEnumerable, pero la idea es muy similar. También se puede separar el repositorio en varios interfaces permitiendo controlar un poco mejor la superficie expuesta hacia el exterior.
He usado mucho este tipo de repositorio y con el tiempo cada vez me gusta menos. La reutilización de código que se obtiene al final no merece la pena (se puede conseguir prácticamente lo mismo usando composición) y me parece que contamina el dominio añadiendo operaciones que tienen sentido sobre ciertas entidades.
Seguramente te estés preguntando qué ocurre si quieres tratar de manera genérica todas tus entidades y tener así un repositorio genérico, un controlador genérico y una vista genérica. Si tu aplicación es así, no te preocupes por cómo implementar el repositorio porque lo que estás desarrollando es una aplicación de manejo de datos (CRUD) que va a tener un dominio anémico y da igual como lo hagas: no tiene sentido aplicar DDD y por tanto menos sentido tiene ponerse quisquilloso con el tipo de repositorio.
» Leer más, comentarios, etc...
Escuela De Codigo
CMS, ¿usar o no usar?
Noviembre 28th, 2011 - [Enlace local]
WordPress el mejor CMS que nuestra generación ha conocido y seguramente muchas generaciones mas dirán lo mismo, me fascina usarlo y no puedo imaginarme hacer un sitio web para algún cliente sin hacer uso de WordPress, simplemente no puedo!!! Sus plugins, sus themes, todo absolutamente todo me gusta! Un CMS es la mejor solución para desarrollar sitios web estáticos o dinámicos!…..¿¿¿¿.eso es cierto????
¿CMS?
Si la palabra CMS te suena a saludo extraterrestre en lengua inventada de serie Geek, pongámonos todos al mismo nivel y expliquemos que es un CMS para aquellos que aun no manejan claramente el concepto
Un sistema de gestión de contenidos (en inglés Content Management System, abreviado CMS) es un programa que permite crear una estructura de soporte (framework) para la creación y administración de contenidos, principalmente en páginas web, por parte de los administradores, editores, participantes y demás roles.
Wikipedia siempre es útil asi que leer su articulo referente al tema nunca esta de mas.
¿Completamente claro? ¿No? CMS solo es un programa que te permite crear y administrar sitios web, no mas no menos, así de fácil e igualmente de complicado.
¿Porque usarlo?
Si eres de los desarrolladores que piensan que usar código de otro es una especie de blasfemia al dios de los códigos fuentes y que si lo haces seras desterrado del paraíso binario, déjame ser tu diablo y tentarte con unas cuantas razones por las que deberías pecar y utilizar un buen CMS.
- Partes de una base hecha, Partes de un proyecto inicial ya hecho y probado. Además también cuentas, normalmente, con una gran cantidad de Themes y Módulos/Pluggins que te ofrecen una gran cantidad de funcionalidades extra(Foros, Wikis, blogs, etc.). Esto hace reducir mucho el tiempo de desarrollo.
- Diseño del proyecto correcto y escalable, El hecho de que sea un CMS estandard mantenido por cientos de personas es obligatorio de que tenga una estructura escalable y poco acoplada. La separación entre CMS, Themes y módulos representa un patrón de desarrollo muy bueno. Si no utilizas un CMS estandard un buen diseño también depende de un buen desarrollador.
- Documentación abundante, En Internet encuentras abundante material en forma de manuales, tutoriales, artículos, etc.
- Formación del equipo de desarrollo, Al ser estandard se reduce muchísimo el tiempo que se tarda en formar y hacer que un nuevo miembro del equipo de desarrollo empiece a producir. Además también permite buscar especialistas en un CMS concreto.
- Estandarización, El hecho de que trabajemos en un marco estandard permite que aparezcan empresas que se especialicen en un sector concreto (Desarrollo de Themes, Pluggins especificos, etc.) y que se cree un market place alrededor del CMS. Esto hace mucho mas competitivo el sector.
- Independencia del desarrollador, Al ser un CMS estandard da la garantía al cliente que puede cambiar de desarrollador en caso que no este satisfecho.
Me has tentado, a utilizar un CMS se ha dicho!
Espera un momento! Quiero que te hagas una pregunta: ¿Que necesita mi usuario y/o cliente?
- ¿Un sitio web estático o dinámico?
- ¿Un carrito de compras?
- ¿Un formulario de contactos?
- ¿Registro de usuarios?
- ¿Un portal web?
- ¿Un foro?
- ¿Un ERP?
- ¿Un sistema de facturación?
- ¿Un punto de ventas?
- ¿Un sistema de contabilidad?
- ¿Un blog?
¿Porque esta pregunta es importante? Porque el usar o no un sistema de gestión de contenidos dependera de : La necesidad de tu cliente
Cuando se es novato (y bueno tambien siendo mas conocedor) se comete el error de querer matar moscas a cañonazos es decir querer resolver todos los problemas con las mismas soluciones, cuando eso evidentemente no es recomendado. Ten muy claro esto: un CMS no es para resolver todos los problemas.
Si tu usuario o cliente te pide alguna de las siguientes cosas:
- Un ERP.
- Un CRM.
- Un punto de ventas.
- Un mega espectacular sitio de comercio electrónico capaz de poner a temblar a Amazon.
- Un foro.
Definitivamente NO debes usar un CMS, en cambio si las necesidades de tus clientes, se encuentran entre las siguientes:
- Un blog.
- Un portal web.
- Un sitio web común y silvestre.
- Un pequeño carrito de compras.
- Registro de usuarios.
Es recomendable ahorrarte mucho trabajo y en lugar de empezar a picar codigo, te hagas de un buen gestor de contenidos y empieces a utilizarlo.
Ahora que ya vimos las ventajas de utilizar un CMS, cuando usarlo y cuando no hacerlo, solo nos queda responder: ¿Cuales son mis opciones? Asi que listo a continuacion los CMS mas populares hoy por hoy:
WordPress
Un par de años atrás, se debatió ampliamente si WordPress realmente debe considerarse como un CMS teniendo en cuenta sus raíces como una plataforma de blogs. Ese debate casi se ha dejado de lado en este momento,WordPress actualmente cuenta con un montón de poderes para sitios web no-blogs.
Fortalezas
- Comunidad de desarrolladores enorme con un montón de documentación y tutoriales disponibles
- Plugins gratuitos y de pago y temas especializados hacen posible crear prácticamente cualquier tipo de sitio web con WordPress
- Panel de control fácil de usar para administrar el contenido
Debilidades
- Puede ser excesivo para los sitios básicos
- Una instalación estándar puede tener un montón de problemas de seguridad, y es muy vulnerable a un ataque sin medidas de seguridad adicionales
- No hay soporte oficial fuera de los foros de usuarios, donde se puede o no obtener una respuesta oficial
Joomla!
Joomla! tiene una historia de desarrollo de largo y una comunidad de desarrolladores muy activa (con más de 200.000 usuarios y colaboradores), por lo que la búsqueda de información y tutoriales es fácil. También hay miles de plugins y add-ons para Joomla!, Por lo que ampliar la funcionalidad de Joomla! no necesariamente requiere de ningún código personalizado.
Fortalezas
- La autenticación del usuario se puede hacer con Twitter, Google, y LDAP, entre otros
- Más de 7000 extensiones
- Usuarios muy activos de la comunidad y las toneladas de documentación disponible
Debilidades
- De fondo no es tan fácil como algunos CMSs, aunque sigue siendo muy útil
- La falta de temas de alta calidad en comparación con algunos otros CMS
- Puede ser excesivo para los sitios sencillos
Drupal
Drupal es otro CMS muy popular, utilizado por un número de empresas de alto perfil incluyendo el New York Observer, Popular Science, MIT, Sony Music, Fast Company, entre otros. Incluye un montón de características para la construcción de sitios internos y externos, y un montón de herramientas para organizar su contenido.
Drupal tiene una comunidad muy activa, con un número de canales IRC, foros, e incluso cara a cara eventos Drupal. También hay documentación generada por la comunidad que está siendo constantemente actualizado y mejorado. Esta documentación incluye todo lo que necesita saber acerca de instalación,módulos, temas de diseño, y mucho más.
Fortalezas
- Apoyo de la comunidad sólida, incluyendo los canales de IRC y encuentros de cara a cara
- Más de 6.000 módulos, lo que hace altamente extensible Drupal
- Un gran número de empresas que ofrecen soporte comercial para Drupal
Debilidades
- Puede ser excesivo para los sitios sencillos
- A falta de muy alta calidad, temas libres y comerciales (hay algunas, pero no tantos como hay en otros CMSs)
- Sistema de tematización es bastante complicado
Hay una enorme cantidad de CMS, unos Open Source, otros de pago, de mayor o menor calidad y popularidad. Me he limitado a estos tres porque son los que conozco (en mayor medida WordPress) y se que con esos tres tienes ya mucho para aprender y auxiliarte en tu trabajo. Solo recuerda, usa un CMS sabiamente.
» Leer más, comentarios, etc...
Fetishcode
autoHeightRows en af:table
Noviembre 26th, 2011 - [Enlace local]
A
» Leer más, comentarios, etc...
Picando Código
Indie Game Music Bundle
Noviembre 26th, 2011 - [Enlace local]
El revolucionario modelo de negocios utilizado por el Humble Indie Bundle da resultado, de eso ya no queda ninguna duda:
Pagar lo que quieras por contenidos multimedia que puedas distribuir libremente.
En este caso este modelo se nos presenta con una oportunidad bastante interesante: Indie Game Music Bundle – comprar la banda sonora oficial de 10 videojuegos de estudios independientes por una suma que elijamos (a partir de U$S 1). El sitio nos avisa: no te avergüences de poner un dólar, la opción está ahí por una razón – ¡queremos que escuches nuestra música! Pero si quieres apoyar a un montón de indies con hambre, ¡tu oportunidad es ahora!
Al pagar más, se obtiene más. Con contribuciones de U$S 10 en adelante, obtenemos 7 discos más. Todo esto 100% libre de DRM. Las descargas son archivos mp3 de 320kbps. Al no tener DRM podemos reproducirlos donde queramos y compartirlos sin restricciones.
Los videojuegos cuyas bandas sonoras están disponibles incluyen Minecraft, Super Meat Boy y The Binding of Isaac, con artistas como C418, Souleye, danny B, Jake “virt” Kaufman, y más.
Al momento de escribir este post estoy escuchando la banda sonora de Super Meat Boy. He leído excelentes críticas de este juego, pero no he podido jugarlo a falta de una versión para GNU/Linux. Se supone que una versión para GNU/Linux está entre los planes futuros, veremos… Mientras tanto, la banda sonora resulta bastante entretenida ![]()
Si les interesa, y les gusta la música de los videojuegos, dense una vuelta por GameMusicBundle.com y compren su paquete de música ![]()
» Leer más, comentarios, etc...
Picando Código
Algunas oportunidades de Black Friday
Noviembre 25th, 2011 - [Enlace local]
Hoy es el “Black Friday”, la fiesta que celebra el consumismo con descuentos varios en todo tipo de productos. Les dejo algunos de los descuentos con los que me encontré hoy. Si quieren compartir algún otro descuento que pueda ser interesante para los demás lectores, los invito a hacerlo en los comentarios:
Hosting al 50% en Hostgator
Descuento del 50% en todos los servicios de alojamiento. Esto incluye hosting compartido, hosting para revendedores, VPS, servidores dedicados y alojamientos Windows. No incluye dominios.
El sitio Hostgator mostrará los precios especiales, ya que no hay que usar insertar ningún código para recibir la promoción. El código se insertará automáticamente en todas las órdenes durante el viernes negro.
El descuento se aplica a la primera factura del cliente. Los alojamientos en servidores VPS y dedicados están disponibles en régimen mensual, por lo que la promoción solo aplica al primer mes (no así con planes anuales). La promoción deja los precios así:
- Hosting compartido: De $4.95 pasa a $2.48/mes (pre-pago)
- Hosting revendedores: De $24.95 a $12.48/mes (pre-pago)
- Hosting VPS: De $19.95 a $9.98/mes (el primer mes)
- Servidores dedicados: De $174 a $87/mes (primer mes)
La oferta se mantiene únicamente por 1 día.
40% de descuento en The Pragmatic Bookshelf
Al igual que el año pasado, el sitio The Pragmatic Bookshelf ofrece un 40% de descuento en todas las compras con el código promocional turkey. El código aplica en libros, PDFs y screencasts, con algunas excepciones como The SPDY Book y Exceptional Ruby. Hay libros sobre metodologías ágiles, desarrollo móvil (iPhone, Android), Java, Ruby y Rails y desarrollo de carrera entre otros.
Más información y condiciones.
15% de descuento en SplitReason
Mi sitio preferido de camisetas y más, splitreason.com, ofrece un 15% de descuento con el código promocional turkey. Oferta válida hasta el lunes 28 de noviembre.
60% de descuento en cómics
Por último, y no por eso menos importante, uno de mis recientes proveedores preferidos de cómics Mile High Comics ofrece un 60% de descuento en todas las compras con el código promocional BLACKFRIDAY. Este código afecta a los cómics y revistas, los trade paperbacks y hardcovers ya se encuentran a un 50% de descuento.
El envío dentro de Estados Unidos es gratis para compras mayores a U$S 30, para compras internacionales en compras mayores a U$S 60.
Recientemente tuve el gusto de realizar una compra en este sitio, y quedé realmente conforme. Si necesitan completar su colección de hace unos años con algunos números sueltos, este es el mejor lugar, y qué mejor oportunidad que un descuento del 60%.
Aprovecho para agradecer a Multiverseros por darme a conocer Mile High Comics ![]()
» Leer más, comentarios, etc...
Koalite's blog
Modificar una clase en Javascript: Eliminar los markers de Google Maps
Noviembre 24th, 2011 - [Enlace local]
Desde que empecé a jugar con javascript he ido aprendiendo muchas cosas nuevas, pero sin duda una de las más curiosas para alguien como yo, acostumbrado a lenguajes estáticos, ha sido la posibilidad de modificar las clases que ya existen.
En C#, si queremos cambiar el comportamiento de una clase tenemos disponibles varias técnicas, pero todas ellas implican crear una nueva clase:
- Podemos crear una clase derivada de la clase existente y redefinir los métodos que queremos (siempre que la clase no sea
sealedy los métodos seanvirtual). - Podemos crear un decorador alrededor de la clase.
Sin embargo, en Javascript podemos cambiar no sólo el comportamiento de una clase ya definida, sino hasta el de un objeto ya creado.
El problema: eliminar todos los marcadores de un mapa
Para profundizar un poco en esto vamos a ver un ejemplo práctico: jugando con las APIs de Google Maps quería buscar una forma de eliminar todos los marcadores (markers) que había añadido sobre un mapa para indicar puntos de interés. Aparentemente esto era algo sencillo en la versión 2, pero no tan fácil en la versión 3.
Como siempre he pensado que es importante saber lo que uno está haciendo, en lugar de copiar el código a ciegas el código de StackOverflow, decidí tratar de entenderlo.
El API original de Google Maps es algo así:
var map = new google.maps.Map(...);
// Para añadir un marker:
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(3, 17),
icon: 'img/marker.png',
title: '¡Hola!'
});
// Para eliminar el marker:
marker.setMap(null);
Básicamente, al crear un Marker le asignamos un Map y el Marker se pinta sobre él. Cuando queremos eliminarlo, establecemos el Map del Marker a null y ya está. Fácil.
El problema es que Map no almacena ninguna referencia a los Markers que se han pintado sobre él, por lo que no es posible eliminarlos a menos que mantengamos externamente una lista con todos los Markers que hemos ido añadiendo. Esa es una solución viable, pero queda feo. Podemos hacerlo mejor.
La solución: modificar las clases Marker y Map
Volvemos al principio del artículo, la modificación de clases en javascript, porque esa es justo la solución más elegante al problema. Vamos a modificar las clases Map y Marker para que entre ambas mantegan la lista de markers de forma interna y así podamos luego borrarlos limpiamente.
En javascript podemos modificar un objeto con sólo añadirle propiedades de cualquier tipo, y teniendo en cuenta que las funciones son un tipo más en javacript, eso quiere decir que podemos añadirle sin ningún problema nuevos métodos e incluso sobreescribir los que ya existen.
var lucas = {
name: 'lucas',
sing: function() {
console.log('estoy cantando');
},
};
lucas.dance= function() {
console.log('estoy bailando');
}
// Ahora lucas sabe cantar y bailar
lucas.sing()
lucas.dance()
Podemos añadir las propiedades a un objeto especial (el prototipo de la clase) para que la modificación afecte a todos los objetos de una clase (incluyendo los que ya se han creado y los que se crearán):
var Person = function(name) {
this.name = name;
};
var lucas = new Person('lucas');
// Aquí lucas no sabe hacer nada todavía
Person.prototype.dance = function() {
console.log('¡mira como bailo!);
};
// Ahora lucas ya sabe bailar
lucas.dance();
Con estos, ejem, profundos conocimientos de como funciona el prototipado en javascript, podemos lanzarnos a hacer nuestra modificación a Map y Marker:
(function() {
// Añado a Map un array con los markers que contiene
google.maps.Map.prototype.markers = new Array();
// Añado a Map un método clearMakers que borrar los markers
google.maps.Map.prototype.clearMarkers = function() {
for (var i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(null);
}
this.markers = new Array();
};
// Reescribo el método setMap de Marker para que cuando se
// asigne el map se guarde en la propiedad markers del map
// OJO: almaceno en oldSetMap el antiguo método setMap
// para poder seguir utilizándolo
var oldSetMap = google.maps.Marker.prototype.setMap;
google.maps.Marker.prototype.setMap = function(map) {
if (map) {
map.markers.push(this);
}
oldSetMap.call(this, map);
}
})();
Creo que con los comentarios queda bastante claro lo que está pasando. Un par de cosas destacables:
- Todo el código lo estamos ejecutando dentro de una función anónima que invocamos automáticamente:
(function(){...})(). Esto lo hago porque quiero aprovechar el cierre (closure) sobre la variableoldSetMapy poder utilizarla sin contaminar el ámbito global. - Para invocar el antiguo
setMap, hay que utilizar la funcióncall()de javascript que nos permite invocar una función como si perteneciese a un objeto, en este caso aMarker.
Lo interesante
Para mi lo más interesante de este ejemplo no es cómo borrar los Markers (aunque en su momento era el problema que quería resolver), sino lo diferente que es la solución en javascript a la que hubiera sido en un lenguaje estático.
La idea de poder modificar "al vuelo" clases es una técnica muy poderosa, pero como decía el tío Ben: un gran poder conlleva una gran resposabilidad. Me da la impresión de que esta técnica hay que aplicarla con cuidado y cariño o puede causar caos y destrucción.
» Leer más, comentarios, etc...
Arragonán
Elecciones al Congreso en Arredol
Noviembre 23rd, 2011 - [Enlace local]
Como publiqué en twitter el mismo domingo del 20-N (el día de las elecciones, vamos
), colaboré con Arredol, un pequeño diario online publicado en aragonés, desarrollando las gráficas de los resultados electorales a las elecciones del congreso español.
Fue un desarrollo exprés, ya que tenía otros compromisos que no podía dejar de lado. Fueron unas 6 o 7 horas de trabajo a tope ese mismo fin de semana, pero me apetecía colaborar por fin con algún medio, aunque fuera tan pequeñito como lo es arredol
.
Herramientas utilizadas:
- El API que puso a disposición El País. Que básicamente hizo el trabajo que según los que defendemos el OpenData debería ser responsabilidad del Ministerio del Interior, poner a disposición de cualquier persona o entidad esos datos de forma estructurada para poder procesarlos.
- El API de Google Charts para las representaciones gráficas. No pude adaptar los colores por partido por las limitaciones que tiene, o al menos no logré dar con la solución.
- En el lado del servidor PHP y simplexml para procesar la información de El País. Básicamente por que el hosting de arredol sólo soporta php, no por otra cosa en especial.
Como podréis comprender, por haber sido un pequeño desarrollo hecho a toda prisa, el código en general es muy mejorable; pero el resultado cara al usuario creo que no está del todo mal.
Seguramente fuera una solución muy alejada de las herramientas de visualización de algunos grandes medios de comunicación, con una posibilidad de interacción mucho mayor. Pero en Aragón quizás fuera de lo mejor, cosa que casi me entristece.
No vi que tuviera mucho que envidiar a lo que vi que hicieron por ejemplo en la web de Heraldo, y no digamos de El Periódico de Aragón donde no vi nada especial para la ocasión… Supongo que no dedicarían muchos esfuerzos…
» Leer más, comentarios, etc...
El blog de pico.dev
Apache Tapestry 5.3 publicado (Notas de publicación)
Noviembre 23rd, 2011 - [Enlace local]


Documentación
La ya buena documentación que existía ha sido mejorada y ampliada con nuevas secciones. Así tenemos un tutotial con el que los usuarios que estén empezando les resulte más fácil la tarea, incluye las herramientas a utilizar, las dependencias, como emepezar una aplicación rápidamente utilizando el archetype de maven y un par de ejemplos sencillos para empezar a hacer algo asi como usar Tapestry con Hibernate. También se ha añadido una sección de recetas sobre como hacer cosas habituales en muchas aplicaciones. También se ha añadido una sección de preguntas frecuentes y unas páginas de consulta para características de uso habitual (Application Module Class Cheat Sheet, Component Cheat Sheet).
Alertas
Tapestry ahora tiene un mecanismo central para manejar las alertas de usuario. Esto incluye el servicio AlertManager y el componente Alerts. Simplmente añade el componente Alerts a tu layout estandar y Tapestry se encarga del resto. Las alertas se pueden añadir tanto en las peticiones tradicionales como en las peticiones Ajax y pueden ser transitorias (se muestran durante unos segundos), normales o fijas (se mantienen entre peticiones hasta que el usuario las elimina expresamente haciendo clic). Las alertas pueden ser de tres severidades: info, advertencia (warn) y error. La apariencia puede ser personalizada sobreescribiendo las reglas CSS de Tapestry.
Salida de comentarios
Ahora es posible que Tapestry emita comentarios de salida. Esto son comentarios (como <!--BEGIN Index:loop (context:Index.tml, line 15)-->) que ayudan a depurar las etiquetas de salida en la parte del cliente. Esto se habilita para todas las peticiones que usen el símbolo de configuración «tapestry.component-render-tracing-enabled» y pueden ser añadidas a cualquier petición añadiendo el parámetro «t:component-trace=true» a la URL. Esto aumenta significativamente el tamaño de las etiquetas de salida pero puede ser muy útil con layouts compejos para determinar que componente es el responsable de cada porción de la página.
Contribuciones de servicio adaptables
Al hacer contribuciones a un servicio ahora no se está limitado a contribuir un valor que sea asignable al tipo asociado con la configuración. Objetos de cualquier tipo pueden ser contribuidos y el servicio TypeCoercer será usado para transformar el valor al tipo de la configuración (Ver documentación TypeCoercer).
Mejoras en la depuración de componentes
Dada la forma en como Tapestry instrumentaba las páginas y componentes usar un depurador ha sido dificultoso con las clases de páginas y componentes, cualquier campo mutable muestra su valor por defecto en el depurador independientemente de que haya sido escrito en el campo o leído de él. En el modo desarrollo de Tapestry 5.3 los valores ocultos leen de y escriben a esos campos en los propios campos (esto también ha sido corregido en la rama de mantenimiento 5.2.5). Este ocultamiento no ocurre en el modo producción para evitar potenciales pérdidas de memorias.
Recarga deshabilitada en producción
Desde ahora no se buscan cambios en los archivos de clases, plantillas o catálogos de mensajes en el modo producción. Es asumido que las aplicaciones Tapestry son empaquetadas en archivos WAR en producción y que cambiar el archivo WAR causa que el contenedor de servlet redespliegue la aplicación entera. Este cambio mejora el rendimiento y reduce el consumo de memoria en las aplicaciones.
JavaDoc Tapestry
Tapestry ahora incluye una nueva librería , tapestry-javadoc, que reemplaza el antiguo componente de informes basado en Maven. Simplemente poniendo una anotación @tapestrydoc en el JavaDoc de los componentes Tapestry generará la documentación completa como parte del JavaDoc... no mas cambios entre el JavaDoc y el informe del componente generado por Maven y no mas dependencia en Maven para la documentación de los componentes. Los estilos del JavaDoc han sido adaptados a los colores del proyecto.
Template skinning
Tapestry añade la posibilidad de personalizar y/o tematizar («skin and/or theme») las páginas o componentes. Es una extensión de como Tapestry gestiona las páginas por locale pero añade ejes definidos por aplicación además de reglas para encontrar recursos. Ver ComponentResourceSelector y ComponentRequestSelectorAnalyzer.
También hay un nuevo componente Dynamic el cual usa una plantilla externa (no una plantilla de Tapestry) que puede ser seleccionada en tiempo de ejecución.
Mediante esta funcionalidad ahora la plantilla que se aplica para una página o componentes no solo vendrá determinado por el locale de la aplicación sino que podremos introducir más variables en la elección. Una de ellas podría ser el tipo de cliente, como por ejemplo un dispositivo móvil del que hace la petición u otros criterios para asi mostrar contenido más adaptado o personalizado.
En el siguiente enlace de puede ver una demostración de como aplicar la funcionalidad Template Skinning.
Evento de formulario cancelado
Los componentes de formulario ahora reconocen cuando el formulario de la parte cliente fue cancelado. Un nuevo evento «cancelled» es disparado al principio del proceso de envío lo cual permite a la página saltar todas las actualizaciones y validaciones en el servidor cuando sea lo deseado.
Restricciones implicitas en OrderedConfiguration
Al usar OrderedConfiguration.add() sin restricciones Tapestry ahora implicitamente ordenará el elmento añadido después del elemento añadido anteriormente dentro del mismo método. En versiones anteriores esos elementos eran añadidos sin restricciones. Esto hace más fácil contribuir un grupo de elementos relacionados con un orden implicito.
Nuevas validaciones de las clases de componente
Tapestry incluye nuevas validaciones de clases de componente para ayudar a reducir algunos errores comunes. Ahora comprueba que los componentes referenciados por un manejador de eventos concuerde con un componente definido en la plantilla... esto identifica rápidamente errores tipográficos en los nombres de métodos. Esto es, si la firma de un manejador de evento es «onFormularioRegistroSubmit()» se comprueba que exista en la plantilla un componente de id «FormularioRegistro». Esta comprobación puede ser deshabilitada con un símbolo de configuración de tal modo que aplicaciones 5.2 existentes que tengan este tipo de errores todavía puedan funcionar (esto es, tendrá manejadores de eventos muertos que nunca serán invocados).
Carpeta de aplicación
Tapestry ahora puede ser configurado para ejecutarse dentro de una carpeta, lo cual puede ser útil cuando se ejecuta dentro de una aplicación web que contiene otros servlets y filtros como una forma de prevenir conflictos. En vez de ejecutarse en la raiz del contexto de la aplicación.
Mejorado el arquetipo de inicio rápido
El arquetipo de Maven ha sido actualizado y ahora muestra varias nuevas funcionalidades de uso común. Además añade soporte para Gradle (Referencia). La forma de usarlo desde la linea de comandos es:
$MAVEN_HOME/bin/mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org/
Páginas blancas
La nueva anotación @WhitelistAccessOnly marca una página como accesible solo por una lista blanca de clientes. Las reglas para la lista son extensibles. La regla por defecto de la lista blanca es que sea accedida desde 127.0.0.1. Usa esta anotación en páginas que pueden exponer datos sensibles como paneles informativos incorporados.
Catálogo de página
Las aplicacicones Tapestry incluyen una página PageCatalog la cual lista todas las páginas cargadas de la aplicación con detalles acerca de su tiempo de construcción y número de componentes. La página requiere acceso en la lista blanca (ver en comentario anterior). Muestra alguna información que solo está disponible en el modo desarrollo. PageCatalog puede ser usada para cargar todas la páginas de la aplicación lo cual es útil para localizar problemas en las páginas... y es especialmente útil al aumentar de una versión anterior de Tapestry.
Otra página de la que podemos obtener información acerca de los servicios de la aplicación es ServiceStatus donde podremos ver el estado de los mismos.
Logging en la parte ciente JavaScript
La consola en la parte cliente Blackbird ha sido eliminada. En su lugar están los mensajes de la consola flotante combinada con el logging a la consola de Firebug o WebKit. Tapestry no captura más las excepciones de JavaScript de inicialización de modo que pueden ser informadas apropiadamente en la consola nativa. Estos cambios deberían hacer la depuración de JavaScript en el lado cliente mucho más fácil.
El informe de error es una de las cosas buenas de Tapestry. Con esta nueva versión esta característica se ha extendido a las peticiones Ajax con lo que cuando se produzca una excepción en el servidor se nos mostrará un informe en una ventana emergente con un contenido similar a las excepciones de las peticiones normales. En este screencast se puede ver en funcionamiento.
Otra lista de novedades no mencionadas en la notas de lanzamiento oficial:
Nuevos componentes
Se han añadido unos cuantos nuevos componentes al los ya presentes en el core. Estos son:
- KaptchaImage / KaptchaField: Permite evitar el spam en los formularios.
- Tree: componente ábol que pemite mostrar información jerárquica con nodos expandibles, contraibles y seleccionables. Es personalizable y basado en Ajax.
- Checklist: componente de selección multiple consistente en diferentes checkbox.
Nueva capa de abstracción JavaScript
En estos momentos Tapestry está atado a Prototype y Scriptaculous por compatibilidad con anteriores versiones (aunque se puede utilizar perfectamente junto con otros frameworks javascript como jQuery). En un futuro la nueva capa capa de abstracción permitirá usar cualquier librería JavaScript. La transición se completará en la versión 5.4.
Soporte Ajax mejorado
La clase MiltiZoneUpdate ha sido marcada como obsoleta en favor del servicio AjaxResponseRenderer. Esta nueva clase permite actualizar una zona con el contenido de Block, Component u otro objeto capaz de ser convertido a RenderCommand. Permite además importar una librería JavaScript como parte de la respuesta Ajax y añadir una llamada a una función en el lado del cliente, útil y a veces necesario para procesar la petición Ajax correctamente.
Integración con JSR 330 (Dependency Injection for Java)
Empezando desde Tapestry 5.3 es posible usar las anotaciones que define la especificación JSR-330 en la capa de servicios de tal modo que no dependan de Tapestry.
Integración JPA2
Integración nativa con JPA2 proporcionando compatibilidad hacia atrás en futuras versiones y posibilidad de usar múltiples unidades de persistencia en la misma aplicación. Permite configurar JPA sin necesidad de XML.
Herramienta construcción, Gradle
Tapestry ha pasado de utilizar Maven a usar Gradle como herramienta de contrucción y compilación para el propio proyecto. Gradle aporta nuevas funcionalidades, simplifica otras y evita algunos de los aspectos menos deseables de Maven.
Actualización Jumpstart
Actualizada la aplicación de referencia Jumpstart a la versión 5.3 con numerosos ejemplos que muestran funcionalidades, y con la posibilidad de ver el código fuente de esos ejemplos.
Otras
- Incorporación de Underscore.js que añade programación funcional a JavaScript (en modo no conflicto).
- Coercion de String-a-Enum sin necesidad de hacer una contribución en el contenedor IOC.
- Compresión JavaScript y CSS a través de de la librería YUICompressor library.
- Más rápido y más eficiente en uso de memoria.
Cambios disruptivos
- Tapestry depende ahora del Servlet API versión 2.5 con lo que la versión mínima para ejecutarlo ahora será Tomcat 6.0+.
- Actualizado Prototype a la versión 1.7.
- Las plantillas sin son tratadas como si tuvieran el doctype de HTML5 () pudiendose usar entidades como © o sin ver errores de parseo de anteriores versiones.
- Entorno RenderSupport (reemplazada con el entorno JavaScriptSupport).
- El objeto MultiZoneUpdate, reemplazada con AjaxResponseRenderer.
- El servicio ClassFactory y la interfaz ClassFab (reemplazada con el servicio PlasticProxyFactory y la interfaz PlasticClass).
- La funcionalidad "suppress redirects", que permitía a los eventos de los componentes responder directamente con HTML, como en Tapestry 4.
Y una lista larga de corrección de errores y mejoras. La lista completa está en las notas de publicación de tapestry 5.3 oficiales y aquí una lista de novedades en inglés.
Referencia:
http://tapestry.apache.org/index.html
http://tapestry.apache.org/download.html
Documentación sobre Apache Tapestry
Motivos para elegir el framework Apache Tapestry
» Leer más, comentarios, etc...
Variable not found
[Auges] ASP.NET MVC + HTML5 + CSS3 + JQuery = La unión perfecta
Noviembre 23rd, 2011 - [Enlace local]
Lo primero, para el que aún no lo sepa, se ha cancelado por causas de fuerza mayor la charla de Luis Ruíz Pavón sobre inyección de dependencias en ASP.NET que estaba prevista para el próximo martes 29 de noviembre. Sentimos las molestias que esto pueda causar, pero lo primero es lo primero :-).
Sin embargo, como ya teníamos el cuerpo hecho a aprender cosas interesantes la semana que viene, tendremos el placer de contar con el gran Marc Rubiño, MVP en ASP.NET y fundador de LoNetCamp, que nos mostrará el lunes 28 de noviembre a las 19:00h (horario peninsular español) la potencia que aporta la unión de tecnologías como ASP.NET MVC, HTML5, CSS3 y JQuery.
Descripción del evento:
Como siempre, podéis asistir desde casa o el trabajo (es un Webcast online), y la asistencia al evento es totalmente gratuita. Para acceder, simplemente debéis registraros en la siguiente dirección:ASP.NET MVC + HTML5 + CSS3 + Jquery = La unión perfecta
Las aplicaciones web modernas nos exigen cada vez más utilizar estándares para dotar a nuestra aplicación de una vistosidad y usabilidad nunca visto hasta el momento. Con ASP.NET MVC podemos separar las responsabilidades de nuestra aplicación de una forma sencilla y con HTML5 y CSS3 podemos obtener los mejores resultados independientemente del navegador gracias a librerías como modernizr.
En este Webcast lo que veremos es cómo de una forma totalmente práctica y con Visual Studio 2010 podemos crear una aplicación web totalmente funcional.
¿Qué utilizaremos en esta práctica?
ASP.NET MVC v.3: Es una plataforma gratuita, Open Source y está incluida en .NET 4.0. Nos sirve para realizar aplicaciones ASP.NET utilizando el patrón MVC, separando las responsabilidades ofreciéndonos beneficios como desarrollo orientado a pruebas “TDD”, mejor soporte de SEO con URLs más limpias, etc.
HTML v.5: La quinta revisión del veterano HTML no finalizada, pero los navegadores se han lanzado a una lucha frenética para adaptar sus especificaciones. Esta versión ha tenido en cuenta las nuevas necesidades y nos ofrece una web semántica.
CSS3: La tercera revisión de la hoja de estilos en cascada, que nos permite separar la estructura del documento de su presentación.
JQuery: Librería script que encapsula la complejidad de JavaScript y nos permite realizar animaciones, interactuar con el DOM y extender la aplicación de una manera muy sencilla y viene incluido en los proyectos ASP.NET MVC.
Modernizr: Librería que nos permite validar si el navegador soporta alguna de las nuevas funcionalidades de HTML 5 y nos permite actuar en consecuencia. Para hacer nuestra aplicación realmente cross-browser.
Ah, y los que ya teníais la fecha del 29 reservada para disfrutar con un Webcast de categoría, recordaros que ese mismo día podéis encontrar a Lluis Franco, MVP C# y un fenómeno de la naturaleza, hablando sobre programación paralela en SecondNug, a las 19:30h (GMT+1).Buena semana de eventos tenemos por delante, ¿eh?
Publicado en: Variable not found.
» Leer más, comentarios, etc...
Escuela De Codigo
Framework, el mejor amigo del programador
Noviembre 23rd, 2011 - [Enlace local]
Hace unos meses atrás me vi envuelto en un proyecto de mediana complejidad, se trataba de desarrollar un plugin para WordPress, a simple vista no parecía nada complicado así que me lo fui tomando con calma y ahi empezó mi martirio, los tiempos se me fueron haciendo mas pequeños y los requerimientos mas grandes, las tareas se me aglutinaba y dos manos ya no eran para nada suficiente para completar el proyecto, asi que decidí ”subcontratar” a alguien mas pero, la ley de Murphy se cumplia al pie de la letra y las cosas seguían de mal en peor…hasta que…tome una decisión…voy a utilizar un framework!! Vi la luz y fui feliz, recupere semanas de tiempo mal invertido y en un par de horas estaba de nuevo con una gran sonrisa mostrando el demo a mi cliente. Un framework de desarrollo rápido me salvo la vida.
¿Framework?
Si estas con una cara de “este tipo cada día trae unas sus palabritas todas raras” es porque no conoces la definición de la palabra “framework” dejame auxiliarme de la wikipedia para ilustrarte
Es una estructura conceptual y tecnológica de soporte definido, normalmente con artefactos o módulos de software concretos, con base a la cual otro proyecto de software puede ser más fácilmente organizado y desarrollado
¿Aun sin digerirlo? Ok, toma 2: Framework es un conjunto de librerías, códigos, programas y demas cosas que te permiten tener una base suficiente para poder iniciar el desarrollo de tus aplicaciones no desde cero sino que con algo de camino recorrido.
Espera, ¿significa que tengo que usar código de otra persona?
Si,un framework básicamente es el codigo que otro desarrollador (o comunidad de desarrolladores) ha creado para resolver un problema especifico y que pone a disposición de los demas porque cree que así como a el le funciono, nos puede funcionar a nosotros también.
¿No te gusta utilizar código de alguien mas? Se me vienen a la mente un par de clásicas excusas para no utilizar un framework.
- Solo Dios y los angeles sabe que cochinada de código a la que me voy a enfrentar
- No tengo ni idea porque han hecho esto asi, lo hare a mi modo mejor
- No tengo tiempo de andar aprendiendo como otro hace sus cosas, usare mis scripts
- Un verdadero programador de pelo en pecho no anda usando código de otro, lo hace el TODO por su cuenta!
- Mi problema es demasiado unico y puntual, la mejor solución es hacer algo a la medida.
- A mi me gusta hacer todo a mi manera
- Si surge un problema quien me va a ayudar a resolverlo?
- Nada como lo viejo conocido (mis propios programas y código)
Si eres un programador con fobia a usar código de otro, dejame mostrarte que no hay nada que temer, que utilizar un framework te dara una gran ventaja competitiva y te permitira desarrollar mas velozmente.
Que gano utilizando un framework
- Un buen comienzo, iniciar un proyecto o desarrollo tiene una parte muy difícil (y aburrida): el inicio. Preparar cada librería a usar, adaptar ese código fuente de ese otro proyecto para hacerlo funcionar en el nuevo, etc. Hacer eso una y otra vez, es repetitivo, te roba tiempo y te quita la diversión. La mayoría de frameworks te proveen de toda una estructura para tu aplicación para que con unos pocos clicks ya tengas algo funcionando.
- Estandarizacion, cada cosa en su lugar, los frameworks te indican donde debe ir cada parte de tu aplicación.
- Desarrollo Rápido, con tanto código ya hecho, tanta funcionalidad ya implementada, tutoriales, internet y sin fin de ayuda que puedes encontrar en la red es imposible que no tengas una primera version de tu aplicación en cuestion de horas sino es que menos!
¿Cual utilizar?
Ahora que sabemos lo que es un framework, las ventajas que implican utilizarlo (ya no hay excusas), surge la pregunta ¿¿¿y cual utilizar??? Porque framework hay de todo tipo, sabor y color, para multiples propósitos y en cuanto lenguaje de programación que el hombre halla inventado asi que la diversidad no sera problema. Pero, para limitarnos un poco y siendo congruentes con los lenguajes de programación que recomiendo les dejo mi top five de frameworks orientados al desarrollo de aplicaciones web que no debes dejar de aprender.
GRAILS
Grails es un framework para aplicaciones web libre desarrollado sobre el lenguaje de programación Groovy (el cual a su vez se basa en la Java platform). Grails pretende ser un marco de trabajo altamente productivo siguiendo paradigmas tales como convención sobre configuración o no te repitas (DRY), proporcionando un entorno de desarrollo estandarizado y ocultando gran parte de los detalles de configuración al programador.
Escrito en Groovy, corriendo en la plataforma Java, Grails es como el hermano que Rails nunca tuvo (y de seguro nunca quizo tener), hereda todo lo bueno de Rails (no te repitas, convención sobre configuración, scallfolding, etc) y tiene todas las ventaja que provee la plataforma Java. Si creíste que desarrollar aplicaciones web en Java era aburrido, mortificante e increiblemente lento, Groovy te mostrara que no es así.
http://grails.org/Installation
http://es.debugmodeon.com/articulo/introduccion-a-grails
YII
Yii es un alto rendimiento framework PHP mejor para el desarrollo de aplicaciones Web 2.0.
Framework para PHP, el cual personalmente amo mucho porque me saco de un apuro con un cliente, sencillamente tiene un generador de código hermoso y una comunidad muy activa en documentación. Si lo tuyo es programar en PHP, Yii debe formar parte de tu navaja suiza de desarrollador.
http://www.yiiframework.com/doc/guide/
http://caraballomaestre.blogspot.com/2011/05/por-que-yii-framework.html
RUBY ON RAILS
Ruby on Rails, también conocido como RoR o Rails es un framework de aplicaciones web de código abierto escrito en el lenguaje de programación Ruby, siguiendo el paradigma de la arquitectura Modelo Vista Controlador (MVC). Trata de combinar la simplicidad con la posibilidad de desarrollar aplicaciones del mundo real escribiendo menos código que con otros frameworks y con un mínimo de configuración.
El mas famoso, el mas querido, el que dicen inicio una revolución en el desarrollo web, abanderado del desarrollo rápido de aplicaciones. Escrito en Ruby, creado por 37Signals, se han escrito mares y mares de las bondades de este framework asi que no seguire aumentando las alabanzas, solo dare una recomendacion: aprende Rails te divertirás!
http://guides.rubyonrails.org/
SINATRA
Sinatra es un DSL para crear aplicaciones web rápidamente en Ruby con un mínimo esfuerzo
Que dijeras si te contara que puedes hacer toda una aplicación web con un par de lineas de código y en un único archivo de código fuente. Sinatra permite eso. Ideal para introducirte en el mundo de Ruby y crear prototipos y aplicaciones desde pequeñas a medianas.
http://www.sinatrarb.com/intro-es.html
http://sinatra-book.gittr.com/
JQUERY
jQuery es una biblioteca de JavaScript, que permite simplificar la manera de interactuar con los documentos HTML, manipular el árbol DOM, manejar eventos, desarrollar animaciones y agregar interacción con la técnica AJAX a páginas web
Y sin olvidarnos del otro lado del monitor, JQuery un framework javascript que permite dotar a tus aplicaciones de todo esa funcionalidad tan chula y popular de estos tiempos (Ajax, Drag on Drop, etc, etc)
http://www.w3schools.com/jquery/default.asp
http://net.tutsplus.com/articles/web-roundups/jquery-for-absolute-beginners-video-series/
Los frameworks son tus amigos, te facilitan la vida, te ahorran tiempo y te hacen mas productivo, definitivamente tienes que aprender mas de uno.
» Leer más, comentarios, etc...
Picando Código
The Humble Introversion Bundle
Noviembre 22nd, 2011 - [Enlace local]
ACTUALIZACIÓN 29/11 - Con más de 140.000 paquetes vendidos, y unos U$S 500.000 recaudados, se actualizó el Humble Introversion Bundle. A lo ya posteado más abajo, se agregó un nuevo juego: Dungeons of Dredmor (para quienes hayan pagado más del promedio). Liberación del código: Introversion está ofreciendo acceso al código fuente de sus juegos Darwinia, Multiwinia, DEFCON y Uplink a los clientes del Humble Bundle. Al comprar los juegos, obtenemos acceso al servidor SVN, la wiki y el foro de desarrollo.
Todavía no terminé de disfrutar al máximo los juegos del Humble Voxatron Deluxe, y ya se lanzó un nuevo bundle: The Humble Introversion Bundle. Como todos los bundles recientes, este cuenta con sus peculiaridades.
En esta edición el paquete de juegos es protagonizado por el estudio Introversion Software. Se trata de un estudio de desarrollo de videojuegos independiente del Reino Unido. Fue fundado en 2001 por tres estudiantes universitarios y los juegos ofrecidos por el estudio son Uplink, Darwinia, DEFCON y Multiwinia.
Además, se continua la estrategia de ediciones anteriores para subir el promedio de donación por persona: Aquellos que superen el precio promedio (en estos momentos U$S 3.56) obtienen otro dos juegos: Aquaria (muy buen juego, incluido en el primer Humble Indie Bundle) y Crayon Physics Deluxe (incluido en el Humble Indie Bundle 3).
Como en todas las ediciones, los juegos son:
- De estudios independientes
- Multiplataforma (funcionan en Mac OS X, GNU/Linux y Windows)
- Sin DRM
- Podemos elegir cuánto pagar y repartir el dinero entre los desarrolladores, la caridad y Humble Bundle.
Como “bonus”, los desarrolladores incluyeron un par de prototipos a modo de demo, que solo funcionan en Windows. Subversion es una demostración de generación de procedimiento para crear un ambiente de ciudad y el segundo es un experimento con edificios de vóxeles.
Les dejo el video presentación, con el desafío de encontrar la referencia a CSI:
Visiten HumbleBundle.com
» Leer más, comentarios, etc...
Picando Código
Concurso de desarrollo de aplicaciones web
Noviembre 22nd, 2011 - [Enlace local]
Desarrollando América Latina es un concurso de desarrollo de aplicaciones web con datos públicos abiertos. El 03 y 04 de Diciembre, por 30 horas consecutivas, los mejores desarrolladores web de 6 países latinoamericanos (Argentina, Brasil, Chile, México, Perú, y Uruguay) se reunirán en sus respectivos países a trabajar para encontrar soluciones digitales a problemas sociales. Habrá importantes premios para los ganadores. Los cupos son limitados, y hay que inscribirse en el sitio del concurso http://desarrollandoamerica.org
A modo de ejemplo mencionamos algunas aplicaciones interesantes que se han desarrollado en otros países utilziando datos públicos abiertos:
- http://wheredoesmymoneygo.org/
- http://lookatcook.com/
- http://www.guardian.co.uk/data
- http://walkshed.org
Algunos puntos interesantes a tener en cuenta
¿Habrá comida gratis?
¡Si!
¿Habrá bebida gratis?
¡Si!
¿Habrá Wi-fi gratis y de buena calidad?
¡Si!
¿Y los premios?
El jurado eligirá las tres mejores aplicaciones. El primer lugar ganará $2,000 USD. El segundo lugar $1,000 USD. Y el tercer lugar $500 USD. Además cada equipo recibirá premios adicionales de nuestros colaboradores y sponsors. Este es un evento tanto nacional como regional. Por ende tendrás la oportunidad de competir en ambos niveles y ganarte un premio regional!
¡Premios regionales! ¿Cuáles son?
Las tres aplicaciones ganadoras de cada país calificarán para continuar al nivel regional, donde el jurado selecionará a las mejores aplicaciones de todo América Latina. Aparte de haber recibido los premios nacionales, las tres mejores aplicaciones a nivel regional ganarán unos premios impresionantes; la oportunidad de seguir desarrollando su aplicación con una organización especializada. Pronto publicarémos más información
¿Quiénes están patrocinando #DLA?
Nuestros patrocinadores principalse son Google, Omidyar Network, y Open Society Institutes. Pero muchas otras organizaciones e individuos estan apoyado este proyecto de distintas formas – contribuir con datos, poner los premios, difundir el evento, y más.
¿Quiénes organizan #DLA?
Este evento está presentado por la Fundación Ciudadano Inteligente, una organización Chilena sin fines de lucro. El evento también cuenta con el apoyo de otros organizadores – Wingu, GarageLab, W3C, Citivox, Fundar, Escuelab, y Cubox.
¿Tengo que desarrollar algo solo o puedo ser parte de un equipo?
Tú puedes elegir! Puedes trabajar sólo, por tu propia cuenta. Puedes armar tu propia equipo, creado por tus amigos superheroes. Puedes aprovechar el instante y conocer a gente nueva. La manera que mejor funciona para tí! Sin embargo, la construcción de un gran equipo permite dividir las responsabilidades entre los miembros y dedicar más tiempo a sus áreas más fuertes. Sin duda recomendaríamos que una combinación de desarrolladores y diseñadores. Ten en cuenta que los equipos no podrán exceder las 8 personas. Mínimo, 1 persona.
¿Qué datos se pueden utilizar?
Nosotros – los coordinadores de cada país – proveerémos los datos. Los datos estarán disponibles para el uso de los desarrolladores. Nosotros estamos preparando los datos con anticipación. Hemos estado trabajando por 3 meses en encontrar datos, limpiar datos, y subir los datos en un sitio central. Una semana antes del evento vamos a lanzar el catálogo de datos donde ustedes podrán ver las fichas de los datos.
¿A qué se refiere con “datos públicos”?
Los “datos públicos” se refieren a datos que han sido liberados para el público. Es decir que estos datos vienen de varios fuentes – el gobierno (de distintos niveles), la sociedad civil, y las organizaciones no gobermentales. Eso depende de la realidad de cada país. Unos países seguramente tendrán mejor sets de datos en seguridad, otros en educación.
Más información en http://desarrollandoamerica.org/
No duden en evacuar sus dudas por correo electrónico.
Agradecemos dar difusión al concurso.
¡Los esperamos!
Les dejo el video presentación del concurso:
» Leer más, comentarios, etc...
Variable not found
ASP.NET MVC: Introducir lógica personalizada al detectar errores de validación en cliente
Noviembre 22nd, 2011 - [Enlace local]
El sistema de validación en cliente de ASP.NET MVC, como sabemos basado en jQuery validate, es el encargado de mostrar u ocultar los mensajes de error asociados a cada campo conforme va comprobando su validez.
Los mensajes de error asociados a cada validador son almacenados inicialmente en atributos data-val-* sobre el control a comprobar, y cuando se detecta un problema de validación, son mostrados copiando su contenido al interior de la etiqueta <span> que el helper Html.ValidationMessage() habrá generado sobre la página.
Sin embargo, al hilo de una consulta reciente en los foros de ASP.NET MVC en MSDN, perfectamente contestada por el amigo Eduard Tomás, pensé que realmente tenemos poco control sobre cómo se muestran estos errores, así que me he puesto un rato a ver cómo podíamos conseguir introducir lógica personalizada en este punto aprovechando la flexibilidad que ofrece jQuery validate 1.9.
Salvo por la escasez de documentación de este componente, tomar el control en el momento de mostrar los mensajes de error es bastante sencillo. Basta con establecer una función en la propiedad showErrors de los settings del plugin, cosa que podemos hacer con el siguiente script de inicialización:
<script type="text/javascript">
$(function () {
var settings = $.data($('form')[0], 'validator').settings;
settings.showErrors = function (errorMap, errorList) {
// Aquí el código personalizado:
[...]
// Y si nos interesa, finalmente podemos
// ejecutar el comportamiento por defecto
this.defaultShowErrors();
};
});
</script>
(Por simplificar, estamos asumiendo que en el formulario hay un único tag <form>, que es el que capturamos con el selector).La función
showErrors() recibe dos parámetros. El primero es un “mapa” donde asociamos a cada clave (nombre del campo) el mensaje de error que tenga asociado. Así, por ejemplo, el valor de errorMap.Nombre será nulo si el campo “Nombre” del formulario no tiene ningún error (ha validado correctamente), o el texto del error en caso contrario.En el segundo parámetro de la función encontraremos un array con los errores a mostrar. En cada elemento tendremos disponible la propiedad
element, desde la que podemos acceder al control que ha generado el error, y message, donde podemos consultar o establecer la descripción del mismo.Es importante tener en cuenta que la función
showErrors() es invocada con mucha frecuencia durante el proceso de edición (pérdida de foco, obtención de foco, pulsación de teclas…), por lo que desde el punto de vista de la usabilidad no tiene demasiado sentido introducir en ella procesos bloqueantes (como puede ser un alert()) o demasiado largos en el tiempo, para evitar que se solapen.Por ejemplo, en el siguiente código utilizamos el efecto “highlight” de jQuery UI para resaltar con un rápido destello el elemento en el que se ha detectado un error:
settings.showErrors = function (errorMap, errorList) {
for (var i = 0; i < errorList.length; i++) {
var error = errorList[i];
// error.element es el elemento que ha provocado el error
$(error.element).effect("highlight", { times: 1 }, 100);
}
this.defaultShowErrors();
};
En fin, algo no demasiado útil ;-P, pero interesante en cualquier caso para profundizar un poco en los misterios e interioridades de jQuery validate.Publicado en Variable not found.
» Leer más, comentarios, etc...
Arragonán
Optimiza tus webs Grails. Greach 2011
Noviembre 21st, 2011 - [Enlace local]
Dejo aquí la presentación que hice en Greach 2011 sobre optimización de webs con Grails.
Y también el video
» Leer más, comentarios, etc...
Picando Código
JRuby: Introduciendo Ruby en un mundo enterprise – RubyConf Uruguay 2011
Noviembre 21st, 2011 - [Enlace local]
Sigo compartiendo mis impresiones de las charlas de la RubyConf Uruguay de este año. Esta vez les voy a hablar de la charla de Jano González.
La charla se dió durante la primera jornada, y le terminé dedicando un post entero por varias razones. En primer lugar, me sentí muy identificado con varias de las cosas que comentó al haber estado trabajando un par de años en Java y queriendo ahora migrar a Ruby. En segundo lugar, como escribí bastante al respecto, iba a quedar demasiado extenso para combinarla en otro post con más charlas.
Si todavía no lo hicieron, pueden ir y leer la primera parte de mis impresiones de RubyConf Uruguay.
Jano González (@janogonzalez), de Chile, ha sido desarrollador Java por 11 años, y Ruby por 1 año. Trabaja en la empresa Continuum en Santiago de Chile, y además de ser músico frustrado (me siento identificado
) también tiene un blog sobre Ruby – Gema Roja.
Jano tambien organiza las meetups de lenguajes dinámicos en Santiago de Chile, así que si van por ahí y les interesa, ya tienen un lugar por donde pasar a tomar un café.
JRuby: Introduciendo Ruby en un mundo enterprise
Su presentación fue una de las que más dió que hablar. En primer lugar porque el tema, “Java vs. Ruby” se vuelve entretenido cuando algunos lo tratan como una guerra santa más. Es irónico, porque en verdad la charla venía más por el lado de “Java CON Ruby”, pero en el peor de los casos, nos entretenemos con la discusión.
La competencia entre distintas tecnologías es necesaria, al mejorar una tecnología, los competidores se ven obligados a no quedarse atrás. Es así que varios frameworks Java han adquirido cosas de Rails. Al contar con un ecosistema tan rico, ambas tecnologías se alimentan y se vuelve algo tonto pero sobretodo innecesario, creo, la “pelea”.
Tengo que decir que la charla fue sumamente divertida, por lo que recomiendo a todos, sobretodo desarrolladores Java, que la miren en Eventials. Tuve el gusto de compartir varias cervezas con Jano en los drink-ups de Heroku y Github, y como le dije personalmente, lo contrataría para dar esta charla como espectáculo en una fiesta. Fue una mezcla de stand-up con charla técnica, muy buena.
Comenzó comentando el tema de haber desarrollado Java por 11 años, “es como estar casado con una mujer hace 11 años. La amo, pero ya conozco la mayoría de sus defectos.” Tuvo un enamoramiento con Ruby y pasó por una pequeña infidelidad a partir del año 2010. Habló un poco del mundo Enterprise contra los Startup más modernos donde los cambios se realizan de forma más ágil y la adopción de nuevas tecnologías es más aceptada. En el mundo Enterprise sin embargo, la relación con el cliente es más complicada y la adopción de tecnologías bastante lenta y tediosa (en general).
Habló de Java EE y frameworks como Spring, Hibernate, etc. su evolución e interacción y algo que los afecta: el exceso de complejidad. El ejemplo más claro que dió fue el AbstractSingletonProxyFactoryBean de Spring. Como dijo Jano, parecía tratarse de un concurso: “Meta tres patrones en uno y gane un iPad”.
JRuby
También habló de las ventajas de los frameworks y Java EE, pero la solución la vió en JRuby: “Llevemos Java al siguiente nivel, tomemos todo lo bueno pero apliquemos lenguajes que nos den felicidad, como Ruby”. Este es un tema bastante interesante en mi agenda, y ya estuve posteando al respecto en el blog: JRuby: Implementación de Ruby en la JVM.
Comparando Ruby con Java, dijo otra frase célebre que comparto con ustedes:
“Yo siempre he dicho que Ruby tiene la grasa necesaria para hacer sabrosa la carne. Java como que ya tiene mucha grasa, me está empezando a caer un poco mal al estómago.”
A continuación, algo que también me pasó al entrar al mundo Ruby, preguntarse “¿Dónde están mis interfaces?”. En Ruby no hay interfaces, se puede ver si un objeto responde a cierto método y tenemos mixins (algo muy increíble de Ruby, concepto en el que ahondaré en algún post más adelante), entre otras cosas.
También destacó la naturaleza de la orientación a objetos de Ruby, donde todo es un objeto. Mencionó los arreglos, hashes, rangos, expresiones regulares y lambdas (otra cosa a la que le vengo entrando de a poco recientemente y es super interesante), los bloques de código y map, select y reduce (de lo funcional). La facilidad de crear getters y setters con attr_reader (o attr_accessor), y la modificación de clases con Monkey Patching.
Por último, la gracia de JRuby es importar clases Java en Ruby, mostró un poco las formas de usarlo y mostró un ejemplo de código Volviendo a la comparación con Java, Jano propuso “Dime qué versión de Java usas y te diré quién eres”. Siendo Java 7 lo mejor del momento, Java 6 “Bien”, Java 5 “Bueno, ya…” y Java 1.4 o menor siendo el infierno.
Tácticas de “Guerra de guerrillas” para incorporar Ruby en el mundo Java empresarial
En principio usar jirb (consola interactiva de JRuby) como REPL (read–eval–print loop). Reemplazar Ant y Maven con Apache Buildr o Rake (|Ruby en vez de tanto XML”). Luego los scripts en general escribirlos en Ruby, y reemplazar JUnit y Selenium con RSpec y Cucumber. Todo esta primera fase es “personal” y el cliente no tiene por qué enterarse ya que no le afecta.
La segunda etapa sería con el cliente, reemplazando servicios REST con Sinatra. También crear DSLs para facilitar el uso de bibliotecas Java. Y “la guinda de la torta”, crear aplicaciones web con Ruby On Rails. Además del ejemplo de JRuby usando Ruby con clases Java Swing, mostró un poco de código de integración con Spring.
El deploy de las aplicaciones JRuby se puede hacer en cualquier appserver. Mencionó algunas herramientas importantes para la integración de Java JRuby: warble, una gema para crear jars o wars de una aplicación Ruby, Rails, Merb o Rack. Trinidad, una gema que permite ejecutar aplicaciones Rails en un contenedor Apache Tomcat embebido. Para algo más “Entreprise” existe también TorqueBox una plataforma de aplicaciones Ruby cuyo diagrama me dió escalofríos: está construído sobre JBoss AS y provee clustering, balance de carga y alta disponibilidad “out of the box”…
Para quienes usan Ruby, hay muchas bibliotecas interesantes como ROFLScale con Netty o Apache Mina, actores remotos con Akka, “bibliotecas menos interesantes pero que le van a interesar al cliente” como iPDF y POI para reportes con PDF y Excel sucesivamente. Y por último STM de Clojure para meterlo en JRuby.
Su conclusión: Se acabó la guerra. Java y Ruby pueden convivir felizmente. Pueden ver y descargar la presentación de Jano en SlideShare. Y dense una vuelta por su blog para seguir sus charlas y conocer un poco más sobre Ruby.
Al final hubo tiempo para preguntas del público. Al preguntarle sobre Scala, Jano contestó con una cita de Charles Nutter (principal desarrollador de JRuby): “Scala es el lenguaje omniparadigma, implementa cada paradigma de programación conocido por el hombre”. Su opinión personal: “Es un gran paso adelante por sobre Java. Podría ser más facil introducir Scala por sobre JRuby en la empresa”.
Como dije, me resultó muy interesante la charla, además de entretenida, y espero sus comentarios para ver qué les pareció la movida como para empezar a usar Ruby en un ambiente de trabajo Java.
» Leer más, comentarios, etc...
Variable not found
Enlaces interesantes 61
Noviembre 21st, 2011 - [Enlace local]
Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 21 al 27 de noviembre de 2011. Espero que os resulten interesantes. :-)
- C#/.NET Little Wonders: The Predicate, Comparison, and Converter Generic Delegates
James Michael - MVC Data URI HTML Helper
Dean Hume - Lazy Remote Validation with ASP.NET MVC 3
Pietro Brambati (vía @osotorrio) - Download Free eBook: Razor View Engine in MVC 3
Abhimanyu Kumar Vatsa (vía @lluisfranco) - Adding Personality with CSS3 Transitions and Animations
IEBlog - Modernizr.js: Polyfills
K. Scott Allen - Associations in EF 4.1 Code First
Morteza Manavi (vía @osotorrio) - Helpers para formularios (ASP.NET MVC)
Eduard Tomás (vía @JTorrecilla) - Web Platform Installer v4 command line (WebPICMD.exe) Preview Release
WebPICmd Team (Vía @wasat) - Microsoft Translator API
Juan María Laó (vía @lluisfranco) - Coffee delivers jolt deep in the brain
Laura Sanders - Getting Query Parameters in Javascript
Phubar Baz (!) - Contour Analysis for Image Recognition in C#
Greg Duncan - ReSharper Settings in 6.1
Hadi Hariri - Poster: What’s new in .NET Framework 4.5?
Heikniemi Hardcoded - Inserciones Masivas en MongoDB vs SQL Server (IV)
Pablo Doval - DDD: 2- Framework de IoC (Service Pack 1)
Omar del Valle - El nuevo objeto jQuery $.Callbacks()
Carlos Benítez - jQuery 1.7.1. released
jQuery Team - Crear un archivo .ZIP con JavaScript
Pablo Suárez (vía @osotorrio) - HTML5 Semantics
Bruce Lawson - Integrating JavaScript Unit Tests with Visual Studio
Stephen Walther - Embedding RavenDB into an ASP.NET MVC 3 Application
Justin Schwartzenberger - Aclarando CQRS [traducción]
Pablo Núñez & Co. - Task Support for Asynchronous Controllers in MVC 4
Malcolm Sheridan - Fechas UTC, JavaScript, jQuery timeago, templates y otras hierbas
Luis Ruiz Pavón - Saber si un elemento tiene un evento jQuery asignado
Sergio León - Bloquear los botones mientras se envía un formulario
José Manuel Alarcón - Agilismo Vs Modelo waterfall tradicional. Muy interesante y resumidito.
Juan Palacio - Desarrollo de una aplicación Metro en C# y XAML
Eduard Tomás (vía @Jtorrecilla) - Large-scale JavaScript Application Architecture
Addy Osmani - Aggregating RSS Feeds in C# and ASP.NET MVC 3
Wade Wegner - 6 Tips to Help You Build a Great Web Application
Greg & Adrian - Los nuevos métodos jQuery on() y off()
Carlos Benítez - DDD: 2- Framework de IoC (parte 1) y DDD- 2- Framework de IoC (parte 2)
Omar del Valle - HOT:Inserciones masivas en Sql Sersver vs Mongo DB (III)
Unai Zorrilla
Publicado en Variable not found


























