Weblogs Código

Variable not found

Invocar View Componentes usando Tag Helpers en ASP.NET Core MVC

January 20, 2017 08:08 AM

ASP.NET Core MVCComo sabemos, para invocar a un view component e incluir la vista parcial que retorna en el interior de otra vista, debemos utilizar desde ésta el helper @Component.Invoke() o su alternativa asíncrona @Component.InvokeAsync(), por ejemplo de la forma que vemos a continuación:
<div class="cart">    
   @await Component.InvokeAsync(
      "ShoppingCart",
      new { showImages = false, showButtons = false }
   )
</div>
Y aunque no es especialmente incómodo ni difícil de implementar, es cierto que presenta algunos inconvenientes. En primer lugar, dado el helper @Component.Invoke() es el mismo para todos los view components, ni el entorno ni el compilador pueden ofrecernos ayuda en nombres o parámetros, ni validar que la llamada sea correcta. Cualquier fallo se detectará exclusivamente en tiempo de ejecución.

Asimismo, está claro que el código de las vistas es más legible y fluido si en lugar de utilizar sintaxis imperativa, como son las llamadas a helpers, se utiliza un enfoque declarativo, esto es, si utilizamos etiquetas como los célebres tag helpers.

En 2014, un miembro del equipo de desarrollo de ASP.NET Core registró un issue en Github proponiendo que debería proporcionarse una alternativa "automágica" basada en tag helpers para renderizar view components, de forma que una llamada como @await Component.InvokeAsync("MyViewComponent") pudiera codificarse más limpiamente como <myViewComponent /> sobre la vista:

Propuesta de NTaylorMullen en Github
Pues bien, la solución no ha sido implementada hasta la versión 1.1 de ASP.NET Core. A partir de ella, por cada view component del proyecto se creará automáticamente un tag helper con su mismo nombre que permitirá realizar este tipo de invocaciones.

Vamos a ver lo sencillo que es utilizar esta característica usando como ejemplo el siguiente view component:
public class ShoppingCartViewComponent: ViewComponent
{
private readonly IShoppingCartServices _shoppingCartServices;  

    public ShoppingCartViewComponent(IShoppingCartServices shoppingCartServices)
{
_shoppingCartServices = shoppingCartServices;
}  
    public async Task<IViewComponentResult> InvokeAsync(
        bool showImages, bool showButtons)
{
var vm = new CurrentCartViewModel()
{
Items = await _shoppingCartServices.GetCurrentCartItems(),
ShowImages = showImages,
ShowButtons = showButtons
};
return View(vm);
}
}
En primer lugar, para que los tag helpers generados automáticamente estén disponibles en nuestras vistas, es necesario añadir al archivo de importaciones globales (_ViewImports.cshtml) la siguiente directiva, obviamente sustituyendo "MyWebApplication" por el nombre de vuestro proyecto:
@addTagHelper *, MyWebApplication
Tras ello, ya en las vistas tendremos nuestro componente disponible en forma de tag helper, por lo que podemos utilizarlo directamente:
<vc:Shopping-cart show-images="true" show-buttons="false"></vc:Shopping-cart>
Es muy importante tener en cuenta que:
  • Los tag helpers de todos los view components definidos en el proyecto estarán disponibles usando el prefijo "vc:", como en el ejemplo anterior.
     
  • El nombre del view component será usado como nombre de etiqueta. En el ejemplo anterior, el nombre sería "ShoppingCart" (sin el "ViewComponent" final).
     
  • Todos los parámetros de su método InvokeAsync() serán usados como atributos de la etiqueta. En el ejemplo anterior, esto ocurriría con los parámetros showImages y showButtons.
     
  • Los nombres serán transformados de forma que las mayúsculas intermedias habituales en el Pascal o Camel Casing serán utilizadas para identificar palabras distintas, que serán separadas por guiones "-" en el nombre de la etiqueta y sus atributos.
     
  • En las versiones actuales del IDE, con el tooling aún en prerelease, aún no funciona bien del todo el intellisense y otras ayudas en tiempo de diseño, pero en un futuro próximo nos ofrecerá ayuda de autocompletado y validación de tipos sobre la marcha.
Espero que os resulte útil :)

Publicado en Variable not found.

» Leer más, comentarios, etc...

Poesía Binaria

Recompilar módulo de kernel de Virtualbox en Debian/Ubuntu y derivadas

January 18, 2017 09:50 AM

Aunque las distribuciones de GNU/Linux cada vez son más amigables para el usuario (user-friendly) y automatizan en muchas ocasiones los procesos de actualización, incluso la actualización del kernel, en distrubiciones como Linux Mint (que es la que estoy utilizando ahora), resulta muy fácil actualizar hasta desde el entorno gráfico.
Pero ciertos drivers tienen que compilarse de nuevo, tenemos el driver de las tarjetas gráficas nvidia y el que Virtualbox necesita para lanzar máquinas virtuales.

Y, aunque estas compilaciones suelen ocurrir de forma transparente al usuario, en ocasiones no es así y pueden fallar, o no lanzarse. Para ello, podemos en estas distribuciones hacer lo siguiente:

sudo dpkg-reconfigure virtualbox-dkms

Tras ello, podemos reiniciar el servicio:

sudo service virtualbox restart

Eso sí, hay que tener en cuenta que el módulo DKMS de Virtualbos 5.0 no es compatible con el kernel 4.8 y la versión 5.1 de Virtualbox ya no necesita dicho módulo. Así que esto nos hará mucho más sencillas las actualizaciones a partir de ahora. Podemos instalar la última versión añadiendo el repositorio de Virtualbox en nuestra máquina. Entrad aquí para ver detalles del repositorio y no olvidéis que hay que hacer:

sudo apt-get update
sudo apt-get install virtualbox-5.1

para instalar la nueva versión.

The post Recompilar módulo de kernel de Virtualbox en Debian/Ubuntu y derivadas appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Poesía Binaria

Nuevo servidor, nuevo rumbo, proyectos y algunos posts

January 17, 2017 04:58 PM

Es un año extraño, casi todos los años desde el día 1 estoy publicando bastante, pero, como veis, este es el primer post del año, a día 17 de Enero, y tampoco tiene mucha chicha. En realidad tengo muchos proyectos nuevos y algunos viejos que me gustaría retomar y, en este blog, también iré plasmando algunas cosas.

Lo primero, anunciar una mudanza, a un nuevo servidor, con más espacio. Porque antes, a diario sufría por el espacio libre, me quedaban apenas 500Mb libres, y bajando… me paso el día rodeado de servidores, y era demasiada tensión, pero no podía aumentar un poco el espacio de forma asequible, así que decidí renovarlo todo y de paso retomar un antiguo proyecto.

Dicho antiguo proyecto era una guía para montar tu VPS en GNU/Linux. Era un proyecto que comencé en 2013 y que, como todo en el mundo de la tecnología se va quedando antiguo a pasos agigantados. Así que he decidido empezar a renovar dicha guía (ya daré guerra también con esto en este blog) y me gustaría publicar dicha guía en varios formatos y plataformas, con muchos más ejemplos, opciones, recomendaciones y explicaciones de todo.

¡¡Estreno newsletter!! El blog con una lista de correo para informar a todo el mundo sobre los posts. Bueno, más o menos, me gustaría incluir enlaces, recomendaciones y alguna cosa interesante que no sea de mi cosecha pero considere relevante. Sería algo así como la página de Facebook, pero un poco 1.0, que aunque parezca mentira, se siguen utilizando estas cosas. Podéis daros de alta aquí:


Pero claro, aunque no soy partidario de dar guerra con la newsletter impidiendo que la gente vea los artículos, con popups inmensos… daré algo de guerra, por si alguien quiere recibir los posts por correo. Es más, yo estoy apuntado a varias listas de varios blogs.

Comentarios. Ya no hay que esperar a la moderación para que figure publicado. Todo viene a raíz de una conversación por Twitter:


A mí también me molestaba un poco tener que esperar a que mis comentarios en otros sitios fueran moderados y, a veces el moderador no está en un tiempo, no se publica, y bueno, en mi blog los tenía moderados. Al principio tenía mucho Spam, con Akismet colaban muchas cosas, pero desde que instalé hace unos años Anti-Spam, desaparecieron los cientos de comentarios ilegítimos. Y, la verdad es que en más de 7 años de blog, sólo he eliminado 3 comentarios, uno de Spam (manual y currado, para que contratara un crédito), un mensaje que contenía insultos gratuitos, y otro mensaje que en 10 palabras metía 6 faltas de ortografía. Considero que en este mundo, cuando alguien quiere comentar suele respetar unas cuantas normas no escritas (o sí escritas). Así que, ya está he decidido hacer que los comentarios se publiquen automáticamente.

Algunas páginas más. Estoy intentando organizar la información, keywords y descripciones, poco a poco, para que se encuentre mejor desde los buscadores, ya que son las principales fuentes de tráfico del blog. Aunque desde Facebook entra mucha gente, desde Google entran 10 veces más personas. Así que tendré que mimar esas fuentes de tráfico, incluso muchos posts que publiqué poco a poco sobre el mismo tema, quiero introducir referencias a los diferentes posts para encontrar más información. Es complicado cuando el blog tiene tantos posts, pero… poco a poco… incluso muchos posts que escribí al principio, puede que necesiten una pequeña revisión.

Un poco más de vídeo. Tengo el vídeo abandonado, pero quiero darle un empujón. Llevo varios meses preparando algunos posts sobre vídeo, pero llevan tiempo. Poco a poco iré soltando cosas, así revivo y organizo un poco mi canal de Youtube, pronto habrá novedades.

Foto principal: Scott Webb

The post Nuevo servidor, nuevo rumbo, proyectos y algunos posts appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Una sinfonía en C#

Tips de Javascript: Lograr que JSON.stringify se comporte a nuestro gusto

January 17, 2017 03:10 PM

Hace ya bastante tiempo que contamos con JSON.parse() y JSON.stringify() para des-serializar y serializar objetos, lo que hace este último es generar una representación JSON de nuestro objeto, al recorrer todas las propiedades del objeto y sus propiedades anidades también, algo así:

image

Esto está muy bien, pero existen ocasiones en las que no queremos esto, por diferentes motivos: no queremos serializar todo, queremos que tenga otra forma, etc. por supuesto que podemos siempre echar mano de un método propio y no usar JSON.stringify, pero si quien consume nuestro código no sabe de la situación es probable que termine haciéndolo, entonces, ¿podemos modificar este comportamiento?

Modificando el comportamiento de JSON.stringify

Sí, existe una forma estándar de decirle al navegador que en lugar de comportarse como lo hace siempre haga exactamente lo que nosotros queremos cuando se usa JSON.stringify, y es tan simple como escribir nuestro propio método toJSON, así algo así;

image

Y magia, vemos que ahora utilizando la función estándar del navegador obtenemos justo lo que queremos.

Nos leemos.

» Leer más, comentarios, etc...

Adrianistán

Tutorial de Piston, programa juegos en Rust

January 17, 2017 10:56 AM

Ya he hablado de Rust varias veces en este blog. La última vez fue en el tutorial de Iron, que os recomiendo ver si os interesa el tema del desarrollo web backend.

Hoy vamos a hablar de Piston. Piston es una de las librerías más antiguas del ecosistema Rust. Surgida cuando todavía no existía Cargo, esta librería está pensada para el desarrollo de juegos. No es la única que existe en Rust pero sí la más conocida. Piston es una librería que te enseñará Rust de la mejor forma. Y ahora quiero disculparme, porque Piston no es una librería, son un montón, pero eso lo veremos enseguida. En primer lugar creamos un proyecto nuevo con Cargo.

cargo new --bin ejemplo_piston
cd ejemplo_piston

