Mutabilidad en Java

Publicado en Java el 25 de February, 2008 por Lek. (14 comentarios)

En Java se supone que todos los parámetros de una función se pasan por valor, pero pronto descubres que no es así y si modificas un objeto dentro de una función, queda alterado desde el punto del código que llamó a dicha función. Por poner un ejemplo,

//Esta función modifica el valor de d
public Date getDate (Date d){
    //d = new Date(); ERRÓNEO
    d.setTime (d.getTime () + 5000);
    return d;
}

Esto se debe a una propiedad de los objetos denominada mutabilidad (de mutar, cambiar) y que podemos expresar de la siguiente manera:

  • Objetos mutables: Cuando tenemos una referencia a la instancia de un objeto y su contenido puede ser alterado
  • Objetos inmutables: Cuando tenemos una referencia a la instancia de un objeto y su contenido no puede ser alterado

Es una práctica común el incluir objetos mutables en una clase Java sin darnos cuenta, como hemos visto en el ejemplo (fechas, streams, arrays, objetos propios…). Puede ser muy útil o también muy molesto según la situación, pues el objeto es asignado directamente y operamos directamente sobre la misma instancia en todas las partes del código. La solución es crear una nueva instancia del objeto, tanto a la hora de asignar como a la hora de retornar los valores.

//Esta función no modifica el valor de d
public Date getDate (Date d){
    Date d2 = new Date(d.getTime());
    d2.setTime(d2.getTime () + 5000);
    return d2;
}

A continuación os pongo un enlace de lectura interesante, Mutable and Immutable Objects.

Vía Bellz, que lo expuso magistralmente en el blog interno de programación.

Actualización 22:14
Gracias a Federico Varela por recordarnos que el ejemplo era más inexacto que Java multiplicando doubles ;) En el primer ejemplo no se modificaba el valor de d al estar ya creando la nueva instancia en la función. Los he corregido para que sean exactamente lo que trataba de expresar en el post.

Accediendo al registro de Windows

Publicado en C/C++, Windows el 23 de February, 2008 por Fran. (Sin comentarios)

Desde hace ya unos años no tocaba Windows para nada, y de programar pues ni hablemos, desde la universidad en que programaba en PASCAL programas para la consola, no había vuelto a tocar nada relacionado con Windows, y menos programar en C sobre Windows (¡herejía!).

Pero por razones sobrenaturales (trabajo), he tenido que programar en C sobre Windows. Al principio me dieron el Visual Studio 2005 (o algo así), y nada más ver que usan su propia mierda para programar en C (¿dónde está el estándar ANSI o C99, señores?) y que realmente está más orientado a C++ que a C, me decidí a usar DevCpp que es libre, usa MinGW y puedo programar para Windows usando la API Win32, usando mi querido C estándar de toda la vida.

Después de este rollo que os he soltado, viene lo que pretendía contaros, y es cómo acceder al registro de Windows usando el lenguaje C. Puede parecer difícil, pero la verdad es que los señores de Microsoft tienen una buena cosa llamada msdn, en la que encuentras cualquier cosa siempre que sepas más o menos donde buscar. Para este caso podemos encontrar toda la información relacionada con el registro aquí.

Pero no os voy a dejar a la buena de dios, así que os voy a poner un pequeño ejemplo de como acceder a una clave del registro, para que podáis saber más o menos cómo funciona.

#include <windows.h>

const char *ruta_reg = "Ruta\\del\\registro";

