ECMAScript 6: Funciones flecha gruesa

Seguimos la serie de artículos dedicados a ECMAScript 6, en este caso con las funciones arrow, funciones flecha o funciones de flecha gruesa. Esta novedad consiste en una sintaxis abreviada para la expresión de función. Además vinculan el valor this contextualmente.

La cuestión de la sintaxist abreviada es simple si vemos un ejemplo:

var a = [
  "Peras",
  "Manzanas",
  "Naranjas",
  "Melones"
];

//Sintaxis de toda la vida
var a2 = a.map(function(t){ return t.length });

//Sintaxis con flecha
var a2 = a.map( s => s.length );

El tema del this contextual es algo más complejo. Seguramente recuerdes que la variable this daba a veces muchos dolores de cabeza ya que pertenecía sólo a un contexto, es decir, cada función definía su propio valor de this. Vamos con un ejemplo de como sería el código old-school:

function Miembro() {
   // Este this es una instancia del constructor Miembro()
   this.experiencia = 0;
   setInterval(function aprender() {
      // Y este this de debajo sería
      //una instancia de la función aprender(),
      //por tanto no podemos usarlo fuera de
      //la función de callback
      //y nos podría generar errores
      this.experiencia++;
   }, 5000);
} 

Teníais la opción de cachear el this dentro de una variable:

function Miembro() {
   var that = this;
   that.experiencia = 0;
   setInterval(function aprender() {
      // Y este this de debajo sería
      //una instancia de la función aprender(),
      //por tanto no podemos usarlo fuera de
      //la función de callback
      that.experiencia++;
   }, 5000);
} 

Otra opción era usar la función bind() para vincular dicha función a this.

Pero con la función de flecha gruesa la cosa es mucho más simple:

function Miembro(){
  this.experiencia = 0;
  //y aquí va la magiar!!!!
  setInterval(() => {
    this.aexperiencia++; //no es un this nuevo, sino que
                       //hace referencia al this de Miembro()
  }, 5000);
}

ECMAScript 6: valores por defecto en las funciones Javascript

Muchos lenguajes permiten definir un valor por defecto en la llamada a una función, pero hasta ahora Javascript no era uno de ellos. Esto cambia con ECMAScript 6, donde podremos hacerlo al igual que en PHP o Python. Os pongo un ejemplillo simple

function EjemploJS(variable="ejemplo"){...}

Esto implicaría que si no se le pasa la variable variable entonces por defecto se aplicará el valor definido en la declaración de la función. Es bastante cómodo porque nos evita hacer pirulas tipo usar un OR cuando la variable viene vacía, que es lo que haríamos en el pasado:

function EjemploJS(variable){
    variable = variable || "ejemplo"
/*lograría el mismo efecto
pero el código es menos limpio*/
}

Próximamente seguiremos con el tema de ECMAScript 6, al que ya dedicamos antaño otra entrada.

Las palabras reservadas let y const en javascript

No conocía la existencia de let, la descubrí ayer porque había usado una variable llamada let en un artículo de 2011 que hablaba sobre cómo validar un DNI con javascript, y me comentaron «let es una palabra reservada«. Mi cara fue como ¿ein? ¿desde cuando? Así que me puse a buscar… y sí, desde la irrupción de ECMAScript 6 en junio de 2015 tenemos una palabra reservada para definir variables que es let,  otra que es const para las constantes.

Sobre const no hay mucho que decir ya que el nombre es muy descriptivo: nos permite definir una constante. ¿Qué es una constante? Pues piensa en una variable pero que sólo puede recibir un valor en el momento de su declaración y que luego ya no puede ser modificada. Te pongo un ejemplo:

/*Declaramos PI como constante*/
const PI = 3.1415926;

/*Esto daría error*/
PI = 3.1416;
/*Porque no se puede volver a dar*/
/*valor a una constante*/

Vamos ahora con let, que tiene más chicha. Citando textualmente la documentación permite declarar variables limitando su alcance (scope) al bloque, declaración, o expresión donde se está usando. ¿Qué diferencia hay con var? Que var nos permite declarar una variable global o una variable local dentro de una función, pero no nos permite limitar su ámbito a un bloque de código concreto. Veamos un ejemplo:

/*Hagamos el ejemplo al viejo estilo*/
/*usando var*/
function PruebaVar() {
  var v = 45;
  if (true) {
    var v = 64;  // es la misma variable
    console.log(v);  // imprime 64
  }
  console.log(v);  // imprime 64
}
/*vemos como el v de dentro del bloque y el de fuera son
la misma variable. Si modificamos su valor dentro del bloque
fuera también está modificado */

/*vamos con let*/
function PruebaLet() {
  let l = 45;
  if (true) {
    let l = 64;  // diferente ámbito
    console.log(l);  // imprime 64
  }
  console.log(l);  // imprime 45
}
/*Con let en cambio la variable l de fuera del
bloque y la de dentro son tomadas como variables
diferentes, y cada una conserva el valor que
se le dio en su ámbito.*/