Ahora abrimos el archivo Cargo.toml, vamos a añadir las dependencias necesarias. Las dependencias en Piston son un poco complicadas, veamos:

  • Existen las dependencias core, implementan la API fundamental pero no pueden usarse por separado, son window, input y event_loop. Se usan a través de piston.
  • Los backends de window, existen actualmente 3 backends: glutin, glfw, sdl2. Se importan manualmente.
  • Graphics, una API 2D, no presente en core, pero al igual que las dependencias core necesita un backend.
  • Los backends de graphics son varios: opengl, gfx y glium.
  • Existe una dependencia que nos deja todo montado, piston_window. Esta trae por defecto el core de Piston, glutin, graphics y gfx.
  • Luego existen dependencias extra, como por ejemplo para cargar texturas, estas las podremos ir añadiendo según las necesite el proyecto.

Para simplificar añadimos piston_window únicamente:

 

[package]
name = "piston_example"
version = "0.1.0"
authors = ["Adrián Arroyo Calle"]

[dependencies]
piston_window = "0.59.0"

 

Ahora abrimos el archivo main.rs. Añadimos la crate de piston_window y los módulos que vamos a usar.

extern crate piston_window;

use piston_window::*;
use std::path::Path;

 

Así mismo definimos un par de cosas para el resto del programa, la versión de OpenGL que usará Piston internamente y una estructura para guardar los movimientos de teclado.

const OPENGL: OpenGL = OpenGL::V3_1;

struct Movement{
    up: bool,
    down: bool,
    left: bool,
    right: bool
}

 

En la función main podemos crear la ventana, especificando título y tamaño. Más opciones como V-Sync, pantalla completa y demás también están disponibles.

fn main() {

    let mut window: PistonWindow = WindowSettings::new("Piston - Adrianistan",[640,480])
        .exit_on_esc(true)
        .opengl(OPENGL)
        .build()
        .unwrap();

 

Ahora cargamos la tipografía Sinkin Sans, que vamos a usar para dibujar texto en pantalla. Como hay dos posibles localizaciones comprobamos esos dos lugares antes de salir del programa si no se consigue cargar la fuente.

    let mut glyphs = Glyphs::new(Path::new("SinkinSans.ttf"),window.factory.clone()).unwrap_or_else(|_|{
        let glyphs = Glyphs::new(Path::new("target/debug/SinkinSans.ttf"),window.factory.clone()).unwrap_or_else(|_|{
            panic!("Failed to open the font file. Check that SinkinSans.tff is in the folder");
        });
        glyphs
    });

 

Inicializamos la estructura de movimientos, generamos las dimensiones iniciales del rectángulo (que será un cuadrado en este caso), su color y la posición del ratón.

    let mut mov = Movement{
        up: false,
        down: false,
        left: false,
        right: false
    };

    let mut dims = rectangle::square(50.0,50.0,100.0);
    let mut rect_color = color::BLACK;

    let mut mc: [f64; 2] = [0.0,0.0];

 

Ahora viene la parte importante, el bucle de eventos. El bucle va a funcionar infinitamente generando eventos por el camino (pueden ser eventos de inactividad también). Usamos la función draw_2d para dibujar en 2D. Hay dos maneras de dibujar un rectángulo, en primer lugar tenemos la forma abreviada y en segundo lugar una más completa que permite más opciones. Por último dibujamos el texto usando la fuente y realizando una transformación para que no quede el texto en la posición 0,0.

 while let Some(e) = window.next() {
        window.draw_2d(&e, |c, g| {
            clear([0.5, 0.5, 0.5, 1.0], g);
            rectangle([1.0, 0.0, 0.0, 1.0], // color rojo, rgba
                        [0.0, 0.0, 100.0, 100.0], // dimensiones
                        c.transform, g); // transormacion y donde se va a dibujar

            let rect = Rectangle::new(rect_color);
            rect.draw(dims,&c.draw_state,c.transform,g);
            text(color::BLACK,18,"¡Saludos desde Piston!",&mut glyphs,c.transform.trans(100.0,200.0),g); // aplicamos una transormacion, movemos las X 100 y las Y 200
        });

 

A continuación vamos a tratar cada evento de forma independiente, como todos los métodos devuelven Option, hemos de usar esta sintaxis con Some. En primer lugar tenemos un UpdateEvent, que básicamente nos informa del tiempo delta transcurrido. Recomiendo usar este evento para realizar los cambios en las geometrías, en este caso para mover el rectángulo.

if let Some(upd_args) = e.update_args() {
            let dt = upd_args.dt;
            
                if mov.right {
                    dims[0] += dt*100.0;
                }
                if mov.left {
                    dims[0] -= dt*100.0;
                }
                if mov.up {
                    dims[1] -= dt*100.0;
                }
                if mov.down {
                    dims[1] += dt*100.0;
                }
        }

Los siguientes dos eventos son opuestos, uno se activa cuando pulsamos una tecla y el otro cuando la soltamos. Comprobamos la tecla y modificamos la estructura movement en consecuencia.

if let Some(Button::Keyboard(key)) = e.press_args() {
            if key == Key::W {
                mov.up = true;
            }
            if key == Key::S {
                mov.down = true;
            }
            if key == Key::A {
                mov.left = true;
            }
            if key == Key::D {
                mov.right = true;
            }
        };
        if let Some(Button::Keyboard(key)) = e.release_args() {
            if key == Key::W {
                mov.up = false;
            }
            if key == Key::S {
                mov.down = false;
            }
            if key == Key::A {
                mov.left = false;
            }
            if key == Key::D {
                mov.right = false;
            }
        };

Por último, si queremos comprobar clicks del ratón hacemos algo similar. He añadido código para que cambio el color del rectángulo si pulsamos sobre él.

if let Some(Button::Mouse(mb)) = e.release_args() {
            if mb == MouseButton::Left {
                let x = mc[0];
                let y = mc[1];
                if x > dims[0] && x < dims[0] + dims[2] { if y > dims[1] && y < dims[1] + dims[3] {
                        rect_color = if rect_color == [1.0,0.0,0.0,0.7]{
                            [0.0,1.0,0.0,0.7]
                        } else if rect_color == [0.0,1.0,0.0,0.7] {
                            [0.0,0.0,1.0,0.7]
                        } else{
                            [1.0,0.0,0.0,0.7]
                        }
                    }
                }
                
            }
        }

A continuación un pequeño evento que guarda la última posición del ratón.

        if let Some(mouse_cursor) = e.mouse_cursor_args() {
            mc = mouse_cursor;
        }
    }
}

 

Y con esto ya tenemos hecho un ejemplo en Piston.

Si quieres tener un ejecutable para Windows sin que se muestre primero la consola debes compilar la versión que vas a distribuir con unos parámetros especiales. Si usas Rust con GCC usarás:

cargo rustc --release -- -Clink-args="-Wl,--subsystem,windows"

Si por el contrario usas Visual C++:

cargo rustc --release -- -Clink-args="/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup"

 

Piston todavía se encuentra en fuerte desarrollo, en la API estan documentados todos los métodos pero aun así muchas veces no se sabe como hacer ciertas cosas. Piston soporta además 3D, contando con una librería especializada en vóxels. Veremos como evoluciona esta librería.

La entrada Tutorial de Piston, programa juegos en Rust aparece primero en Blog - Adrianistan.eu.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 265

January 16, 2017 07:05 AM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET

ASP.NET

.NET Core / ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Data

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Cross-platform

Otros

Y como extra, una curiosidad: ¿os habéis preguntado alguna vez lo que ocurre si intentáis descubrir una puerta trasera en Stackoverflow, del tipo http://stackoverflow.com/admin.php? Desde luego, estos chavales tienen sentido del humor :D
Publicado en Variable not found

» Leer más, comentarios, etc...

Koalite

Un diccionario persistente en 4 líneas de javascript

January 16, 2017 05:06 AM

A raíz de la excelente serie de post que está escribiendo Modesto San Juan sobre la programación orientada a objetos, comentábamos hace poco en twitter que a veces la programación funcional y la programación orientada a objetos ofrecen dos enfoques distintos para alcanzar lo mismo, y cómo ambos paradigmas cuentas con estructuras “idomáticas” para implementar conceptos del otro.

Todos los que hemos tocado javascript en algún momento hemos vivido esa sensación de estar simulando conceptos de programación orientada a objetos con funciones (con closures concretamente), pero lo cierto es que puede parecer algo anecdótico o impuesto por las “limitaciones” del lenguaje. 

Sin embargo, hay veces que modelar “objetos” o, siendo más correcto, estructuras de datos, con construcciones puramente funcionales, puede llegar a ser una solución mucho más sencilla.
A los que conozcáis el libro Structure and Interpretation of Computer Programs el ejemplo que vamos a ver en este post os resultará simplista, pero a los que no lo hayáis leido tal vez os resulte curioso y os anime a leer el libro (merece la pena, en serio).

Un diccionario inmutable y persistente

Vamos a implementar una estructura de datos que represente un diccionario, o un array asociativo, como se le conoce en otros ámbitos, que almacene un conjunto de pares clave/valor. Las operaciones básicas serán: crear un diccionario vacío, asociar una clave a un valor, eliminar la asociación entre una clave y un valor, y, por supuesto, obtener el valor asociado a una clave.

Hasta aquí, no parece un problema muy complicado y, de hecho, casi todos los lenguajes de programación que conozco incluyen una estructura de datos similar en su librería estándar. Aun sin usarla, crear nuestra propia implementación sería bastante sencillo a partir de una lista de pares.

Para hacerlo más interesante, vamos a intentar que nuestro diccionario sea inmutable y persistente. Es decir, cuando añadamos o eliminemos entradas del diccionario, queremos que no se modifique el diccionario original, sino que se cree un diccionario totalmente nuevo con los cambios que sea necesario. Y claro, queremos que estas operaciones de adición y eliminación sean eficientes. A ser posible, que tengan una complejidad algorítmica constante (O(1)). Además, hay que vigilar el consumo de memoria y evitar que al añadir un valor al diccionario acabemos teniendo dos copias en memoria de todo el diccionario original.

Resumiendo, si aprovechamos que todo el mundo es capaz de leer javascript y usamos ese lenguaje para especificar el problema, queremos un api así:

// Devuelve un diccionario vacío
function emptyDict() { ... }

// Obtiene el valor asociado a `key` en `dict`,
// o `null` si `key` no está en el diccionario
function get(dict, key) { ... }


// Crea un nuevo diccionario igual que `dict`, 
// pero en el que `key` está asociado a `value`.
// El diccionario original *no* debe ser modificado.
function set(dict, key, value) { ... }

// Crea un nuevo diccionario igual que `dict`, 
// pero que ya no contiene `key`.
// El diccionario original *no* debe ser modificado.
function remove(dict, key) { ... }

Con este api, deberíamos ser capaces de pasar estos tests:

let d = emptyDict();

assertEquals(null, get(d, 'lucas'), 'd no contiene nada');

let d1 = set(d, 'lucas', 10);

assertEquals(10, get(d1, 'lucas'), 'd1 contiene lucas');
assertEquals(null, get(d, 'lucas'), 'pero d sigue vacío');

let d2 = set(d1, 'marcos', 20);

assertEquals(10, get(d2, 'lucas'), 'd2 contiene lucas');
assertEquals(20, get(d2, 'marcos'), 'd2 contiene marcos');
assertEquals(null, get(d1, 'marcos'), 'pero d1 *no* contiene marcos');

let d3 = remove(d2, 'lucas');

assertEquals(null, get(d3, 'lucas'), 'd3 ya *no* contiene lucas');
assertEquals(20, get(d3, 'marcos'), 'd3 contiene marcos');
assertEquals(10, get(d2, 'lucas'), 'd2 sigue conteniendo lucas');
assertEquals(20, get(d2, 'marcos'), 'd2 sigue conteniendo marcos');

Si queréis probar a implementar esto con un enfoque más “OOP”, veréis que es relativamente fácil, siempre y cuando ignores las restricciones de eficiencia a la hora de insertar y eliminar, y no te preocupes por el consumo de memoria. En cuanto quieres introducir la inmutabilidad necesitas empezar a copiar objetos o arrays, y la cosa se complica un poco.

Una solución natural basada en funciones

Vamos a intentar resolver el problema utilizando sólo funciones, sin recurrir a objetos de javascript (que no dejan de ser diccionarios en si mismos), ni arrays. Aunque pueda parecer extraño, la solución es bastante natural (y curiosa si no has visto muchos ejemplos de este tipo).

