viernes, 20 de diciembre de 2019

Microsoft y Linux

Que Microsoft ofreciese productos "open source" era impensable hace 10 años. Que además fuese un buen software, más impensable todavía.

Y aquí estamos, a las puertas de 2020, con Microsoft contribuyendo en el kernel de Linux y ofreciendo herramientas "open source".

sábado, 12 de octubre de 2019

Receta: migrar un Wordpress a localhost sin plugins

Situación típica: te encuentras con un blog en Wordpress "legacy", sin actualizar, o con muchos cambios por hacer. Es necesario echar a correr el blog en otro servidor (o mismamente en localhost).

Receta rápida

En el servidor donde corre:

1) Copiamos el árbol de directorios tal cual, mejor en un archivador:
/var/www/ $ tar cf blog-migrar.tar blog/
Ahora nos llevamos el .tar a nuestra máquina y lo descomprimimos el directorio web.

2) Volcamos la base de datos:
/var/www/ $ mysqldump -u usuario -p -h hostBaseDatos BaseDatosWordpress > BaseDatosWordpress.sql

3) Corregimos las referencias en la base de datos. Supongamos que la URL base del blog es www.webviejuna.com y que lo vamos a echar a correr en un servidor de desarrollo que será localhost.www.webviejuna.com (sin HTTPs). Hay que sustituir todas las apariciones de "www.webviejuna.com" por "localhost.www.webviejuna.com" en el SQL generado. Se puede hacer con sed o en el editor de textos si el archivo sql no es muy grande y el editor de texto no se queda frito.

4) Creamos la base de datos en el servidor de desarrollo, le damos permisos y cargamos el SQL que acabamos de modificar en el servidor de desarrollo:
$ mysql -u usuarioSuper -p  -e "CREATE DATABASE BlogPrueba;"
$ mysql -u usuarioSuper -p  -e "GRANT ALL PRIVILEGES ON BlogPrueba.* TO 'usuariotest'@'localhost' IDENTIFIED BY 'pass';"
$ cat BaseDatosWordpress.sql | mysql -u usuarioSuper -p BlogPrueba


5) Editamos el wp-config.php para cambiar los parámetros de conexión, apuntando a la base de datos local. Ojo con las posibles personalizaciones (por ejemplo, constantes como WP_CONTENT_URL, o ajustes como $_SERVER['HTTPS'] = 'on')

6) Muy útil en desarrollo. En wp-config.php:
define('WP_DEBUG', isset($_GET['debug']) && $_GET['debug'] == '1');
Así activamos el modo debug a demanda poniendo debug=1 como parámetro en la URL.


viernes, 20 de septiembre de 2019

lunes, 15 de abril de 2019

Cuando unos leguajes tratan los arrays por referencia y otros por copia

¿Qué ocurre cuando asignamos un array a otro? En la mayor parte de los lenguajes, lo habitual es que la nueva variable sea un puntero (referencia) al primer array. Por ejemplo, en Python:

array2 = array1 = {'uno': 1, 'dos': 2}

print('array1 antes:', array1)
print('array2 antes:', array2)

array2['dos'] = 22
array1['tres'] = 3

print('array1 después:', array1)
print('array2 después:', array2)


La salida de este script sería la siguiente:

~ $ python3 testarray.py 

array1 antes: {'uno': 1, 'dos': 2}
array2 antes: {'uno': 1, 'dos': 2}
array1 después: {'uno': 1, 'dos': 22, 'tres': 3}
array2 después: {'uno': 1, 'dos': 22, 'tres': 3}


Como era previsible, al cambiar algo en array1 o en array2, el otro array se modifica, porque las dos variables son una referencia al mismo array. (En Python a este tipo de datos se le llama diccionario, pero podemos asumir que es equivalente al array asociativo de PHP)

Este sencillo ejemplo es muy adecuado para explicar a alguien lo que son las referencias. Se ve claramente que cambiar algo en una variable tiene efectos colaterales.

Sin embargo, podemos encontrarnos sorpresas en otros lenguajes. PHP, por ejemplo, copia el array en la nueva variable y a partir de ese momento, son dos referencias independientes. Mucho cuidado si nuestro array contiene muchos datos, se duplica el consumo de memoria:

<?php 
$array1 = $array2 = array("uno" => 1, "dos" => 2);

echo "array1 antes:"; var_dump($array1); echo "\n";
echo "array2 antes:"; var_dump($array2); echo "\n";

$array1["tres"] = 3;
$array2["dos"] = 22;

echo "array1 después:"; var_dump($array1); echo "\n";
echo "array2 después:"; var_dump($array2); echo "\n";


La salida de este script es la siguiente:

~ $ php testarray.php 

array1 antes:array(2) {["uno"]=> int(1), ["dos"]=> int(2)}
array2 antes:array(2) {["uno"]=> int(1), ["dos"]=> int(2)}

array1 después:array(3) {["uno"]=> int(1), ["dos"]=> int(2), ["tres"]=> int(3)}
array2 después:array(2) {["uno"]=>, int(1), ["dos"]=> int(22)}

¿Qué ha pasado en este caso? Las dos variables son independientes, los cambios en una no afectan a la otra. Cada una apunta a una región de memoria diferente. En PHP se puede conseguir el mismo comportamiento que en otros lenguajes, esto es, que asignar una variable a otra por referencia:

<?php 
$array1 = array("uno" => 1, "dos" => 2);
$array2 = &$array1;

echo "array1 antes:"; var_dump($array1); echo "\n";
echo "array2 antes:"; var_dump($array2); echo "\n";

$array1["tres"] = 3;
$array2["dos"] = 22;

echo "array1 después:"; var_dump($array1); echo "\n";
echo "array2 después:"; var_dump($array2); echo "\n";

En este caso el comportamiento es el mismo que en el primer script en Python.
La expresión $array2 = &$array1asigna por referencia la variable 1 a la variable 2.

¿Qué comportamiento es deseable o más conveniente en un lenguaje de programación? La aproximación de PHP puede parecer más ineficiente, pero si reflexionamos un momento, tiene algo a su favor: es consistente.

<?php
$a = $b = 4;
$a = 5;
var_dump($a); var_dump($b);

La salida es:

int(5)
int(4)

Cada variable es una copia.

En Python, los tipos de datos simples sí que se asignan por copia:

Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
>>> a = b = 4
>>> a = 5
>>> a
5
>>> b
4
>>>

También se ve cómo son variables independientes. 

Todos los tipos de datos, simples y compuestos, se comportan igual PHP, sin embargo, en Python los tipos de datos compuestos (diccionarios, listas,... se asignan por referencia y los tipos de datos simples (enteros,...), se asignan por copia.

Esto no es bueno ni malo... pero hay que estar atento.