El uso de let y const sólo está disponible en bloques envueltos en una etiqueta <script type="application/javascript;version=1.7"> o en una versión superior.

Código PHP para comprobar si un servidor está funcionando o caído.

Estaba los día pasados liado con un desarrollo en PHP para uso interno en la oficina que requería que, en un punto dado, el código recogiera qué servidores de los clientes están activos y cuales no.

Tras sucesivas búsquedas y documentación llegué a dos soluciones. Esta primera lo que haría sería mostrarnos si en una máquina está funcionando el servidor web:

/*La función recibe la ip
o la url del servidor*/
function testServidorWeb($servidor) {
    $a = @get_headers($servidor);
    
    if (is_array($a)) {
        return true;
    } else {
        return false;
    }
}

En este primer ejemplo creamos una función que recibe o la ip externa o la url del servidor que queremos comprobar que tiene su servidor web funcional. Dicha función hará una petición HTTP al servidor y recogerá las cabeceras de la respuesta con get_headers. En caso de que haya recibido la respuesta la función devuelve true, y si no ha habido respuesta alguna entonces devuelve false.

En el segundo ejemplo tenemos una función que comprueba si se recibe respuesta desde un puerto concreto. Así podemos comprobar varios servicios como el servidor web, el servidor ftp, la conexión por telnet…

function checkPuerto($dominio,$puerto){
    $starttime = microtime(true);
    $file      = @fsockopen ($dominio, $puerto, $errno, $errstr, 10);
    $stoptime  = microtime(true);
    $status    = 0;
 
    if (!$file){    
        $status = -1;  // Sitio caído
    } else {
        fclose($file);
        $status = ($stoptime - $starttime) * 1000;
        $status = floor($status);
    }
    
    if ($status <> -1) {
        return true;
    } else {
        return false;
    }
    
}

En este caso le enviamos a la función el dominio del servidor a probar y el puerto que queremos chequear, sirviéndonos de la función fsockopen de PHP. Ojo si queréis comprobar los sockets UDP, que podéis recibir un falso positivo debido a que UDP es un protoclo «sin conexión» (en el enlace a fsockopen ya hay un aviso donde lo explican).

CSS: el pseudo-elemento ::selection

¿Quieres definir un estilo para el texto seleccionado? ¿que el color de fondo sea verde moco? ¿que la leta se ponga en añil? Con CSS esto es posible utilizando el pseudo-elemento ::selection.

Debemos empezar recalcando que ::selection no pertenece a la especificación standar de CSS3 (estaba presente en los borradores, pero se eliminó de la especificación final), por tanto no está garantizado su funcionamiento en todos los navegadores. A pesar de eso tiene bastante compatibilidad, al menos con los navegadores para sistemas operativos de escritorio (y por otra parte, en un dispositivo móvil no es muy habitual andar seleccionando texto, al menos en mi caso). En caniuse podéis comprobarlo.

Si habéis ojeado el enlace anterior veríais que además en el caso de Firefox hay que usarlo con el prefijo -moz. En todo caso, este pseudo-elemento sólo acepta un pequeño grupo de reglas CSS: color, background, background-color y text-shadow. Ojo con querer utilizar una imagen de fondo, porque background-image será ignorado, igual que el resto de reglas que no sean las cuatro antes citadas.

Vamos con un ejemplillo de cómo funciona esto. Para ello usaremos nombres de clase llamados ejemploN a los que sumaremos el pseudo-elemento:

/*Empezamos por el color de fondo, gris*/
.ejemplo1::selection{
    background-color:#555555;
}
.ejemplo1::-moz-selection{
    background-color:#555555;
}
/*Ponemos la letra en rojo*/
.ejemplo2::selection{
    color:#FF0000;
}
.ejemplo2::-moz-selection{
    color:#FF0000;
}

/*Ponemos la letra en negro y el color de fondo gris claro*/
.ejemplo3::selection{
    background-color:#cccccc;
    color:#000000;
}
.ejemplo3::-moz-selection{
    background-color:#cccccc;
    color:#000000;
}

/*Le ponemos sombra al texto seleccionado*/
.ejemplo4::selection{
    text-shadow: 1px 1px 0 #27ae60;
}
.ejemplo4::-moz-selection{
   text-shadow: 1px 1px 0 #27ae60;
}

Puede ser un efecto interesante, pero repito que no forma parte de la especificación, no es un standar y por tanto puede que en un futuro de problemas o no funcione correctamente. Nos tocará esperar.

CSS3 Media Queries para Moto 360 Watch

Si el otro día os comentaba que había estado ojeando el tema de las media queries para los dispositivos de Apple, vamos ahora con el wearable de Motorola. ¿Qué resulución usaría en CSS para este dispositivo? Pues esta:

@media 
  (max-device-width: 218px)
  and (max-device-height: 281px) { 
/*Aquí lo que toque*/
}

Conforme me vaya enterando de más dispositivos los iré compartiendo por aquí.