Empezamos por crear un diccionario vacío.

¿Cuál es nuestra definición de diccionario vacío? Un diccionario que no contiene claves, es decir, un diccionario en el cual, para cualquier clave que utilicemos se cumple que get(dict, key) === null.

Puesto que la definición de diccionario vacío depende de la definición de get, implementemos ambas a la vez:

function emptyDict() {
  return function(k) {
    return null;
  };
}

function get(dict, key) {
  return dict(key);
}

Vale, a primera vista es un poco raro, pero vamos a analizarlo despacio.

Implementaremos un diccionario como una función, aunque eso es totalmente transparente para el usuario del diccionario, que sólo accederá a él a través del api definida en el punto anterior.

Para extraer valores del diccionario, invocaremos la función que representa al diccionario con la clave cuyo valor queremos obtener. Eso es exactamente lo que tenemos en la función get. Por tanto, un diccionario vacío será una función que, independientemente del valor que le pasemos como parámetro, siempre devolverá null que, recordemos, es el comportamiento que hemos definido para el caso de acceder a claves no presentes en el diccionario. Otra opción sería lanzar un error (y la implementación sería análoga cambiando el null por un throw "Invalid key" o algo similar).

¿Cómo añadimos valores al diccionario?

Puesto que estamos implementando el diccionario como una función, necesitaremos crear una función que, cuando reciba la clave añadida, devuelva el valor asociado. Para el resto de valores, deberá comportarse exactamente igual que el diccionario original:

function set(dict, key, value) {
	return function(k) {
		return k === key ? value : get(dict, k);
	};
}

Sencillo, ¿no? Nuestra nueva función devuelve el valor asociado a key al ser invocada con ese parámetro, y delega el resto de claves a lo que ya hubiera antes.

Sólo nos queda eliminar valores del diccionario, y a estas alturas seguro que te puedes imaginar cómo hacerlo:

function remove(dict, key) {
	return function(k) {
		return k == key ? null : get(dict, k);
	};
}

Como era de esperar, creamos una nueva función en la cual, cuando se intenta acceder al valor eliminado, devuelve null, y para el resto de valores, delega el resultado al diccionario original.

Si juntamos todo el código y lo ponemos en bonito (con las arrow functions de ES2015), nos quedan las siguientes 4 líneas:

const emptyDict = () => () => null;
const get = (dict, key) => dict(key);
const set = (dict, key, value) => k => key === k ? value : dict(k);
const remove = (dict, key, value) => k => key === k ? null : dict(k);

Sin llegar al Code Golf, hay que reconocer que queda una implementación bastante simple (lo de sencilla lo dejo ya a vuestro criterio).

Cumple con todos los requisitos indicados al principio: inmutabilidad, persistencia, coste constante para inserción y eliminación, y consumo mínimo de memoria. No he implementado la solución a partir de objetos o arrays, pero estoy casi seguro de que requiere más código.

Por si alguien se plantea si esto es usable, hay que tener en cuenta dos cosas: el coste de acceso para obtener un elemento es un triste O(n) y, dependiendo del tamaño del diccionario, te arriesgas a obtener un stack overflow si el jitter que ejecuta el código no es capaz de optimizar la recursión final (desconozco si V8 lo hace, por comparar, creo que la JVM no es capaz y que .NET sólo lo hace en 64 bits).

Resumen

Es divertido jugar con distintos enfoques a la hora de resolver un problema. Incluso problemas que, a priori, nos pueden parecer muy indicados para aplicar un enfoque concreto, una vez analizados nos pueden acabar sorprendiendo.

Si nunca te habías parado a pensarlo y te hubieran dicho que una forma muy sencilla de implementar un diccionario persistente es sólo con funciones, seguramente te hubiera extrañado, pero la realidad es que la solución es bastante natural. De hecho, utilizar un enfoque OOP clásico para este problema es complicado (sobre todo la parte de evitar duplicar el consumo de memoria con cada inserción/eliminación).

En el mundo real las estructuras de datos persistentes se implementan con técnicas más sofisticadas que permiten asegurar un rendimiento mejor, pero esto no deja de ser un poco de pornografía interesante para pasar el rato.

Posts relacionados:

  1. Modificar una clase en Javascript: Eliminar los markers de Google Maps
  2. Usando C# para entender los constructores de Javascript
  3. Usando C# para entender los prototipos de Javascript

» Leer más, comentarios, etc...

Adrianistán

9front, un fork de Plan9 desarrollado por dementes

January 16, 2017 12:03 AM

Hace poco, por IRC conocí la existencia de este sistema operativo, 9front, derivado de Plan9. En principio pensé que sería un fork normal y corriente. Cuando entré en su página descubrí sin embargo que era algo completamente distinto.

La 9community, formada por Henry Kissinger y Hillary Clinton, promotores del nuevo orden mundial

Su página web está cargada de minimalismo y memes, la gran mayoría de ellos inspirados en la guerra fría. Al entrar respiramos la esencia de 9front. Por ejemplo, el servidor web de la página es werc. Werc se define a sí mismo como el anti-framework anti-web. Sin bases de datos, solo ficheros y ¡programado en rc! Rc es un componente fundamental de 9front, una piedra angular. Se trata del lenguaje de shell de 9front. El equivalente en Linux sería Bash.

Werc es solo una de las cosas que acoge bajo su paraguas la organización Cat-V (de System-V, marcándose un chiste Unix de cuidado). El lema de Cat-V, Considered harmful (considerado peligroso) nos alerta de que encontraremos contenido que ha sido ajeno para la mayoría de la población. ¿Realmente estamos entrando en Cat-V en la iluminación de Internet? ¿Es entrar en Cat-V un equivalente moderno a salir de la cueva de Platón?

Algunos proyectos de Cat-V son:

  • 9P, un sistema de archivos distribuido. Es usado por 9front.
  • Acme, un editor de texto hecho por Rob Pike
  • Sam, otro editor de texto, también de Rob Pike
  • Fortune, una colección de archivos fortune de varios sistemas UNIX. Parémonos ante este fortune etiquetado dentro de OpenBSD:
(1) Alexander the Great was a great general.
(2) Great generals are forewarned.
(3) Forewarned is forearmed.
(4) Four is an even number.
(5) Four is certainly an odd number of arms for a man to have.
(6) The only number that is both even and odd is infinity.

Therefore, Alexander the Great had an infinite number of arms.

Corramos un tupido velo y sigamos.

¡La web oficial de Glenda!

Por si te lo preguntas, sí, la mascota de Go se encuentra inspirada en Glenda

El subdominio harmful está reservado para pensamientos y para expresar opiniones.

Se habla de economía, películas, periodismo, relaciones personales (de tratar con estúpidos, un artículo muy bueno), de lo políticamente correcto, de ciencia, de la seguridad post 11S, de sociedad (y para mi sorpresa contiene una opinión que yo también tengo pero que apenas he visto, el matrimonio debe ser eliminado del sistema legal de los países para pasar a ser algo cultural/religioso, similar al bautizo), se habla de software, de estándares y de palabras. Pretenden hablar de: SQL, fútbol, la Matrix, svn, postmodernismo, gnu, religión, vi, educación, apache, respeto, teoría de cuerdas, complejidad, comida ‘orgánica’, etanol, igualdad, metadata, lógica de “sentirse bien”, teoría del trabajo, …

HTTP 0.2, un intento de simplificar HTTP.

NineTimes, la web de noticias del mundo Plan9, Inferno y 9front.

Y por supuesto, un archivo de citas célebres.

Volvamos a 9front

Continué en la página de 9front, vi que tenía un Código de Conducta (algo que han introducido algunos proyectos open source pero que bajo mi punto de vista es innecesario y en algunos casos peligroso). Sin embargo en 9front no hay un código de conducta, hay varios. Cada vez que te metes en la página sale uno distinto. Y todos son muy random. Desde el credo en latín hasta una especie de receta para crear desarrolladores químicamente. La mitad son cánticos de alabanza a 9front. Yo veo en esto una sátira perfecta de lo que son algunos Códigos de Conducta.

Luego vemos para descargar las ISO, pero a estas alturas es lo que menos importa. A continuación encontramos una recopilación de webs alternativas para 9front. Hay una basada en 4chan, pero esta me gusta más:

Y llegamos a mi sección favorita, Propaganda.

Porque el boot de 9front es explosivo, nuclearmente explosivo
La comunidad 9front

Los altos mandos de 9front
The front fell off

Man es un comando muy propenso a chistes
Mothra es el navegador web de 9front
Orwell dirige NineTimes
El comando timesync no es más que una modernización de Stonehenge

Posiblemente haga una entrada seria hablando de 9front, pero es que la comunidad 9front tiene mucha tela que cortar.

Y donde dije dementes, quise decir genios. Son absolutos genios.

La entrada 9front, un fork de Plan9 desarrollado por dementes aparece primero en Blog - Adrianistan.eu.

» Leer más, comentarios, etc...

Variable not found

¡Felices fiestas, y gran 2017!

January 15, 2017 12:05 PM






Os deseo unas muy felices fiestas navideñas y
un 2017 lleno sólo de cosas buenas.

¡Nos vemos por aquí!

Publicado en: www.variablenotfound.com.

» Leer más, comentarios, etc...

Blog Bitix

Script de instalación de Arch Linux desatendido, automatizado y personalizable

January 12, 2017 11:00 PM

Arch Linux es una de las distribuciones más personalizables de GNU/Linux pero cuya instalación requiere leer una buena cantidad de documentación para saber que comandos ejecutar en el prompt del sistema en el que te deja se medio de instalación. Algunos usuarios eligen una distribución como Antergos, KaOS o Manjaro con un instalalador gráfico y guiado simplemente por el hecho de no enfrentarse al instalador de Arch Linux. Ejecutar un comando y esperar a que termine para introducir otro es lento y requiere de atención.

Arch Linux
Linux
GNU

Hace tiempo que instalar una distribución GNU/Linux no tiene más dificultad que instalar un sistema operativo como Windows, que consiste en descargar la imagen ISO del CD o DVD, grabarla en un CD, DVD o memoria USB e iniciar el sistema con el medio. Las distribuciones aconsejadas para usuarios que provienen de Windows o macOS o no tiene muchos conocimientos informáticos poseen instaladores gráficos o basados en texto y guiados en varios pasos hasta completar la instalación en menos de una hora. Distribuciones como Ubuntu, elementary OS o Linux Mint hacen que la instalación no requiera muchos conocimientos y sea completada con éxito por cualquier usuario.

Instalación guíada de Debian basada en texto y gráfica

Otras distribuciones basadas en principios diferentes y usuarios a los que está destinadas con otras necesidades o preferencias puede que requieran algo más de conocimientos a cambio de realizar configuraciones más avanzadas como el particionado del disco, cifrado del disco o software que se instala. Algunas distribuciones como Arch Linux incluso no proporcionan ningún instalador.

It is targeted at the proficient GNU/Linux user, or anyone with a do-it-yourself attitude who is willing to read the documentation, and solve their own problems.

En Arch Linux con su forma de hacer las cosas deja al usuario el poder de personalizar el sistema completamente a sus necesidades y preferencias únicamente limitado por su determinación de conseguirlo. Solo proporciona el medio con el que iniciar la instalación que comienza con una terminal y un prompt del sistema, una guía de instalación junto con las recomendaciones generales y una de las mejores fuentes de información en GNU/Linux además de completa de cada aspecto que necesitemos en la instalación. Después de haber leído las páginas relevantes de la wiki de Arch Linux, seguramente más de una y dos veces, hasta comprenderla en su mayor parte se empieza a realizar la receta que contenga los comandos necesarios hasta completar la instalación.