char *get_clave (char *clave) {

	DWORD BufferSize = 2048;
	DWORD cbData;
	DWORD dwRet;
	DWORD regType;
	HKEY hkey;

	if (RegOpenKeyEx (HKEY_CURRENT_USER, TEXT (ruta_reg), 0,
				KEY_READ, &hkey) == ERROR_SUCCESS)
	{

		PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc (BufferSize);
		if (PerfData == NULL) {
			printf ("Error\n");
			return NULL;
		}
		cbData = BufferSize;

		dwRet = RegQueryValueEx (hkey, TEXT (type), NULL, &regType,
						(LPBYTE) PerfData, &cbData);

		/* Get a buffer that is big enough. */
		while (dwRet == ERROR_MORE_DATA) {
			BufferSize *= 2;
			PerfData = (PPERF_DATA_BLOCK) realloc (PerfData, BufferSize);
			if (PerfData == NULL) {
				printf ("Error\n");
				return NULL;
			}
			cbData = BufferSize;

			/* Conseguimos el valor de la clave */
			dwRet = RegQueryValueEx (hkey, TEXT (clave), NULL, &regType,
							(LPBYTE) PerfData, &cbData );
		}

		/* Error */
		if (dwRet != ERROR_SUCCESS) {
			printf ("Error\n");
			return NULL;
		}

		printf ("%s\n", (char *) PerfData);

		return (char *) PerfData;
	}

	return NULL;
}

Sólo tenéis que cambiar la constante ruta_reg por una válida (que sea de HKEY_CURRENT_USER, ya que creo que si no eres administrador no puedes acceder a otra) y pasar como parámetro clave el nombre de la clave de la que queremos conocer su valor.

10 años de XML

Publicado en Noticias el 14 de February, 2008 por Lek. (4 comentarios)

El domingo el lenguaje de marcado XML cumplió 10 años. En este tiempo se ha convertido en un elemento habitual para casi cualquier tipo de programa. Desde ser la base del protocolo de comunicación entre programas hasta definir la configuración de los mismos… pasando por ser el lenguaje en que se envía la información. Es quizá este último punto donde XML ha mostrado su peor cara, especialmente debido a que la peña no lo sabe usar.

Burradas como abrir una sección CDATA e insertar un fichero con la información marcada por posiciones, o el envío de más de 70 megas de información con los problemas de parseado que eso supone, son sólo 2 ejemplos que me vienen a la cabeza sin mucho esfuerzo.

Y aunque XML será el estándar de facto dentro de otros 10 años, no le faltarán competidores. En el artículo original mencionan JSON y últimamente yo he oído hablar del Glimmerized XML.

Animaos, contadnos vuestras experiencias dantescas con XML y si habéis probado alguna de las alternativas que ya existen… o existirán (¡¡primicia mundial!!)

Vía JavaHispano

The Practice Of Programming

Publicado en Libros el 8 de February, 2008 por Fran. (1 comentario)

The Practice Of ProgrammingThe Practice Of Programming (web) o, en español, La práctica de la programación es un libro escrito por dos grandes maestros de la programación, como son: Brian W. Kernighan y Rob Pike (de los que seguro hablaremos por aquí algún día).

Este libro proporciona sugerencias y técnicas para que el programador pueda mejorar su habilidad, y sobre todo realizar sus tareas más eficientemente. En él aparece poco código, ya que se orienta más a dar consejos sobre como solventar ciertos problemas que suele tener todo programador.

Para mí es un libro muy recomendable, ya que aunque muchas de las sugerencias y/o consejos que proporcionan los conocía, no está de más revisarlos y ver cómo, personas de la altura de estos maestros, trabajan y te aconsejan en diferentes aspectos, además de siempre aprender algo nuevo.

Para que os hagáis una idea de los temas que tratan os pongo el índice:

  1. Estilo
  2. Algoritmos y estructuras de datos
  3. Diseño e implementación
  4. Interfaces
  5. Depuración
  6. Pruebas
  7. Rendimiento
  8. Portabilidad
  9. Notación

Creo que es un buen libro para alguien que acabe de aprender a programar y quiera meterse más de lleno en este apasionante mundo, de hecho querría haber sabido de este libro bastante antes.

Recomendación: Alta.
Nivel: Medio.
Idioma: Español (aunque yo lo leí en inglés).