Media Queries para Apple Watch

Minientrada sobre CSS (y maquera muy a mi pesar) rápida mientras cocino una más musical para esta semana. ¿Cuál sería el tamaño de pantalla en una media query para aplicar un estilo CSS concreto a algo que se visualice en un dispositivo Apple Watch (aka El Reloj Manzanita)? Pues segú veo en github sería lo siguiente:

@media
  (max-device-width: 42mm)
  and (min-device-width: 38mm) { 
/*Aquí el código css a implementar*/
}

Si me voy enterando de otros dispositivos os los iré anunciando.

Creando una tabla con los bordes redondos con CSS3

¿Cómo puede redondear los bordes de una tabla con CSS? Ponerle bordes al objeto table o al tr no va a funcionar, hay que hacerlo sobre el primer o el último td de la fila.

table { border-collapse: separate; }
td { border: solid 1px #000; }
/*PARA LA PRIMERA FILA TIENES DOS OPCIONES*/
/*Así sería la cosa
si has empezado con un tr
*/
tr:first-child td:first-child { border-top-left-radius: 10px; }
tr:first-child td:last-child { border-top-right-radius: 10px; }
tr:first-child td:only-child { border-top-right-radius: 10px;
border-top-left-radius: 10px; }
/*si en lugar de eso has usado la etiquetas thead y th es más
sencillo todavía*/
th:first-child { border-top-left-radius: 10px; }
th:last-child { border-top-right-radius: 10px; }
th:only-child { border-top-right-radius: 10px;
border-top-left-radius: 10px; }

/*Y ASÍ PONEMOS EL PIE*/
tr:last-child td:first-child { border-bottom-left-radius: 10px; }
tr:last-child td:last-child { border-bottom-right-radius: 10px; }
tr:last-child td:only-child { border-bottom-right-radius: 10px;border-bottom-left-radius: 10px; }

Clase para prevenir ataques XSS en Java

Buscando información para aumentar la seguridad de una aplicación web basada en Java me encontré con esta clase para filtrar los posibles ataques XSS en la web de un veterano ingeniero llamado Ricardo Zuasti.

Su solución propone dos clases. La primera, que copio de su entrada original a continuación, lo que hace es filtrar las peticiones HTTP para que sean filtradas por la clase especializada creada para eso:

public class XSSFilter implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
 
    @Override
    public void destroy() {
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
        chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
    }
 
}

Tras esto propone la siguiente clase para realizar el filtrado. Esta clase sobreescribe los métodos getParameterValues(), getParameter() y getHeader() y utiliza una serie de patrones para evitar la entrada de código malicioso en tu web. El método stripXSS() es el que realiza la labor de filtrado.

import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
 
public class XSSRequestWrapper extends HttpServletRequestWrapper {
 
    private static Pattern[] patterns = new Pattern[]{
        // Script fragments
        Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
        // src='...'
        Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        // lonely script tags
        Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
        Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        // eval(...)
        Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        // expression(...)
        Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
        // javascript:...
        Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
        // vbscript:...
        Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
        // onload(...)=...
        Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)
    };
 
    public XSSRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
    }
 
    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);
 
        if (values == null) {
            return null;
        }
 
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = stripXSS(values[i]);
        }
 
        return encodedValues;
    }
 
    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
 
        return stripXSS(value);
    }
 
    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        return stripXSS(value);
    }
 
    private String stripXSS(String value) {
        if (value != null) {
            // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
            // avoid encoded attacks.
            // value = ESAPI.encoder().canonicalize(value);
 
            // Avoid null characters
            value = value.replaceAll("\0", "");
 
            // Remove all sections that match a pattern
            for (Pattern scriptPattern : patterns){
                value = scriptPattern.matcher(value).replaceAll("");
            }
        }
        return value;
    }
}

Entre las recomendaciones que da en el artículo original está la de configurar este filtro como el primero en tu web.xml y también, en referencia al código que aparece comentado en la segunda clase, echarle un ojo a la librería ESAPI, que nos proporciona diversas soluciones de seguridad.

Desde aquí sólo me queda enviarle mi agradecimiento por su trabajo al señor Zuasti y animarle a recuperar su blog, que tiene material interesante pero hace tiempo que no actualiza.

Dar formato a un float para mostrar sólo dos decimales en Python

A la hora de trabajar con números decimales en cualquier lenguaje nos topamos con la necesidad de darles un formato adecuado en muchas ocasiones (por ejemplo si trabajamos con valores monetarios, con estaturas, etc) para presentar un resultado en pantalla. El más habitual es recortar o redondear los decimales para mostrar sólo dos. ¿Cómo podemos hacer esto en Python? Con la función format() y los operadores de formateo de cadenas es muy simple:

#Formateamos 5.1234554321
print "{0:.2f}".format(5.1234554321)
#El resultado sería
>>5.12
#¿Y si queremos tres?
print "{0:.3f}".format(5.1234554321)
#El resultado sería
>>5.123