En multitud de blogs y vídeos de YouTube hay guías que contienen los comandos y las explicaciones necesarias. Cualquier usuario de Arch Linux con un blog seguramente ha publicado un artículo con su guía de instalación (sí, yo también publiqué la mía). Un usuario que quiera instalar Arch Linux debe leer varios de esos artículos además de la guía oficial de instalación. Según la filosofía de Arch Linux este proceso de aprendizaje se considera necesario y permite una mayor compresión del sistema. Pero saber los comandos que hay que introducir para realizar la instalación de Arch Linux no evita tener que teclearlos uno de tras de otro y esperar a que termine el anterior para introducir el siguiente. Tampoco todas las personas tienen el tiempo para realizarlo. Varias distribuciones derivadas de Arch Linux como Antergos, KaOS o Manjaro ofrecen los instaladores gráficos y guiados más amigables que atraen a algunos usuarios buscando usar Arch Linux pero no pasar por su poco amigable proceso de instalación. Por fortuna al ser una distribución rolling release (en constante actualización) solo hay que hacer una única instalación por equipo en principio durante toda su vida de uso. Pero incluso para los usuarios de Arch Linux realizar una segunda instalación en un nuevo equipo es cansina.

Hace unos meses conocí arch-anywhere que básicamente es un script de bash, con un instalador guiado y basado en texto que hace menos laboriosa la instalación de Arch Linux de forma similar a las existentes en otras distribuciones más amigables. Sin embargo, hay un dos cosas que no me convencen de arch-anywhere, una es que no es desatendido requiriendo contestar a varias preguntas de forma interactiva, esperar a que termine ejecute algún comando según la contestación anterior y contestar a la siguiente pregunta. Por lo demás, ofrece un buen nivel de personalización cubriendo las necesidades más comunes de los usuarios como personalizar el particionado, elegir el sistema de archivos, si se quiere LVM, cifrado, el entorno de escritorio (GNOME, KDE, XFCE, …), kernel, cargador de arranque (GRUB) y programas a instalar. Otra cosa que no me convence es que usa una imagen ISO propia y no la original de Arch Linux.

Basándome en arch-anywhere y dedicando un poco de tiempo he creado un script en bash para instalar Arch Linux de forma automatizada, desatendida y personalizable hasta cierto punto aunque siendo útil para los casos de configuraciones más comunes. Algunas de las funcionalidades que soporta son:

La forma aconsejada de instalar Arch Linux es aprendiendo cuales son los comandos a ejecutar y que hace cada uno de ellos, primero lee la guía oficial de instalación de Arch Linux y comprende que hacen los comandos del script. Este script no es oficial y por ello en el foro de Arch Linux en español o en inglés no podrán darte soporte aunque yo en los comentarios de este artículo te ayudaré si preguntas. Ten en cuenta que de momento solo lo he probado en VirtualBox no en un sistema real y que este script elimina toda la información del dispositivo de instalación. Si lo pruebas deja un comentario al final de artículo.

Iniciado el instalador de la imagen ISO de Arch Linux, hay que descargar el script, editar algunas variables de entorno y darle permisos de ejecución. Los comandos y variables a editar según el sistema a instalar son los siguientes:

El código del instalador no es muy complicado y mucho más sencillo que el código de arch-anywhere al no estar mezclado con los mensajes interactivos que hacen preguntas y esperan respuestas. Los comandos que he recopilado de la receta son los que ejecutaríamos uno detrás de otro con únicamente el medio de instalación de Arch Linux. La función main contiene los pasos en los que consiste la instalación, desde el paticionado y cifrado del disco hasta el reinicio una vez completada la instalación, el resto de las funciones los comandos de ese paso de la instalación.

Estas son algunas capturas de pantalla con diferentes entornos de escritorio que he probado con VirtualBox.

Entornos de escritorio GNOME y KDE
Entornos de escritorio Xfce y Cinnamon
Entornos de escritorio LXDE y Mate
Solicitud de contraseña para descifrar partición root

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 264

January 10, 2017 07:56 AM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET

ASP.NET

.NET Core / ASP.NET Core

Conceptos/Patrones/Buenas prácticas

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Publicado en Variable not found

» Leer más, comentarios, etc...

Variable not found

Top posts 2016 en Variable not found

January 09, 2017 03:37 PM

The best of 2016Como las tradiciones están para cumplirlas, aprovecharemos este primer post del año para hacer el clásico repaso de los diez artículos de 2016 que fueron más visitados durante el año que acabamos de cerrar.

He de decir que esta vez he tenido que manipular un poco los resultados porque muchos de los posts más visitados eran los relativos a los anuncios de la gran celebración del décimo aniversario del blog y los espectaculares sorteos y regalos (como éste, éste, este, éste, éste…) que repartimos gracias a nuestros patrocinadores. Por tanto, para no monopolizar el ranking sin añadir mucho valor a estas alturas, no los he tenido en cuenta.

Ya centrados en los artículos con más chicha, veremos que la gran mayoría de entradas destacadas tienen que ver con ASP.NET Core, lo que pone de manifiesto el interés que está despertando el nuevo framework, y dejan claro que vosotros, amigos del blog, sois gente inquieta y os gusta estar a la última ;)

Encabeza el ranking el post "ASP.NET 5 se llama ahora ASP.NET Core", un eco del controvertido anuncio de Microsoft anunciando el cambio de nombre de su nuevo framework de desarrollo para la web. Aunque conceptualmente fue un renombrado correcto, no se puede decir lo mismo del momento que eligieron para hacerlo, que sin duda fue demasiado tarde.

En segunda posición encontramos "¿Cuál es el "Bus factor" de tu proyecto?" una llamada de atención sobre los peligros de concentrar toda la información y conocimiento sobre un proyecto en un grupo reducido de personas. Un tema serio, independientemente de lo divertido del término.

Le sigue en el ranking el artículo "5 cambios destacables en ASP.NET Core RC2", donde comentábamos las principales novedades introducidas en la tardía y rompedora segunda release candidate del nuevo marco de trabajo. Aquí comenzaron a verse aplicados los cambios de nombre, el nuevo modelo de aplicaciones de consola ASP.NET  y el descarte de DNX en favor de .NET Core CLI.

El siguiente post más visto fue el que se hacía eco del lanzamiento de la versión 1.0 RTM de .NET Core, ASP.NET Core y Entity Framework Core. Era sin duda un esperado acontecimiento, probablemente el más importante de los últimos años, y era previsible que el tema despertara interés.

A continuación encontramos un artículo con contenido puramente técnico donde explorábamos el uso de variables de sesión en ASP.NET Core 1.0. Aunque a veces denostadas, probablemente por el abuso que históricamente se ha hecho de ellas, las variables de sesión son un recurso útil para el mantenimiento de estado entre peticiones de una aplicación web, y el interés despertado por este contenido dejó claro que aún siguen formando parte de la caja de herramientas de los desarrolladores.

En sexto lugar tenemos un post autorespondiéndome a una curiosidad que arrastraba desde hacía tiempo. En ¿Es ASP.NET Core MVC un middleware? estudiábamos si existía un middleware específico de MVC que fuera el responsable de "enganchar" este framework al pipeline de ASP.NET Core. Spoiler: no, no existe.

En "Convenciones personalizadas en ASP.NET Core MVC" introducíamos el Application Model de MVC, y cómo aprovecharlo para construir convenciones custom en las aplicaciones, como añadir automáticamente el filtro [ValidateAntiForgeryToken] a todas las acciones accesibles a través del método POST.

"ASP.NET Core" en Google TrendsSeguidamente encontramos entre los posts más vistos el anuncio del lanzamiento de mi Curso de ASP.NET Core MVC en CampusMVP, demostrando de nuevo el interés de la comunidad de desarrolladores en esta nueva tecnología, y que reflejaba en el gráfico adjunto. Aún estáis a tiempo de echar un vistazo al artículo para decidir si lo empezáis mañana mismo ;)

Y finalizamos el top ten con un empate entre dos posts puramente técnicos, también sobre ASP.NET Core. El primero de ellos era el inicio de la serie "Archivos estáticos en aplicaciones ASP.NET Core", que se extendió posteriormente durante tres artículos más. El segundo, es una reedición de un artículo anterior, actualizada a versiones más reciente de ASP.NET Core, tras los cambios introducidos en RC2: "Logging en ASPNET Core (actualizado a RC2)".

Aunque ya hemos completado el ranking de los diez posts más visitados, voy a hacer una excepción para incluir el que hace número 11, porque tiene si mérito: Visual Studio 2017 se llamará finalmente Visual Studio Core 1.0. Y no queda ahí la cosa… Pues sí, la broma escrita para el pasado día de los inocentes (28-dic) entró con fuerza y en sólo tres días se quedó en las puertas de estar entre los diez artículos más vistos del año pasado :DD

Como siempre, aparte de los contenidos generados durante 2016, hemos tenido bastantes visitas a posts que ya son clásicos en el blog y supongo que estarán muy bien posicionados en buscadores, como:
Y un año más, por su alta situación en el ranking, me gustaría destacar el excelente artículo “Closures en JavaScript: entiéndelos de una vez por todas”, del amigo Óscar Sotorrío, el único que ha sido capaz de publicar como blogger invitado en Variable Not Found. ¡A ver si algunos más os animáis, las puertas están abiertas!

Y esto es todo! Espero que os haya resultado interesante para conocer algún artículo que os perdisteis en su momento o para rememorar algunos que os llamaron la atención ;)

Publicado en Variable not found.

» Leer más, comentarios, etc...

Koalite

Mis tecnologías del 2016

January 09, 2017 05:06 AM

Soy un hombre de tradiciones y toca continuar la que inicié el año pasado, a petición de Alfredo, repasando mis tecnologías del 2015. Es además una buena forma de resumir las herramientas que uso actualmente para los que puedan estar interesados en conocerlas.

Al igual que el año pasado, me ceñiré a tecnologías que uso profesionalmente porque son con las que más me he pegado y de las que puedo dar una opinión más formada. También quiero recordar que me dedico a desarrollar productos, no proyectos. Son además productos que llevan años en el mercado y (esperamos) durarán unos cuantos años más, y son instalados en miles de clientes por un montón de distribuidores, sobre un parque de equipos (hardware y software) de lo más heterogéneo. Todo esto hace que andar saltando de tecnología en tecnología sólo porque esté de moda o porque prometa maravillosas mejoras no es para nosotros una opción, así que no esperes grandes cambios ni plataformas ultramodernas de dudoso futuro.

.NET

Seguimos planteándonos la posibilidad de abandonar .NET a medio plazo, así que tratamos de minimizar los nuevos desarrollos sobre esta plataforma.

Eso no quiere decir que no la usemos, al contrario, todos nuestros sistemas de backend están desarrollados en C# y trabajamos con ellos todos los días, pero hemos hecho pocos cambios en esta parte.

Mantenemos nuestro stack de librerías por defecto: NHibernate como ORM, Castle Windsor como contenedor IoC, NUnit para tests y log4net para logging. No siempre las usamos, pero lo normal es que si queremos echar mano de alguna librería de ese tipo, recurramos a ellas.

Puede que haya librerías más actuales para todas esas cosas, pero cuando hemos jugado con ellas tampoco nos han aportado lo suficiente para cambiar. Supongo que si nos dedicásemos a hacer proyectos acotados en el tiempo tendríamos más variedad; en nuestro caso, reescribir partes grandes de una aplicación solo pasar a otra librería más moderna que realmente no te aporta mucho más, es una pérdida de tiempo y dinero.

Miramos de reojo .NET Core con ciertas esperanzas de que nos pueda ser útil algún día y que nuestra migración sea a .NET Core desde .NET Framework en lugar de saltar a plataformas más extrañas para nosotros, pero por el momento lo vemos lejos. Quizá esto se aclare dentro de un tiempo, cuando sea un poco más estable, las herramientas estén más consolidadas y se vea más claro dónde va a acabar todo.

Javascript

Si después de hablar de la inestabilidad de .NET Core te digo que HTML5 y Javascript es nuestra plataforma preferida para desarrollar aplicaciones cliente, seguramente te resulte extraño. La diferencia fundamental es la comparación con las alternativas. Mientras que .NET Core todavía lo consideramos una opción inferior (en nuestro escenario, insisto) a .NET Framework, HTML5 y Javascript nos aporta más que soluciones nativas o multiplataforma como Xamarin, lo que nos compensa en cierto modo la falta de estabilidad.

En la parte de Javascript hay menos uniformidad que en .NET y tenemos algún cadáver en el armario desarrollado con AngularJS que nos da un excelente rendimiento económico y unos cuantos quebraderos de cabeza a la hora de mantenerlo.

Todos los desarrollos nuevos los estamos haciendo desde hace un par de años con ReactJS, que cada vez nos gusta más por la flexibilidad que nos da a la hora de estructurar el código.

El año pasado mencionaba nuestras dudas con React Router, y eso ha acabado desembocando en un cambio hacia minimal-router, una microlibrería que surgió de un ejercicio de diseño en abierto y que estamos usando en producción en un par de aplicaciones.

Otra cosa que no nos acababa de gustar era Material-UI, y aunque la aplicación donde lo usamos sigue empleando ese interfaz de usuario (y no tenemos previsto cambiarla), hemos vuelto a diseños basados en Bootstrap o implementados desde cero por nosotros.

En cuanto a herramientas, las mismas que el año pasado: scripts npm (sin Grunt ni Gulp), mocha, chai, …, en fin, los sospechosos habituales. Como incorporación de este año hemos tenido enzyme para testear componentes de ReactJS que nos ha gustado bastante (aunque en general tratemos de evitar ese tipo de tests).

El año de TypeScript

Es la mayor novedad del 2016 para nosotros, y es algo de lo que todavía no estamos muy convencidos.

De momento tenemos alguna aplicación en producción y estamos desarrollando más con TypeScript, pero, sinceramente, aún no las tengo todas conmigo con respecto a esta tecnología.

Un lenguaje que saca versiones nuevas cada 2 meses, introduciendo cambios semánticos importantes, da un poco de miedo. Si a eso le unes que al usarlo te conviertes automáticamente en ciudadano de segunda dentro del ecosistema Javascript y tienes que pegarte más para poder usar determinadas herramientas y librerías que no están pensadas para TypeScript, es normal que surjan dudas.

Sin embargo, hay que reconocer que sus herramientas, uno de los puntos fuertes de TypeScript, facilitan mucho la vida en otros aspectos. Además son ampliamente soportadas por los editores de texto, lo que permite libertad a la hora de elegir el entorno de desarrollo, que es algo que valoro mucho.

Tal vez alguno os preguntéis por qué no hemos optado por otro tipo de lenguajes, como mi “amado” clojurescript. Estuvimos evaluando algunas alternativas, pero lo cierto es que para elegir un lenguaje de programación hay factores que pesan más que el propio lenguaje.

No hemos hecho grandes cambios en nuestra arquitectura o herramientas para integrar TypeScript y mantenemos las mismas herramientas y liberías que con Javascript, sólo que ahora hay que buscar las definiciones de tipos (algo que no siempre es fácil) y los plugins adecuados para preprocesar los ficheros TypeScript y convertirlos a Javascript, como tsify para browserify o ts-node para ejecutar los tests con mocha.

Aquí siempre echo de menos que el compilador de TypeScript no esté implementado como un plugin de Babel; no sé si es posible, pero simplificaría muchísimo todo.

La relación de amor/odio con webpack

Otra de las novedades de este año para nosotros es webpack. Después de haber pasado por grunt y gulp, y haber acabado con una solución muy ligera basada en scripts npm, utilizar una herramienta como webpack nos genera serias dudas.

Por una parte, es muy atractivo poder gestionar todos los recursos de tu aplicación de una forma homogénea, incluyendo TypeScript, less, imágenes, etc. Que sea posible versionarlos con un hash para gestionar la caché es muy útil, y hay partes que encajan especialmente bien con TypeScript, como el plugin file loader, que a la vez que nos permite aprovechar el pipeline de webpack para gestionar ficheros, nos ofrece un acceso “tipado” a las rutas de los ficheros.

Para gestionar los ficheros css, incluyendo la concatenación de ficheros desde distintas rutas y la consolidación de recursos (imágenes, fuentes, etc.) en una única carpeta, no hemos encontrado una solución mejor.

A cambio, introduce una complejidad excesiva. A esto hay que unirle que la documentación es bastante mala (aunque ya vamos estando acostumbrados a eso) y que vive a caballo entre la versión 1.x y la 2.x (aunque la 2.x parece que ya está más cerca), cada una con sus peculiaridades, lo que contribuye a hacerlo todo aún más confuso.

Pero el principal problema es que es lento. Lentísimo. Hay una parte que es culpa del compilador de TypeScript (que tampoco es lo más rápido del mundo), pero con webpack el problema se exacerba. Acostumbrado a tiempos de décimas de segundo para compilar con Babel y Browserify, pasar a varios segundos con webpack y TypeScript se me hace muy duro.

Al menos gracias a la inestimable ayuda de Dani de la Cruz hemos conseguido que la parte de gestión de css sea lo bastante rápida como para que resulte usable.

Pese a que hemos invertido unas cuantas horas en Webpack y tenemos aplicaciones funcionando con él, no tengo nada claro que se mantenga entre nosotros, o por lo menos que lo haga como solución única para compilar TypeScript. Ahora mismo me inclino más por una mezcla con browserify (u otro sistema rápido) durante el desarrollo y usar Webpack para empaquetar sólo de cara al despliegue… Ya veremos cómo acaba la historia.

Y poco más

En la parte de infraestructura no hemos hecho prácticamente ningún cambio con respecto al año pasado y seguimos usando las mismas herramientas (YouTrack, SVN, Cruise Control.NET, …). Estamos pendientes de novedades y, a título personal, usamos otro tipo de soluciones (Git, Trello, etc.), pero lo cierto es que hasta ahora no hemos encontrado motivación suficiente (dado nuestro escenario) para que nos compense la migración a nivel profesional con todo lo que ello implica.

En cuanto a editores, IDEs, y demás, seguimos utilizando Visual Studio 2013 (no hemos necesitado nada del 2015 y las quejas que hemos leído nos han echado un poco para atrás) y, aunque yo sigo fiel a emacs, VS Code ha entrado con fuerza para desbancar a los Atom y Sublime que usaban algunos.

Si alguno tiene curiosidad por alguna herramienta o tecnología en concreto, puede preguntar en los comentarios: no hacemos nada tan secreto que no se pueda contar ;-)

Posts relacionados:

  1. Mis tecnologías del 2015
  2. Resumen 2016

» Leer más, comentarios, etc...

PHP Senior

Tips: cómo resolver el cálculo de un factorial usando recursividad (PHP7)

January 09, 2017 03:33 AM


Por lo general no es muy común que en PHP, y trabajando con sistemas comerciales, tengamos que implementar soluciones recursivas. Pero como tampoco es imposible, les paso un ejemplo. Tengamos en cuenta que aunque parezca obvio:

a) el problema debe ser "un problema recursivo" (que tenga sentido aplicar la recursividad)

b) cuando se trabaja con recursión, debe existir el caso "resoluble directo", que permite salir de la recursión (o entraríamos en loop infinito).

El ejemplo más clásico es el cálculo de un factorial. Si factorial de 5 se calcula 1 x 2 x 3 x 4 x 5, por lo tanto podemos hacer un método que reciba el número a calcular, y posteriormente se va a ir llamando a sí mismo restando 1, hasta llegar al caso "resoluble directo", es decir 0, posteriormente iniciará el retorno recursivo y haciendo el cálculo "al revés" de la invocación inicial (revisar ejecución al final del ejemplo).

PD: de paso, lo hacemos usando PHP 7 o superior. Si bien en este ejemplo no se aprovecha mucho, está bueno que nos empecemos a acostumbrar a las nuevas funcionalidades que trae (como en este caso, la validación de tipos tanto en el input como en el output).

/**
 * Cómo resolver el cálculo de un factorial usando recursividad
 *
 * factorial de 5 = 1 x 2 x 3 x 4 x 5
 *
 */


class Factorial{
  
    public function 
calcular(int $numero) : int
    {
      
        if (
$numero 0) {
          
            
// entro en la recursividad ...
            
$aux $this->calcular($numero 1);
          
            
$calculo $aux $numero;
            echo 
"$aux * $numero = $calculo \n";
          
            return 
$calculo;
        } else {
            
// caso resoluble directamente ...
            
return 1;
        }
    }
}


$factorial = new Factorial();

echo 
"resultado = " $factorial->calcular(5) . " \n";


// Ejecución

php index.php 

1 * 1 = 1 
1 * 2 = 2 
2 * 3 = 6 
6 * 4 = 24 
24 * 5 = 120 
resultado = 120 

Espero que les resulte útil! ;-) 

Espero todas sus dudas! 


» Leer más, comentarios, etc...

PHP Senior

GIT cambiar el editor por defecto a VIM

January 09, 2017 03:32 AM

A veces cuando usamos git en consola unix / linux queda con un editor por defecto que puede no ser de nuestro agrado. Si vienes usando vim, puedes aplicar esta sintaxis:

git config --global core.editor "vim"

» Leer más, comentarios, etc...

PHP Senior

Frase: "Para algunos autores, la herencia o las clases no son conceptos esenciales para la paradigma de POO"

January 08, 2017 10:34 PM


Frase leída en Wikipedia sobre el lenguaje "Go" de Google:

Alan Kay

"Para algunos autores, la herencia o las clases no son conceptos esenciales para la paradigma de POO, sino más bien un medio de implementación. Existen desde hace tiempo lenguajes orientados a objetos que no admiten clases, sino que se basan en prototipos, como Javascript o Self. Según declaraciones de Alan Kay, creador de Smaltalk, lo esencial del paradigma es el paso de mensajes.6



Lenguaje Go
Go tiene tipos y métodos y permite un estilo de programación orientado a objetos, pero no admite construir jerarquías, es decir, no admite la herencia, que para otros autores sí es un mecanismo esencial de la POO. En Go, el concepto de “interfaz“ es similar al usado en Java: cualquier objeto (value) que cumpla el contrato especificado por una interfaz (sin necesidad de una declaración explícita) obtiene ese tipo. También existen formas de embeber tipos dentro de otros tipos para obtener algo análogo a las subclases. Los métodos de Go son más generales que los de C++ o Java, pueden ser definidos para cualquier tipo de datos no sólo para los registros."

Para los que estamos en la POO desde hace muchos años, da para pensar, no? 

Fuente: Wikipedia, lenguaje de programación Go (creado por Google)

» Leer más, comentarios, etc...

PHP Senior

PHP 7.1: cómo instalarlo en Ubuntu

January 08, 2017 09:21 PM

Para quienes quieren probar PHP 7.1 en Ubuntu, ya que actualmente no está disponible como paquete oficial de instalación, pueden seguir los siguientes pasos:


sudo add-apt-repository ppa:ondrej/php

sudo apt-get update

sudo apt-get upgrade

(optional) sudo apt-get remove php7.0

sudo apt-get install php7.1


Instalación probada en Ubuntu 16.04 LTS sin problemas.

Saludos! 

» Leer más, comentarios, etc...

Adrianistán

Un nuevo lenguaje de programación para juegos

January 08, 2017 12:46 PM

En la inocentada sobre Rust puse un vídeo de Jonathan Blow titulado Ideas about a new programming language for games. En el vídeo, Blow analiza los problemas que presenta C++ para el desarrollo de juegos y por qué según él ni Go ni D ni Rust consiguen mejorar la situación. El lenguaje de programación perfecto para juegos debería tener las siguientes características:

  • Poca fricción
  • Placer por programar
  • Rendimiento
  • Simplicidad
  • Diseñado para buenos programadores

Con poca fricción se refiere a que la tarea de programar no debe añadir mucha complejidad para solucionar problemas que tendríamos si programásemos de la forma más simple posible. Fricción es para él RAII en C++. Fricción es la gestión de errores en Rust. Fricción se entiende como código que no añade significativamente nada pero que es necesario para un correcto funcionamiento. Fricción es rellenar papeleo de Hacienda. Muchos defensores de estas posturas argumentan que en realidad esa productividad perdida se recupera con el tiempo al reducir el número de bugs que pueden ocurrir. Blow dice que según su experiencia en juegos AAA realmente no compensa. Tardas más tiempo solventado bugs potenciales que bugs reales. Su solución no es evitar al 100% este tipo de bugs (como hace Rust) sino habilitar unas herramientas potentes que ayuden a solucionar estos bugs si alguna vez suceden.

Esto se relaciona con el placer por programar. Un lenguaje que te invite a programar, a experimentar, donde te sientas a gusto. Muchos lenguajes han perdido esa esencia. Con el tiempo muchos lenguajes se han ido complicando de forma innecesaria y se han ido volviendo pesadillas. Ruby sería el caso contrario, un lenguaje que conserva ese placer. Pero Ruby no entra en juego por razones obvias de rendimiento.

Con rendimiento básicamente dice que cualquier lenguaje que disponga de GC (recolector de basura) no es válido. Incluso Go, que tiene un GC mucho mejor que Java o la plataforma .NET no lo considera correcto.

Con simplicidad se busca legibilidad y potencia. El lenguaje debe ser uniforme, con cohesión en todos sus elementos.

Y con diseñado para buenos programadores se refiere a que el lenguaje no debe suponer que el programador es idiota e intentar corregir sus errores. Debe permitir hacer virguerías si así lo desea el programador. Rust está bien pues permite tener código unsafe. Justo lo que se necesita para hacer virguerías. Pero hace falta más trabajo en este aspecto pues supone un cambio de mentalidad.

La idea detrás de RAII es incorrecta

Mucha gente opina que RAII es una de las mejores cosas que han pasado en la programación. Muchos lenguajes presuponen RAII. D por ejemplo considera que RAII es la manera correcta de programar. Resource Acquisition Is Initialization consiste en que cada vez que vamos a acceder a un recurso tenemos que codificarlo en una clase, inicializar el recurso en un constructor y liberar el recurso en un destructor. Añades operadores para permitir copia, … Este sistema presenta una elevada fricción. Y además no funciona bien, en el sentido de que todo se acaba sobrecomplicando. Alejándose de esa simplicidad que estamos buscando.

Uno de los principales problemas de este patrón de diseño es que no existe un recurso. Es una generalización errónea de varios conceptos. Un recurso puede ser memoria, otro recurso puede ser un archivo, una entrada de teclado, etc El problema es que estos recursos son demasiado diferentes como para ser tratados con un mismo patrón de forma óptima. Mientras RAII puede ser interesante hablando de archivos, es una muy mala opción si hablamos de memoria. Porque la memoria es el recurso más importante para un programador. Se podría simplificar diciendo que un programador lo único que hace es modificar la memoria constantemente.

Pero muchos de los usos de RAII tienen que ver con las excepciones. Y a Blow tampoco le gustan las excepciones. La gestión de errores en C es pésima pero las excepciones son muy complejas. Una de las cosas más complejas que implementan los lenguajes de programación que disponen de ellas. Y la implementación de C++ más todavía. Blow se lamenta de que haya gente que siga pensando que es una buena idea. Reduce la claridad del código, complica el flujo del programa. RAII en C++ ayuda a que en caso de que se de una excepción los recursos puedan ser liberados.

No solo lo dice él, sino que enlaza el siguiente vídeo: Systematic Error Handling in C++ por Andrei Alexandrescu.


Un mejor sistema que las excepciones

Go implementa múltiples valores de retorno (al contrario que la mayoría de lenguajes derivados de C donde solo de devuelve una cosa). Go lo soporta de forma nativa. Pero Matt Newport le responde como podría hacer eso en C++11 con std::tie.

#include <iostream>;
#include <tuple>;
#include <functional>;
 
std::tuple<int, int> f()
{
    int x = 5;
    return std::make_tuple(x, 7); // return {x,7}; en C++17
}
 
int main()
{
    int a, b;
    std::tie(a, b) = f();
    std::cout << a << " " << b << "\n";
}

Rust, como Go, soporta esto de forma nativa:

fn f() -> (i32,i32) {
	(4,7)
}

fn main() -> () {
	let (a,b) = f();
	println!("A es {}, B es {}",a,b);
}

Aunque no es la manera en la que Rust maneja los errores. En su lugar posee Option y Result que en C++17 también van a ser implementados en std::optional y que es en realidad un concepto presente en Haskell.

Sintaxis exasperante

En la charla Blow sigue hablando y comenta que desde un punto de visto purista y correcto la sintaxis de punteros de C++11 es incorrecta. Que std::unique_ptr<Vector3[]> implica que quieres un Unique Ptr basado en Vector3 pero en realidad la idea correcta sería quiero un Vector3 con características de Unique Ptr. Lo mismo es aplicable para std::shared_ptr. Este tipo de punteros no deberían estar expresados de esta forma sino que deberían entrar en la sintaxis del lenguaje, por su utilidad práctica.

En Rust, el equivalente a std::unique_ptr sería Box que es el puntero más usado. El equivalente a std::shared_ptr sería Rc, no tan usado pero disponible.

Blow sigue hablando en este vídeo y en el siguiente de más errores que tiene C++, aunque de menor importancia. En todo caso, Blow sigue en el desarrollo de su compilador de Jai. C++ ha avanzado un montón y me ha llegado a sorprender que existiesen cosas como constexpr y los módulos de C++, una solución a los archivos de cabecera que son tan tediosos de escribir.

Si tenéis tiempo y sabéis inglés miráos el vídeo original. Creo que esta mucho mejor explicado que esto. Y también la respuesta de Matt Newport en la que dice que C++ SÍ es válido para todo lo que dice Blow.

La entrada Un nuevo lenguaje de programación para juegos aparece primero en Blog - Adrianistan.eu.

» Leer más, comentarios, etc...

Blog Bitix

Artículo #3 de Yo apoyo al software libre

January 06, 2017 09:00 PM

Los últimos meses me han sido bastante buenos en cuanto a los ingresos por la publicidad AdSense y los enlaces de afiliado de Amazon que incluyo en el blog con el objetivo de monetizarlo un poco. Desde luego esos pequeños ingresos no compensan la enorme cantidad de tiempo que requiere escribir un artículo, y no es solo escribirlo sino también editarlo, crear el ejemplo de código si el artículo es sobre programación, sacar las capturas de pantalla e investigar la materia de la que habla el artículo. Otra forma de monetizar el blog que estoy evaluando es escribir artículos patrocinados con la plataforma Publisuites, sin embargo, aún no he recibido ninguna propuesta ya que quizá haya puesto el precio demasiado alto pero escribir un artículo cuesta unas horas de trabajo.

Por la publicidad de AdSense he notado un significativo aumento de ingresos duante los últimos meses del 2016 superando los 20€ mensuales cuando hasta no hace mucho la cifra estaba en unos 10€. En proporción al aumento de número de visitas que ha experimentado este blog en 2016 como comento en el artículo Heroteca #10 donde hago un repaso de ese año. Esto ha hecho que en poco menos de cinco meses Google me haya hecho otra transferencia por importe de unos 75€. Por los enlaces de afiliado también he recibido otro ingreso por parte de Amazon de unos 35€.

Como me he propuesto en anteriores veces que he recibido algún ingreso por el blog he hecho unas pequeñas donaciones a algunos proyectos de software libre. En anteriores ocasiones han sido a la FSFE, Mozilla, Wikipedia y ahora los proyectos que he elegido a los que hacer una donación han sido Elementary OS, LibreOffice (The Document Foundation) y Arch Linux ARM. Aunque muchos usuarios hagan donaciones la viabilidad de estos proyectos no deberían depender de ellas ya que seguro que no cubren los gastos en los que incurran estos proyectos. Algunos de estos gastos son los servidores para prestar el servicio y páginas web, conferencias a las que asisten sus desarroladores y los viajes de estos, seguro que hay unos cuantos más.

Elementary OS

Aunque la distribución GNU/Linux que uso es Arch Linux he elegido donar a Elementary OS porque me parece una distribución interesante por ofrecer algo distinto a las otras muchas distribuciones que existen y no tienen algo diferenciador. Elementary tiene un diseño, estética y usabilidad de interfaz muy cuidada. Arch Linux es la distribución rolling release que se mantiene siempre actualizada y con una gran documentación en forma de wiki. Las versiones LTS de Ubuntu ofrecen soporte durante un periodo largo de tiempo pero cuya interfaz Unity no convence a muchos. Debian, openSUSE y Fedora son otras de las distribuciones grandes y junto con Linux Mint también a tener en cuenta para los usuarios que quieren dar el cambio a Linux. Pero para un recién llegado a GNU/Linux o que simplemente quiere un sistema para trabajar en mi opinión Elementary OS o Linux Mint o una versión LTS de Ubuntu si nos convence su interfaz Unity sea lo recomendable por lo que usar en un primer momento, desde luego no Arch Linux y posiblemente tampoco Debian, openSUSE o Fedora. Espero que Elementary siga desarrollandose y no sea una de las muchas distribuciones que al cabo de unos años es abandonada por falta de interés de sus desarrolladores, falta de éxito o ingresos.

Elementary OS

Libre Office

LibreOffice es el proyecto ofimático que se postula como una de las mejores alternativas ofimáticas a Microsoft Office. Su interfaz, en mi opinión, está saturada de opciones en menús donde es difícil encontrar la funcionalidad que uno necesita siendo parecida a versiones antiguas de Microsoft Office. Sin embargo, en GNU/Linux no hay muchas alternativas ofimáticas tan completas de software libre. Otra alternativa es WPS Office con una interfaz mas cuidada y parecida a Microsoft Office con su interfaz de caja de herramientas ribbon donde es más fácil encontrar las opciones en vez de interminables menús y diálogos de configuración. En LibreOffice me parece tan importante añadir nuevas funcionalidades como mejorar las existentes pero me gustaría que la interfaz fuese mejor, más parecida a la de Microsoft Office si fuese necesario. Parece que están dando los primeros pasos en LibreOffice para evolucionar la barra de herramientas.

LibreOffice

Arch Linux ARM

El tercer proyecto al que he donado ha sido a Arch Linux ARM ya que lo uso en la Raspberry Pi con la que hago la descarga de imágenes de alguna distribución que quiera probar, series, películas y libros mediante P2P. Solo tiene 256MiB de memoria y una CPU de un único núcleo pero son más que suficientes para en una noche descargar cualquier contenido que necesite.

Arch Linux

Comprobantes de las donaciones

Donación Elementary OS
Donación The Document Foundation
Donación Arch Linux ARM

Otros proyectos que me planteo hacer una donación en el futuro son a algún proyecto relacionado con las distribuciones BSD, GNOME o el reproductor VLC. Desde luego no es mucho ni todo lo que recibo como ingresos por la publicidad, sin embargo, espero que ayude a que estos grandes proyectos de software libre sigan mejorando y yo como usuario junto con otros muchos de algunos de ellos disfrutándolos en la totalidad de ellos sin coste alguno en licencias de software.

Hay muchas formas de colaborar con el software libre, donar dinero solo es una de ellas.

» Leer más, comentarios, etc...

Arragonán

Un repaso a mi 2016

January 06, 2017 07:01 PM

Pues ya hemos cambiado de año y no tenía muy claro si escribir algo a modo resumen como en años anteriores, y mucho menos objetivos. Pero oye, que el que salir mencionado al respecto en la bonilista es un buen motivador. Así que al lío.

El primer trimestre del año estuve trabajando con Maubic como contractor haciendo trabajo de backend (node, microservices…) y ayudando a introducir algunos temas de testing, CI… Durante el año he continuado dando soporte a Bichomanía haciendo cositas.

Por otro lado ya estábamos trabajando en la idea de montar los Coding Stones desde principios de año: haciéndonos inception, mucha conversación, ayuda externa… Al fin en Marzo/Abril empezamos con nuestro primer proyecto como banda, durante el año pudimos trabajar en otro, además de hacer trabajos de consultoría y formación. Para mi el estar acompañado de esta gente ha sido (y es) algo que me ha venido la hostia de bien a todos los niveles, lo mejor del año.

En el caso de Outreach Tool, he ido dando soporte puntual a nivel de la web y buscar herramientas. El proyecto ha ido madurando y validando gracias al trabajo del resto del equipo, hemos llegado a un punto donde la limitación es a nivel de producto (un excel), así que en Diciembre decidimos que era el momento de que me pusiera las pilas para desarrollar la aplicación web para hacerlo usable para gente normal.

Además cerramos definitivamente Mhop. Minchador este año ha caído bastante en el olvido y no le he dedicado apenas tiempo. En cambio a mi side-project Mosica le he ido dando cariño a ratos para mejorarlo y resolver un gran problema, el Ayuntamiento de Zaragoza condenó su agenda cultural al ostracismo, sigue publicada como datos abiertos pero tiene una cantidad/calidad de conciertos irrisoria.

En cuanto a viajes… pocos, salvo un par de escapadas, y casi siempre por eventos o trabajo: Estuve en la Qcon London, como voluntario, aproveché para conocer un poco la ciudad. En la BilboStack. Estuvimos todos los Coding Stones de retiro en Alcañiz. En la Tarugoconf. En la Barcelona Software Craftsmanship, donde hice un coding dojo. En Codemotion Madrid donde hablé sobre un proyecto en el que andamos trabajando. En la CAS 2016, donde también hablé, esta vez de equipos indie. En Valencia dando una formación sobre, entre alguna otra cosa, Extreme Programming.

Como se puede ver, este final de año he vuelto a la carretera en cuanto a eventos, llevaba un par en los que sólo presentaba en eventos locales.

Estuve involucrado organizando un nuevo Startup Open Space desde el colectivo CachiruloValley, también moviendo varios FridayDojos y las quedadas de Zaragoza.rb.

En otro (des)orden de cosas:

  • Fui a bastantes conciertos, me quedé con las ganas de ir a otros muchos.
  • He cerrado bares de vez en cuando, pero menos.
  • Entre fútbol sala y fútbol 7 jugué en 3 equipos.
  • Además jugué el torneo de fútbol 7 de mi pueblo, con el equipo de Viejas Glorias y me lo pasé genial.
  • Tuve mis idas y venidas.
  • Disfruté tanto de pilares como de las festas de san roc, pero los años empiezan a pesar.
  • Empecé a entrenar a boxeo.
  • Cambiamos de oficina a una bastante molona.
  • Niko ya no está en la familia. Aún a veces sigo soñando con ello.
  • Hicimos muchas cenas en el Bonanza con los caballeretes.
  • He improvisado bastantes planes, para acabar teniendo un puñado de aventuras y desventuras.
  • Leí una docena de libros, técnicos y no técnicos. Que no es mucho, pero para mi falta de rutina no está mal.
  • Tuve 1 despedida y 3 bodas.
  • No he notado mucha mejora de mis molestias estomacales respecto al año anterior.
  • A algunos amigos los he visto bastante menos de lo que me hubiera gustado.
  • Un día fui a escalar.
  • Me destrocé el cuádriceps jugando a fútbol 7 y aún estoy recuperándome de ello.
  • Volví a participar en Movember.

En conclusión, un año con bastantes luces y algunas sombras, a ver si este hay menos de lo segundo.

Objetivos 2017

Llevo varios años sin marcarme objetivos concretos anuales, mucho menos publicándolos, pero he hecho el ejercicio y aquí van algunos:

  • Continuidad con los Coding Stones. Que nos sigan saliendo proyectos y colaboraciones que nos ayuden a seguir creciendo tanto como grupo como individualmente. Tenemos alguna cosa a la vista con muy buena pinta para ello, a ver si sale.
  • Tener una versión de Outreach Tool en web en el primer trimestre. A partir de ahí ir refinando y ver a dónde somos capaces de llegar a nivel de negocio.
  • Conseguir una rutina de entrenamientos de verdad. Lo que además significaría que me estaría cuidando más.
  • Hacer algún viaje de vacaciones de verdad. Tengo un par de destinos pensados, veremos.
  • Conseguir volver a darle algo más de vidilla a CachiruloValley. ¿Podcast? ¿Eventos?
  • Lanzar la versión 2 de la app móvil de Mosica, y además lanzar algún meta-side-project con un amigo.
  • Volver a mentorizar a 1 o 2 desarrolladores. Este año no hicimos Senpai Devs, el formato que teníamos nos consumía demasiado para que fuera sostenible. Pero me apetece mucho ayudar a gente con menos experiencia de la que seguro que yo también aprendería mogollón.
  • Ir a algún festival de música. Hay un par que llaman mi atención, pero no sé aún.

Y por pedir algo: Salud, para el resto haré lo que pueda.

¡Feliz an nou!

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Cuento: El Test

January 05, 2017 06:35 PM

Desde 2012 con Decreto de Retiro Optativo, que no escribía uno de mis relatos o cuentos. Por motivos obvios, debo excluir el Empieza el día de 2013. Lo cierto es que a principios de 2013, empecé a escribir El Test, pero lo dejé inacabado, hasta recientemente que lo cambié por completo, y lo terminé. No […]

La entrada Cuento: El Test aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Ejemplo con PB/Forms

January 04, 2017 09:00 AM

En el anterior artículo de Classic PowerBasic gratis, BiaNamaran me sugería hacer un pequeño tutorial tipo “Hello World” explicando la filosofía de trabajo de PowerBasic for Windows (PB/Win), y PowerBasic Forms (PB/Forms), unas herramientas que pese a estar valoradas en 80$, podéis conseguir de manera gratuita. Asumiendo que ya hayáis instalado PBWin y PBForms, cosa […]

La entrada Ejemplo con PB/Forms aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Una sinfonía en C#

Novedades de C#7: Funciones locales

December 30, 2016 12:36 PM

Ya hemos visto algunas de las novedaes de C#7 en este espacio y es momento de hablar de las funciones locales.

¿Qué son las funciones locales?

En pocas palabras C#7 nos da la posibilidad de declarar una función dentro de otra…si, dentro de otra, con las ventajas que esto aporta:

  • Visibilidad acotada
  • Acceso a las variables del entorno en que se declara
  • No ensuciamos el código con algo muy específico del contexto que necesitamos

Vamos a ver un ejemplo, imaginemos que tenemos una estructura tipo árbol guardada en una base de datos

image

Simple, cada elemento tiene un padre y así se arma el árbol, del lado de C# tenemos:

class Hoja
{
    public string Nombre { get; set; }
    public int Id { get; set; }
    public IList Hijos { get; set; }
    public Hoja Padre { get; set; }
}

Básicamente tiene el nombre, id, el id del padre y el listado de hijos, lo que queremos hacer es armar un árbol poniendo los hijos, lo natural sería hacer algo recursivo.

void BuscarHijos(Hoja hoja, IEnumerable hojas)
{
    foreach (var hijo in hojas.Where(i => i.Padre.Id == hoja.Id))
    {
        hoja.Hijos.Add(hijo);
        BuscarHijos(hijo, hojas);
    }
}

public IEnumerable Generar()
{
    var hojas = Hoja.GetAll();
    var lista = new List();

    foreach (var item in hojas.Where(i => i.Padre == null)) // buscamos los nodos raíz
    {
        lista.Add(item);
        BuscarHijos(item, hojas);
    }

    return lista;
}

Entonces, primero buscamos aquellas hojas que no tiene padres (son las raices) y después iteramos esa colección y buscamos las hojas que tienen como padre al nodo raíz actual, usamos una función recursiva para buscar hijos de hijos, esto debería funcionar.

Usando funciones locales.

El mismo código con funciones locales se pude hacer así:

var lista = new List();

foreach (var item in hojas.Where(i=>i.Padre == null))
{
    lista.Add(item);
    BuscarHijos(item);

    void BuscarHijos(Hoja hoja)
    {
        foreach (var hijo in hojas.Where(i => i.Padre.Id == hoja.Id))
        {
            hoja.Hijos.Add(hijo);
            BuscarHijos(hijo);
        }
    };
}

Como vemos declaramos la función BuscarHijos no solo dentro del método sino dentro del bucle y acotamos bien su impacto, además tenemos visibilidad de la lista de hojas y de la misma función BuscarHijo, super cool

Hay más detalles sobre las funciones locales en este link, y la propuesta original de la funcionalidad acá.

Nos leemos.

» Leer más, comentarios, etc...

Variable not found

Visual Studio 2017 se llamará finalmente Visual Studio Core 1.0. Y no queda ahí la cosa…

December 30, 2016 08:20 AM

Sin duda, el equipo de marketing de Microsoft es conocido por su gran habilidad y creatividad a la hora de nombrar los nuevos productos que la fábrica de Redmond va lanzando al mercado. Pero no sólo eso, también son realmente buenos sabiendo cuándo hay que hacerlo para conseguir captar la atención y elevar el hype.

Pantalla de inicio de Visual Studio Core 1.0Ya lo demostraron meses atrás con el renombrado de toda nueva pila de tecnologías relacionadas .NET, cuando decidieron cambiar de ASP.NET 5 a ASP.NET Core, una idea que sirvió para centrar las expectativas del producto y entusiasmó a los autores de contenidos (blogs, podcasts, libros, cursos, presentaciones, etc.), sobre todo por lo oportuno de tan estratégico movimiento.

Y el renombrado de la suite de desarrollo por excelencia ya se estaba haciendo de esperar, aunque esta vez no nos ha pillado desprevenidos. De hecho, más o menos era un secreto a voces e incluso había algún leak donde se había adelantado la noticia: Visual Studio 2017 se llamará finalmente Visual Studio Core 1.0, rompiendo así con la tradición de versionarlos según el año de aparición, como se lleva haciendo desde el año 2003.

Ayer mismo se publicó la Release Candidate 2, en la que ya figura el nuevo nombre del producto. También es posible descargar ya las actualizaciones de componentes y herramientas de terceros (como JetBrains, Telerik, Component One, DevExpress y otros) con adaptaciones a estos cambios, así como acceder a documentación y materiales actualizados.

Code Studio VisualComo consecuencia de este cambio, y dado que existe un parecido razonable del nuevo nombre con el popular Visual Studio Code, éste último pasará a denominarse Code Studio Visual, eliminando así toda posibilidad de confusión entre ambos productos, pero manteniendo al mismo tiempo el "aire" de familia entre ellos.

La nueva versión disponible a día de hoy, versionada como 2.0, ya hace efectivo este cambio, como podéis ver en la captura de pantalla adjunta.

Pero la oleada de renombrados en la organización no queda aquí, pues lo mismo ocurre con los servicios para desarrolladores en la nube. Con objeto de hacer más sencilla la adopción de la nueva nomenclatura, los servicios conocidos como Visual Studio Online, que luego pasaron a denominarse Visual Studio Team Services, pasarán ahora a llamarse Visual Studio Core Team Online Services, dejando así más patente su relación con la familia de productos y su enfoque de plataforma completamente online.

Aunque algo más adelante, también se verán afectados los servicios generales en la nube, lo que hasta ahora conocíamos como Microsoft Azure, que pasarán a denominarse Microsoft Cloud Core Services. Sin duda, todo un acierto el eliminar la palabra "Azure", que al fin y al cabo no dice nada, y comunicar más claramente dónde se encuentra la aportación de valor del producto, como ya hacen otros proveedores como Amazon, IBM o Google.

Según Patrick Iñuelas, product manager de Microsoft Naming Core Team (la división de marketing encargada de poner en marcha estos cambios) están ahora trabajando en el próximo paso, que es renombrar Xamarin a Silverlight Core, en palabras textuales, "porque tenemos el nombre de dominio disponible".

¿Y mi opinión respecto a todos estos cambios? Pues, por supuesto, absolutamente favorable. Los nombres anteriores sonaban ya algo añejos y a los jóvenes desarrolladores les sonaba a algo “legacy”; es lógico que cada cierto tiempo haya que hacer un reboot para poner los contadores a cero y comenzar de nuevo. En cuanto a los nombres elegidos, creo que son totalmente acertados porque son fáciles de recordar, tienen gancho, y se alinean correctamente con la tendencia "Core" de los últimos tiempos, dando una imagen mucho más fresca y moderna de los productos.


[Actualizado 30/12] Nota para despistados: pues no, no es una noticia real, simplemente se trata de una broma por el 28 de diciembre, día de los inocentes en España. Visual Studio 2017 seguirá llamándose así, Azure no cambiará de nombre, y tampoco Xamarin... al menos de momento ;D

Publicado en Variable not found.

» Leer más, comentarios, etc...

Poesía Binaria

El 2016 para Poesía Binaria. Estadísticas, agradecimientos, redes y SQL. Y sólo es el principio

December 29, 2016 09:10 AM

2016-resumen

Ya va acabando el año y, como siempre hago un balance de las estadísticas del blog que comparto con todos vosotros, con algún detalle friki de los que me gustan (como consultas SQL que podríamos hacer todos en nuestro WordPress).

¡Este año el blog no me ha costado dinero!

Y estoy muy contento y orgulloso. Aunque todavía no es un blog rentable. No lo hago por dinero, lo hago porque me ayuda a aclarar mis ideas, me resulta interesante tener una chuleta cuando descubro algo interesante, o cuando paso horas intentando echar a andar un programa, me gusta tener una documentación a mano. Además, intento detallar lo más posible, precisamente porque seguro que dos semanas después de solucionar un problema, no tengo ni idea de cómo lo hice, ni de los pasos que di para llegar a un determinado punto.

Pero ese no es el tema, este año, gracias a que he sido embajador de Siteground, he realizado varios posts patrocinados y por fin, después de 7 años de vida, este año el servidor me ha salido gratis y con lo que me ha sobrado, aprovecharé para hacer una pequeña mejora en el servidor para alojar algunos proyectos personales.

Redes sociales

En Facebook, el 1 de enero de 2016 tenía 651 me “Me gusta”, y a 21/12/20216, hay 818 por lo que, ¡la familia crece! Aunque se han marchado 16 personas. Asiduamente muevo los posts a través de la página, y grupos de programación, por lo que muchos vienen de ahí. En Facebook no sólo publico posts míos, también comparto algunas publicaciones que me parecen interesantes, incluso memes relacionados con la programación.
Aquí van las 5 publicaciones que más éxito tuvieron en Facebook:

En lo que respecta a Twitter, he pensado en hacer un Twitter especial para el blog, y separarlo en cierto modo de mi cuenta personal, aunque la programación y la tecnología es una parte muy importante de mi vida, y creo que compartiría aún muchos contenidos similares en las dos cuentas (aunque claro, seguro que si envío algún mensaje a una empresa, programa de televisión o una fotografía de algo que me llame la atención, puede que no le interese a quien sólo me siga por la tecnología). Es una asignatura pendiente. De todas formas, este año, tengo que agradecer especialmente a @Ibermatica_RRHH, @juanfortuna, @jvareblog, @4GeeksLA, @alexcbandera, @maxezek1 (no estáis todos, este año sois muchos los que habéis interactuado por Twitter, y esta es sólo una pequeña muestra. Tengo que automatizar un poco el proceso y las métricas todavía).

Google+… intento meterme, y publicar cosas allí, pero a pesar de los cambios en la interfaz sigue sin llamarme mucho la atención. Sé que para el SEO es bueno, pero siento que entro en una fiesta en la que no conozco a nadie y cuando veo alguna cara que me suena, es un holograma…

Estoy abierto a colaboraciones, aunque este año no he publicado ningún post invitado, podéis contactar conmigo libremente, os haré una mención, os moveré el post por redes sociales, colocaré un link y seguro que será bueno para los dos.

Es más, este año he empezado a animarme de nuevo a escribir posts en otros blogs. Tengo algunas colaboraciones pendientes, pero empecé con esta en DesdeLinux: 5 maneras de desconectar y conectar un dispositivo USB sin retirar las manos del teclado.
Además, estoy guardando como privados todos aquellos posts que haga como invitado, porque en el pasado hice varias colaboraciones en blogs que ya no existen y a mí no me gusta tirar nada.

Lo más visitado

Los que ya me conocéis, sabéis que soy un cabezón y no utilizo Google Analytics, pero utilizo Piwik para contabilizar las visitas. Estos son los 5 posts más visitados este año:

  1. Bucles y cursores en MySQL con ejemplos. Sube desde la quinta a la primera posición este año.
  2. Listar archivos dentro de un directorio o carpeta en C
  3. Creando un servidor que acepte múltiples clientes simultáneos en C
  4. Introducción a Timer y TimerTask en Java
  5. Separar palabras de una cadena de caracteres en un array [ C ]

Este año ha sido más variado, pero las visitas que entran de buscadores siempre suelen ser consultas similares.

Lo más comentado

Para conocer lo más comentado en el blog hice lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
SELECT WPC.comment_post_ID AS Post_id,
   COUNT(WPC.comment_post_ID) AS Comments,
   WPP.post_title AS Title
FROM wp_comments WPC LEFT JOIN wp_posts WPP ON WPC.comment_post_id=WPP.ID
WHERE WPC.comment_date>='2015-01-01' AND
   WPC.comment_date<'2016-01-01' AND
   WPC.comment_approved=1 AND
   WPC.comment_type<>'trackback' AND
   WPC.comment_type<>'pingback'
GROUP BY Post_id
ORDER BY Comments DESC
LIMIT 5;

Y obtuve esta lista:

Lo más buscado dentro de Poesía Binaria

  • imagemagick (11%)
  • bmp (3%)
  • magento (2%)
  • servidor (2%)
  • fecha (1%)

Es el buscador interno, y casi siempre la gente busca en Google. Yo nunca le he tenido gran estima, pero se han hecho algo más de 1000 búsquedas.

Búsquedas externas

Estas son las palabras clave que vienen de buscadores, sobre todo Google, Bing y Duck Duck Go (en este orden), aunque Google gana de calle como buscador preferido:

  • timer java
  • for en bash
  • for en mysql
  • expresiones regulares en c
  • eliminar elemento array php

Esto se mantiene casi como estos años atrás, aunque las expresiones regulares en C están ganando terreno… tendré que dedicar algún post más a la causa.

Navegadores más usados

  • Google Chrome (70%)
  • Mozilla Firefox (23%)
  • Safari (3%)
  • Opera (1%)

Ya no suele entrar gente con Internet Explorer o Microsoft Edge. Y Google Chrome gana posiciones.

Sistemas operativos

  • Windows (61%)
  • GNU/Linux (cualquier distribución) (17%)
  • Android (10%)
  • Mac OSX (5%)

Aunque las posiciones se mantienen, Windows pierde un 1%, las distribuciones de GNU/Linux pierden 2% y Android sube.

Enlaces entrantes

Dejando fuera entradas desde buscadores, Facebook, Twitter y otras redes sociales. Desde estas páginas he recibido más visitas:

Países

  • España (47%)
  • Mexico (16%)
  • EEUU (9%)
  • Argentina (6%)
  • Colombia (6%)

Las visitas de Latinoamérica han caído un poco y Estados Unidos entra con fuerza. Pero casi todo mi público proviene de España.

Horas más visitadas

  • 11:00 – 12:00 (7.1%)
  • 12:00 – 13:00 (7.1%)
  • 10:00 – 11:00 (6.6%)
  • 16:00 – 17:00 (6.4%)
  • 13:00 – 14:00 (6.3%)

Otras curiosidades

Este año se han publicado 89 posts y 5 páginas (1.8 por semana, aunque muy lejos de mi reto de 150 este año) de los cuales 51 de ellos contienen código y 20 de ellos ejemplos de uso de terminal (con el plugin SimTerm, que lo liberé este verano, por lo que no se cuentan todos los posts con ejemplos). Además, he modificado 26 posts de años antetiores.

En total 260 fragmentos de código (3 menos que el año pasado, aunque no he contado los de este post). De los cuales:

  • 71 son de C
  • 69 son de BASH
  • 46 son de PHP
  • 45 son de C++

Cada post tiene una media de 1527.4886 palabras o unas 11510.2386 letras, ¡cómo me enrollo!. También he publicado 732 enlaces (algo menos del doble que el año pasado) de los cuales 304 son internos (428 externos).

Los posts más largos

Posts más cortos

Y los posts más cortos (no recopilatorios):

Anexo MySQL

Muchas estadísticas las he sacado consultando la base de datos, aquí os pongo las consultas utilizadas:

Total de posts en el año

1
2
3
4
5
6
SELECT post_name,post_status,post_title
FROM wp_posts wpp
WHERE post_type = 'post' AND
    post_status NOT LIKE '%draft' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01';

Posts que contienen código

Utilizo un plugin que utiliza el shortcode [ cc ] … [ /cc ] para colorear el código, con la consulta detecto dónde se ha llamado:

1
2
3
4
5
6
7
SELECT post_name,post_status,post_title
FROM wp_posts wpp
WHERE post_type = 'post' AND
    post_status NOT LIKE '%draft' AND
    post_content LIKE '%[/cc%' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01';

Posts que usan simterm

En este caso es igual pero con el shortcode [ simterm ]

1
2
3
4
5
6
7
SELECT post_name,post_status,post_title
FROM wp_posts wpp
WHERE post_type = 'post' AND
    post_status NOT LIKE '%draft' AND
    post_content LIKE '%[/simterm%' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01';

Páginas publicadas

1
2
3
4
5
6
SELECT post_name,post_status,post_title
FROM wp_posts wpp
WHERE post_type = 'page' AND
    post_status NOT LIKE '%draft' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01';

Contar letras y palabras

Para determinar el número de palabras en el post, se han contado las letras del post con espacios y sin espacios. No es la forma más precisa, pero nos da una idea.

Media de letras y palabras:

1
2
3
4
5
6
7
SELECT AVG(LENGTH(post_content)),
   AVG(LENGTH(post_content) - LENGTH(REPLACE(post_content, ' ', ''))+1) AS Words
FROM wp_posts wpp
WHERE post_type = 'post' AND
    post_status NOT LIKE '%draft' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01';

Total de fragmentos de código

1
2
3
4
5
SELECT SUM(LENGTH(post_content) - LENGTH(REPLACE(post_content, '[ /cc]', '')))/CHAR_LENGTH('[ /cc]') AS Codes FROM wp_posts wpp
WHERE post_type = 'post' AND
    post_status NOT LIKE '%draft' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01';

Contar enlaces

1
2
3
4
5
6
SELECT SUM(CHAR_LENGTH(post_content) - CHAR_LENGTH(REPLACE(post_content, '<a href=', '')))/CHAR_LENGTH('<a href=') AS Links
FROM wp_posts wpp
WHERE post_type = 'post' AND
    post_status NOT LIKE '%draft' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01';

Posts más largos

1
2
3
4
5
6
7
8
SELECT post_title,
    LENGTH(post_content) AS Chars,
    LENGTH(post_content) - LENGTH(REPLACE(post_content, ' ', ''))+1 AS Words
FROM wp_posts wpp WHERE post_type = 'post' AND
    post_status NOT LIKE '%draft' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01';
ORDER BY Words DESC LIMIT 5;

Posts más cortos

1
2
3
4
5
6
7
8
9
SELECT post_title,
   LENGTH(post_content) AS Chars,
   LENGTH(post_content) - LENGTH(REPLACE(post_content, ' ', ''))+1 AS Words
FROM wp_posts wpp WHERE post_type = 'post' AND
   post_status NOT LIKE '%draft' AND
    post_date>='2016-01-01' AND
    post_date<'2017-01-01' AND
   post_content NOT LIKE 'BITes%'
ORDER BY Words ASC LIMIT 5;

Mis posts recopilatorios suelen tener BITes al principio del título, por lo que aquí los descarto.

Posts de otros años modificados este 2016

1
2
3
4
5
6
7
SELECT ID, post_name
FROM poesia_posts
WHERE post_modified>='2016-01-01' AND
   post_modified<'2017-01-01' AND
   post_date<'2016-01-01' AND
   (post_type='page' OR post_type='post') AND
   post_status NOT LIKE '%draft%';

The post El 2016 para Poesía Binaria. Estadísticas, agradecimientos, redes y SQL. Y sólo es el principio appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin