Translate
domingo, 25 de febrero de 2018
Que es machine learning?
Encontre un post de la gente de codecademy que esta muy bueno. Este post trata de explicar ¿qué es el aprendizaje automático, quién debe aprenderlo y cuándo puedo visitar Westworld?
El aprendizaje automático evolucionó a partir del reconocimiento de patrones y la aplicación de algoritmos que pueden aprender de los datos y luego hacer predicciones, y está estrechamente relacionado con las estadísticas computacionales. Esto nos indica el post.
Sin más que aconsejarlos que lo lean dejo el link:
http://news.codecademy.com/what-is-machine-learning/?utm_source=customer.io&utm_medium=email&utm_campaign=fortnightly_2-22-18&utm_content=whatismachinelearning
miércoles, 21 de febrero de 2018
Libros Gratuitos!!!
Quiero compartir un mail que me llego de java code geeks con unos libros gratuitos:
martes, 20 de febrero de 2018
Un resumen de Scala for the Impatient, parte 37
Los métodos apply y update
En scala podemos extender la sintaxis de llamada de funciones :
f(n1, n2, n3, …)
Si f es una función o un método, se ejecuta. De lo contrario, se
llama al método apply por lo tanto es equivalente a llamar a
f.apply(n1, n2, n3, …)
De la misma manera si se utiliza la notación de función con
asignación se llama al método update :
f(n1, n2, n3, …) = value
Es similar a llamar a :
f.update(n1, n2, n3, …, value)
Este mecanismo es utilizado en arrays y maps :
val scores = new scala.collection.mutable.HashMap[String, Int]
scores("Bob") = 100 // es como llamar a
scores.update("Bob", 100)
val bobsScore = scores("Bob") // es como llamar a
scores.apply("Bob")
El método apply también es usado para retornar instancias de
objetos, sin tener que llamar al constructor con el new :
class Fraction(n: Int, d: Int) {
}
object Fraction {
def apply(n: Int, d: Int) = new Fraction(n, d)
}
De esta manera podemos hacer lo siguiente:
val result = Fraction(3, 4) * Fraction(2, 5)
Extractors
Un extractor es un objeto que puede desaplicar un método. Se puede
pensar esto como el método contrario a el apply. Por ejemplo si el
apply agrega un elemento a una lista el extractor debería quitar
este elemento.
Por ejemplo el objeto Fraction tiene un método apply que retorna una
Fraction a partir de un numerador y un denominador. El extractor
debería retornar un numerador y un denominador a partir de una
Fraction.
object Fraction {
def unapply(input: Fraction) =
if (input.den == 0) None else Some((input.num, input.den))
}
Por lo general el método unapply retorna un Option dado que puede
haber un error cuando queremos desaplicar un método. En el ejemplo
si el denominador es 0 retorna None.
val Fraction(a, b) = f;
val tupleOption = Fraction.unapply(f)
if (tupleOption == None) throw new MatchError
// tupleOption is Some((t1 , t2))
En el ejemplo el método apply y unapply son inversos pero esto no es
obligatorio.
Graylog, guarda y consulta tus logs de forma centralizada.
Graylog es un producto que permite consultar y almacenar registros de aplicaciones de forma centralizada y eficiente. Para esto utiliza MongoDB para almacenar los log y Elasticsearch para la búsqueda e indexación.
Con Graylog se puede guardar los registros de forma
centralizada, detectar problemas de manera temprana y de esta manera resolverlos
más rápidamente.
A la vez Graylog provee un sistema de administración de
registros con el cual se puede consultar registros de forma interactiva y
rápida y permite almacenar registros de diferentes servidores, dispositivos de
red y aplicaciones.
De esta forma este producto permitirá auditar la aplicación
de forma económica y eficiente. Permitiendo a los auditores ganar tiempo y centralizarse
en su trabajo en vez de envolverlos en problemas técnicos.
lunes, 19 de febrero de 2018
MongoDB 4.0 incluye transacciones de múltiples documentos
MongoDB 4.0 incluye transacciones de múltiples documentos. Eso es todo. Toda la info...
Pero si no sabes:
El soporte para transacciones de documentos múltiples, es una técnica para el aislamiento de instantáneas a menudo asociada con las bases de datos relacionales PostgreSQL y Oracle. Y es la piedra angular ACID
MongoDB 4.0 ofrecerá la capacidad de realizar una lectura consistente. Es decir, devolverá solo los datos como se conocía en el momento en que comenzó la operación de lectura. Las versiones anteriores de MongoDB podían arrojar resultados que no necesariamente eran consistentes con ningún punto en el tiempo. Incluso podría omitir documentos o devolver varias versiones del mismo documento en una sola consulta. Pero esto ahora cambio.
Dejo link:
http://www.zdnet.com/article/mongodb-cto-how-our-new-wiredtiger-storage-engine-will-earn-its-stripes/
Pero si no sabes:
El soporte para transacciones de documentos múltiples, es una técnica para el aislamiento de instantáneas a menudo asociada con las bases de datos relacionales PostgreSQL y Oracle. Y es la piedra angular ACID
MongoDB 4.0 ofrecerá la capacidad de realizar una lectura consistente. Es decir, devolverá solo los datos como se conocía en el momento en que comenzó la operación de lectura. Las versiones anteriores de MongoDB podían arrojar resultados que no necesariamente eran consistentes con ningún punto en el tiempo. Incluso podría omitir documentos o devolver varias versiones del mismo documento en una sola consulta. Pero esto ahora cambio.
Dejo link:
http://www.zdnet.com/article/mongodb-cto-how-our-new-wiredtiger-storage-engine-will-earn-its-stripes/
jueves, 15 de febrero de 2018
Top de lenguajes que tenes que aprender en el 2018
Me encontre un post sobre los lenguajes que debes aprender este 2018, si no lo sabes. Y en resumen los lenguajes son los siguientes :
- JavaScript
- TypeScript (si bien no es un lenguaje, es un framework que suma características a un lenguaje, por lo tanto es valido)
- Python
- Java
- Kotlin
- C & C++
- PHP
- Swift
- Scala
Lindo ranking veo algunos lenguajes viejos, pero salvo algunos puntos, estoy de acuerdo.
martes, 13 de febrero de 2018
Un Post sobre el blog!
Tarde o temprano le tenía que tocas al blog hablar de el mismo. Por lo tanto te paso unos datos recopados del blog que no te van a servir de nada. Tal vez podes tirar estos datos en una reunión familiar, pero no se, velo...
- El blog nace en julio del 2009 y los primeros post eran publicaciones de tp de la facultad.
- El año que viene cumplimos 10 años. Me acabo de dar cuenta
- Tenemos publicados 1815 post, con este 1816.
Los temas son variados pero por lo general Java, Linux, Scala, es decir lenguajes de programación y software libre.
Les paso un gráfico:
Si no lo ven muy bien hagan click y se agranda (eso le digo a las chicas) , se los prometo.
Si clasificamos a el blog por tag tendremos el siguiente top ten (quitando a otros)
Y eso es todo amigos...
Si tienen preguntas, en los comentarios.
Ah, y notaron que hay un botón para donar dinero?
Si clasificamos a el blog por tag tendremos el siguiente top ten (quitando a otros)
- Java
- Linux
- Scala
- Python
- javascript
- Ruby
- Apache
- php
- C++
- Haskell
Y eso es todo amigos...
Si tienen preguntas, en los comentarios.
Ah, y notaron que hay un botón para donar dinero?
Programación Orientada a Objetos en Python, parte 4
Las propiedades “privadas”, no existen en Python :(
Sin embargo, hay una convención que se sigue en la mayoría del código Python: un nombre prefijado con un guión bajo (por ejemplo, _spam) debería tratarse como una propiedad privada
Cualquier identificador con la forma __spam (al menos dos guiones bajos al principio, como mucho un guión bajo al final) es textualmente reemplazado por _nombredeclase__spam, donde nombredeclase es el nombre de clase actual al que se le sacan guiones bajos del comienzo (si los tuviera). Se modifica el nombre del identificador sin importar su posición sintáctica, siempre y cuando ocurra dentro de la definición de una clase.
La modificación de nombres es útil para dejar que las subclases sobreescriban los métodos sin romper las llamadas a los métodos desde la misma clase. Por ejemplo:
class Mapeo:
def __init__(self, iterable):
self.lista_de_items = []
self.__actualizar(iterable)
def actualizar(self, iterable):
for item in iterable:
self.lista_de_items.append(item)
__actualizar = actualizar # copia privada del actualizar() original
class SubClaseMapeo(Mapeo):
def actualizar(self, keys, values):
# provee una nueva signatura para actualizar()
# pero no rompe __init__()
for item in zip(keys, values):
self.lista_de_items.append(item)
Hay que aclarar que las reglas de modificación de nombres están diseñadas principalmente para evitar colisiones de nombres; es posible acceder o modificar una variable que es considerada como privada. Esto hasta puede resultar útil en circunstancias especiales, tales como en el depurador.
Note que el código pasado a exec o eval() no considera que la clase que invoca sea la clase actual; esto es similar al efecto de la sentencia global, efecto que es de similar manera restringido a código que es compilado en conjunto. La misma restricción aplica a getattr(), setattr() y delattr(), así como cuando se referencia a __dict__ directamente.
A veces es útil tener un tipo de datos similar al “registro” de Pascal o la “estructura” de C, que sirva para juntar algunos pocos ítems con nombre. Una definición de clase vacía funcionará perfecto:
class Empleado:
pass
juan = Empleado() # Crear un registro de empleado vacío
# Llenar los campos del registro
juan.nombre = 'Juan Pistola'
juan.depto = 'laboratorio de computación'
juan.salario = 1000
Algún código Python que espera un tipo abstracto de datos, en particular puede frecuentemente recibir. En cambio una clase que emula los métodos de aquel tipo de datos. Por ejemplo, si tenés una función que formatea algunos datos a partir de un objeto archivo, podés definir una clase con métodos read() y readline() que obtengan los datos de alguna cadena en memoria intermedia, y pasarlo como argumento.
Los objetos método de instancia tienen atributos también: m.__self__ es el objeto instancia con el método m(), y m.__func__ es el objeto función correspondiente al método.
lunes, 12 de febrero de 2018
Programación Orientada a Objetos en Python, parte 3
Python soporta la herencia y la herencia múltiple. Una definición de clase con múltiples clases base se ve así:
class ClaseDerivada(Base1, Base2, Base3):
<declaración-1>
.
.
.
<declaración-N>
Si un atributo no se encuentra en ClaseDerivada, se busca en Base1, luego (recursivamente) en las clases base de Base1, y sólo si no se encuentra allí se lo busca en Base2, y así sucesivamente.
El orden de resolución de métodos cambia dinámicamente para soportar las llamadas cooperativas a super(). Este enfoque es conocido en otros lenguajes con herencia múltiple como “llámese al siguiente método” y es más poderoso que la llamada al superior que se encuentra en lenguajes con sólo herencia simple.
No nos olvidemos del problema del diamante, Por ejemplo, todas las clases heredan de object, por lo tanto cualquier caso de herencia múltiple provee más de un camino para llegar a object. Para que las clases base no sean accedidas más de una vez, el algoritmo dinámico hace lineal el orden de búsqueda de manera que se preserve el orden de izquierda a derecha especificado en cada clase, que se llame a cada clase base sólo una vez, y que sea monótona (lo cual significa que una clase puede tener clases derivadas sin afectar el orden de precedencia de sus clases bases). En conjunto, estas propiedades hacen posible diseñar clases confiables y extensibles con herencia múltiple.
Programación Orientada a Objetos en Python, parte 2
Bueno, ya vimos clases y herencia en python. Esta segunda parte vamos a seguir hablando de la construcción de objetos.
La operación de instanciación crea un objeto vacío. En muchas ocasiones necesitamos crear objetos en un estado inicial particular. Por lo tanto se puede definir un método especial llamado __init__(), de esta forma:
def __init__(self):
self.datos = []
Cuando definimos un método __init__(), la instanciación de la clase automáticamente invoca a __init__(). Entonces, en este ejemplo, una instancia nueva e inicializada se puede obtener haciendo:
x = MiClase()
Por supuesto, el método __init__() puede tener argumentos para mayor flexibilidad. En ese caso, los argumentos que se pasen al operador de instanciación de la clase van a parar al método __init__(). Por ejemplo,
>>> class Complejo:
... def __init__(self, partereal, parteimaginaria):
... self.r = partereal
... self.i = parteimaginaria
...
>>> x = Complejo(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
Python permite las variables de instancia son para datos únicos de cada instancia y las variables de clase son para atributos y métodos compartidos por todas las instancias de la clase:
class Perro:
tipo = 'canino' # variable de clase compartida por todas las instancias
def __init__(self, nombre):
self.nombre = nombre # variable de instancia única para la instancia
>>> d = Perro('Fido')
>>> e = Perro('Buddy')
>>> d.tipo # compartido por todos los perros
'canino'
>>> e.tipo # compartido por todos los perros
'canino'
>>> d.nombre # único para d
'Fido'
>>> e.nombre # único para e
'Buddy'
Todo valor es un objeto, y por lo tanto un objeto conoce su clase (también llamado su tipo). Ésta se almacena como objeto.__class__ y es un objeto.
La operación de instanciación crea un objeto vacío. En muchas ocasiones necesitamos crear objetos en un estado inicial particular. Por lo tanto se puede definir un método especial llamado __init__(), de esta forma:
def __init__(self):
self.datos = []
Cuando definimos un método __init__(), la instanciación de la clase automáticamente invoca a __init__(). Entonces, en este ejemplo, una instancia nueva e inicializada se puede obtener haciendo:
x = MiClase()
Por supuesto, el método __init__() puede tener argumentos para mayor flexibilidad. En ese caso, los argumentos que se pasen al operador de instanciación de la clase van a parar al método __init__(). Por ejemplo,
>>> class Complejo:
... def __init__(self, partereal, parteimaginaria):
... self.r = partereal
... self.i = parteimaginaria
...
>>> x = Complejo(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
Python permite las variables de instancia son para datos únicos de cada instancia y las variables de clase son para atributos y métodos compartidos por todas las instancias de la clase:
class Perro:
tipo = 'canino' # variable de clase compartida por todas las instancias
def __init__(self, nombre):
self.nombre = nombre # variable de instancia única para la instancia
>>> d = Perro('Fido')
>>> e = Perro('Buddy')
>>> d.tipo # compartido por todos los perros
'canino'
>>> e.tipo # compartido por todos los perros
'canino'
>>> d.nombre # único para d
'Fido'
>>> e.nombre # único para e
'Buddy'
Todo valor es un objeto, y por lo tanto un objeto conoce su clase (también llamado su tipo). Ésta se almacena como objeto.__class__ y es un objeto.
domingo, 11 de febrero de 2018
Programación Orientada a Objetos en Python
Como les dije anteriormente estoy estudiando nuevamente python para unas cosas que tengo que hacer. Más allá de esto, vamos a repasar los conceptos de poo en python.
Primero y principal python implementa la poo con clases, como lo hacen la mayoría de los lenguajes. Las clases son una abstracción de un conjunto de objetos, esto luego define el tipo de nuestros objetos. Veamos las clases en python:
class Objeto:
pass
class Antena:
pass
class Pelo:
pass
class Ojo:
pass
Como se puede ver se usa la convención CamelCase para el nombre de las clases, y por supuesto las clases pueden tener atributos y métodos:
class Objeto():
color = "verde"
tamanio = "grande"
aspecto = "feo"
antenas = Antena()
ojos = Ojo()
pelos = Pelo()
def flotar(self):
print 12
Por alguna razón que desconozco el primer parámetro de los métodos debe ser self (en este punto alguien me puede ayudar?). Y tambien se utiliza la misma convención.
Todo muy lindo pero donde están los objetos? veamos como instanciar objetos :
et = Objeto()
print et.color
print et.tamanio
print et.aspecto
et.color = "rosa"
print et.color
Una característica de poo es la herencia que esta implementada en python tambien, se agrega la clase padre entre paréntesis luego del nombre de la clase :
class NuevoObjeto(Objeto):
pie = Pie()
def saltar(self):
pass
Podemos heredar de la clase object que es la clase principal de Python:
class Antena(object):
color = ""
longitud = ""
class Pelo(object):
color = ""
textura = ""
Luego seguimos con el miniresumen.
sábado, 10 de febrero de 2018
Que trae de nuevo Java 9 ?
Voy a hacer un minipost de las características nuevas que trae Java 9, luego desarrollo cada una de forma individual.
JShell: REPL: Porfin!!! un repl en java. Para los que no saben que es un repl, la wikipedia dice lo siguiente : Un bucle Lectura-Evaluación-Impresión ("REPL" o "Read-Eval-Print-Loop"), también conocido como alto nivel interactivo o consola de lenguaje, es un entorno de programación computacional simple e interactivo que toma las entradas individuales del usuario, las evalúa y devuelve el resultado al usuario; un programa escrito en un entorno REPL es ejecutado parte por parte.
Métodos privados en las interfaces: Java 8 nos proporcionó la implementación de métodos predeterminado y estático en Interfaces; sin embargo, no podemos crear métodos privados en las interfaces. Si nos encontramos en una situación en la que tenemos múltiples métodos predeterminados en una interfaz que contiene la misma funcionalidad. En este escenario, normalmente refactorizaríamos estos métodos predeterminados para llamar a un método privado que contenga la funcionalidad compartida y ahora podemos hacer esto en java 9 :
public interface MyInterface {
default void interfaceDefaultMethod() { init(); }
default void interfaceSecondDefaultMethod() { init(); }
// This is the declaration of the Private Method in Interface
private void init() { ... }
}
Java 9 Module System: Claramente esto necesita un post en si. Pero para resumir podemos decir: Hasta la versión de Java 8 estábamos usando los contenedores monolíticos para diseñar nuestras aplicaciones basadas en Java. Hay dos problemas principales fundamentales con este diseño: Código difícil de encapsular y no hay ninguna noción de dependencias explícitas entre las diferentes partes de un sistema. Para evitar estos problemas fundamentales, Java 9 introdujo el sistema de módulos. Estos son algunos de los principales beneficios que obtenemos del Sistema de Módulos.
Los JDK, JRE, JAR actuales, etc. ahora están divididos en módulos más pequeños, por lo que solo podemos usar los módulos que deseamos. Esto ayuda a reducir la aplicación para dispositivos más pequeños.
Fuerte soporte para encapsulación. Las API internas no críticas están ocultas ahora, ya que los módulos ocultan detalles internos y no deseados de forma muy segura. Esto mejora la seguridad de la aplicación.
Mejoras en Javadoc: Java 9 ahora admite la búsqueda de documentación API internamente dentro de Javadoc.
HTTP/2 Client: Se ha lanzado una nueva API cliente HTTP/2 para soportar el protocolo HTTP/2 y las características de websockets. Este es un reemplazo del antiguo "HttpUrlConnection".
Nuevo esquema de cadena de versiones: Proporciona un formato de cadena de versión simplificado que ayuda a distinguir claramente las versiones principales, secundarias, de seguridad y actualización de parches.
El nuevo formato de cadena de versión se alinea con las prácticas actuales de la industria, en particular las versiones semánticas (servidor). El formato es el siguiente:
$ MAJOR. $ MENOR. $ SEGURIDAD. $ PATCH
Archivos JAR múltiple releases: Extiende el formato de archivo JAR para permitir que múltiples versiones de archivos de clase específicos de versiones de Java coexistan en un solo archivo.
Un JAR de múltiples releases (MRJAR) contiene directorios adicionales versionados para clases y recursos específicos para versiones de plataforma Java particulares.
Mejoras en Stream API: La mejora en Stream API permite filtrar flujos entrantes de datos de serialización de objetos para mejorar la seguridad y la solidez.
Los clientes de serialización de objetos pueden validar su entrada más fácilmente, y los objetos exportados de Invocación de Método Remoto (RMI) también pueden validar los argumentos de invocación más fácilmente.
Los clientes de serialización implementan una interfaz de filtro que está configurada en un ObjectInputStream. Para RMI, el objeto se exporta a través de RemoteServerRef que establece el filtro en MarshalInputStream para validar los argumentos de invocación ya que no están agrupados.
Mailrelay, una de las mejores plataformas de email marketing que existen en el mercado
MailRelay es una herramienta de envío de emails. No! No es un cliente de correo, es una plataforma de email marketing avanzado con características de gran alcance. Te permite crear, enviar y gestionar tus boletines enviados vía emails con estadísticas completas, a la vez podes analizar el comportamiento del suscriptor.
Mailing marketing ?? Si, tambien se lo conoce como ciberbuzoneo o en inglés: e-mailing es un método de marketing directo que utiliza el correo electrónico como medio de comunicación comercial para enviar mensajes a una audiencia. De esta forma podes tener al tanto a tus clientes de las novedades de tu empresa, nuevos productos, ofertas, etc...
Cuando se trata de correos masivos y envío masivo, no hay ninguna diferencia real entre los dos términos. Ambos significan envío masivo de email promocional para sus clientes y contactos. A veces, las personas confunden con correos masivos de spam. Sin embargo, la diferencia entre ambos es que el spam es no solicitado, mientras que el correo masivo es basado en permisos. Email marketing masivo tiene algunas ventajas muy profundas sobre todas las demás formas de marketing.
Con MailRelay podemos crear boletines y enviárselas a un grupo de suscriptores, a la vez la herramienta analiza el comportamiento del subscriptor, de esta forma podemos saber cual es el articulo más visitado, y que suscriptores vieron que articulo pudiendo analizar las necesidades de los clientes según esta información.
MailRelay no solo permite crear campañas de email marketing sino que tambien darle un correcto seguimiento y tener un contacto real con los clientes. Y es muy importante este seguimiento tanto para fidelizar al cliente como para estimular las ventas.
Entre otras ventajas podemos nombrar:
- Un seguimiento inteligente de los clientes: con esta herramienta podes saber que necesita cada suscriptor y podemos hacer un seguimiento de los clientes y sus necesidades.
- No vamos a ser catalogados como spam: Mailrelay cumple con todas las normas de correo electrónico anti-spam, haciendo que la puntuación antispam sea menos posible.
- Templates para nuestros boletines: Mailrelay cuenta con una completa biblioteca de templates gratuitos que podemos utilizar.
- SMTP de alto rendimiento: Mailrelay nos ofrece un servicio smtp que se distingue por su alto rendimiento.
- Facilidad de uso: No es necesario que contrates a un programador o un diseñador gráfico, cualquier persona puede utilizar este servicio.
- Atención personalizada: Recibe atención personalizada y respuesta inmediata a tus dudas.
Hoy día son muchas las empresas que buscan vender más, conseguir más visibilidad, fidelizar a sus clientes y destacar sobre su competencia. Objetivos todos dirigidos a garantizar la viabilidad de la empresa o proyecto. Objetivos que no son nada fáciles de conseguir y mantener.
Mailrelay tiene más de 15 años de experiencia en e-mail marketing, tanto desarrollando una herramienta de email marketing efectiva, como es Mailrelay, como ayudando a los clientes a mejorar sus resultados, llegar a la bandeja de entrada, solucionar sus problemas de spam, etc.
Como conclusión les aconsejo que vean con buenos ojos a Mailrelay dado su excelente soporte y sus ofertas. Y además es un excelente producto. Mailrelay te permite gestionar tu e-mail marketing de forma fácil y efectiva
Dejo link:
https://mailrelay.com/es
martes, 6 de febrero de 2018
20 libros que un desarrollador java debe leer en el 2018
En Dzone nos sugieren libros para leer en el 2018 y estoy bastante de acuerdo con la lista por lo tanto la comparto:
Puff!! Tenemos mucho para leer!!
Dejo link: https://dzone.com/articles/20-books-java-programmers-should-read-in-2018
1. Java 8 in Action
2. Clean Architecture
3. Grokking Algorithms
4. Building Microservices: Designing Fine-Grained Systems
5. Soft Skills
6. Database Design for Mere Mortals
7. Making Java Groovy
8. Groovy in Action, Second Edition
9. TCP/IP Illustrated
10. UML Distilled
11. Hibernate Tips
12. The Art of Agile Development
13. Essential Scrum
14. Java Performance Companion
15. High-Performance Java Persistence
16. Functional Programming in Scala
17. Scala for the Impatient
18. Head First JavaScript
19. SQL CookBook
20. The Complete Software Developer's Career Guide
Dejo link: https://dzone.com/articles/20-books-java-programmers-should-read-in-2018
lunes, 5 de febrero de 2018
Empezando con Elixir 11
Sigils
Elixir proporciona una sintaxis alternativa para representar y trabajar con literales. Un Sigils comenzará con una tilde ~ seguido de un carácter. El núcleo Elixir nos proporciona algunos Sigils integrados, sin embargo, es posible crear el nuestros propios Sigils cuando necesitamos extender el lenguaje.
Los Sigils disponibles son:
~ C Genera una lista de caracteres sin escape ni interpolación
~ c Genera una lista de caracteres con escape e interpolación
~ R Genera una expresión regular sin escape ni interpolación
~ r Genera una expresión regular con escape e interpolación
~ S Genera una cadena sin escape ni interpolación
~ s Genera una cadena con escape e interpolación
~ W Genera una lista de palabras sin escape ni interpolación
~ w Genera una lista de palabras con escape e interpolación
~ N genera una estructura NaiveDateTime
Una lista de delimitadores incluye:
<...> Un par de signos menor/mayor
{...} Un par de llaves
[...] Un par de corchetes
(...) Un par de paréntesis
| ... | Un par de barras verticales
/.../ Un par de barras diagonales
"..." Un par de comillas dobles
'...' Un par de comillas simples
Lista de caracteres
~c y ~C generan una lista de caracteres:
iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'
iex> ~C/2 + 7 = #{2 + 7}/
'2 + 7 = \#{2 + 7}'
Podemos ver que la minúscula ~c interpola el cálculo, mientras que la mayúscula ~C no. Veremos que esta propiedad de mayúsculas o minúsculas es común en todos los sigils.
Expresiones regulares
~ r y ~ R se usan para representar expresiones regulares. Los podemos crear justo en el momento de utilizarlo o para usar dentro de las funciones de Regex. Por ejemplo:
iex> re = ~r/elixir/
~r/elixir/
iex> "Elixir" =~ re
false
iex> "elixir" =~ re
true
Podemos ver que en la primera prueba de igualdad, no coincide con la expresión regular. Esto se debe a que está en mayúscula. Debido a que Elixir admite expresiones regulares compatibles con Perl (PCRE), podemos agregar i al final para desactivar la distinción entre mayúsculas y minúsculas.
iex> re = ~r/elixir/i
~r/elixir/i
iex> "Elixir" =~ re
true
iex> "elixir" =~ re
true
Además, Elixir proporciona la API de expresiones regulares que está construida sobre la biblioteca de expresiones regulares de Erlang. Es decir que podemos utilizarlos en funciones, veamos un ejemplo:
iex> string = "100_000_000"
"100_000_000"
iex> Regex.split(~r/_/, string)
["100", "000", "000"]
String
~s y ~S se utilizan para generar cadenas. Por ejemplo:
iex> ~s/the cat in the hat on the mat/
"the cat in the hat on the mat"
iex> ~S/the cat in the hat on the mat/
"the cat in the hat on the mat"
¿Cuál es la diferencia? La diferencia es similar a los otros sigils que vimos. La respuesta es la interpolación y el uso de secuencias de escape. Si tomamos otro ejemplo:
iex> ~s/welcome to elixir #{String.downcase "school"}/
"welcome to elixir school"
iex> ~S/welcome to elixir #{String.downcase "school"}/
"welcome to elixir \#{String.downcase \"school\"}"
Word List
La lista de palabras puede ser útil de vez en cuando. Puede ahorrar tiempo, pulsaciones de teclas y posiblemente reducir la complejidad dentro del código. Por ejemplo:
iex> ~w/i love elixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love elixir school/
["i", "love", "elixir", "school"]
Podemos ver que el delimitador es espacio en blanco. Sin embargo, no hay diferencia entre estos dos ejemplos. De nuevo, la diferencia viene con las secuencias de interpolación y escape. Por ejemplo:
iex> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]
NaiveDateTime
Un NaiveDateTime puede ser útil para crear rápidamente una estructura para representar un DateTime sin una zona horaria.
En su mayor parte, deberíamos evitar crear una estructura NaiveDateTime directamente. Sin embargo, es muy útil para la coincidencia de patrones. Por ejemplo:
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") == {:ok, ~N[2015-01-23 23:50:07]}
Crear un Sigils
Uno de los objetivos de Elixir es ser un lenguaje de programación extensible. No debería sorprender entonces que pueda crear fácilmente sus propios sigils personalizados. En este ejemplo, crearemos un sigils para convertir una cadena en mayúscula. Como ya existe una función para esto en Elixir Core (String.upcase/1), envolveremos nuestro sigils alrededor de esa función.
iex> defmodule MySigils do
...> def sigil_u(string, []), do: String.upcase(string)
...> end
iex> import MySigils
nil
iex> ~u/elixir school/
ELIXIR SCHOOL
Primero definimos un módulo llamado MySigils y dentro de ese módulo, creamos una función llamada sigil_u. Como no existe un sigilo en el espacio de sigilo existente, lo usaremos. El _u indica que deseamos usar u como el carácter después de ~ . La definición de la función debe tomar dos argumentos, una entrada y una lista.
Elixir proporciona una sintaxis alternativa para representar y trabajar con literales. Un Sigils comenzará con una tilde ~ seguido de un carácter. El núcleo Elixir nos proporciona algunos Sigils integrados, sin embargo, es posible crear el nuestros propios Sigils cuando necesitamos extender el lenguaje.
Los Sigils disponibles son:
~ C Genera una lista de caracteres sin escape ni interpolación
~ c Genera una lista de caracteres con escape e interpolación
~ R Genera una expresión regular sin escape ni interpolación
~ r Genera una expresión regular con escape e interpolación
~ S Genera una cadena sin escape ni interpolación
~ s Genera una cadena con escape e interpolación
~ W Genera una lista de palabras sin escape ni interpolación
~ w Genera una lista de palabras con escape e interpolación
~ N genera una estructura NaiveDateTime
Una lista de delimitadores incluye:
<...> Un par de signos menor/mayor
{...} Un par de llaves
[...] Un par de corchetes
(...) Un par de paréntesis
| ... | Un par de barras verticales
/.../ Un par de barras diagonales
"..." Un par de comillas dobles
'...' Un par de comillas simples
Lista de caracteres
~c y ~C generan una lista de caracteres:
iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'
iex> ~C/2 + 7 = #{2 + 7}/
'2 + 7 = \#{2 + 7}'
Podemos ver que la minúscula ~c interpola el cálculo, mientras que la mayúscula ~C no. Veremos que esta propiedad de mayúsculas o minúsculas es común en todos los sigils.
Expresiones regulares
~ r y ~ R se usan para representar expresiones regulares. Los podemos crear justo en el momento de utilizarlo o para usar dentro de las funciones de Regex. Por ejemplo:
iex> re = ~r/elixir/
~r/elixir/
iex> "Elixir" =~ re
false
iex> "elixir" =~ re
true
Podemos ver que en la primera prueba de igualdad, no coincide con la expresión regular. Esto se debe a que está en mayúscula. Debido a que Elixir admite expresiones regulares compatibles con Perl (PCRE), podemos agregar i al final para desactivar la distinción entre mayúsculas y minúsculas.
iex> re = ~r/elixir/i
~r/elixir/i
iex> "Elixir" =~ re
true
iex> "elixir" =~ re
true
Además, Elixir proporciona la API de expresiones regulares que está construida sobre la biblioteca de expresiones regulares de Erlang. Es decir que podemos utilizarlos en funciones, veamos un ejemplo:
iex> string = "100_000_000"
"100_000_000"
iex> Regex.split(~r/_/, string)
["100", "000", "000"]
String
~s y ~S se utilizan para generar cadenas. Por ejemplo:
iex> ~s/the cat in the hat on the mat/
"the cat in the hat on the mat"
iex> ~S/the cat in the hat on the mat/
"the cat in the hat on the mat"
¿Cuál es la diferencia? La diferencia es similar a los otros sigils que vimos. La respuesta es la interpolación y el uso de secuencias de escape. Si tomamos otro ejemplo:
iex> ~s/welcome to elixir #{String.downcase "school"}/
"welcome to elixir school"
iex> ~S/welcome to elixir #{String.downcase "school"}/
"welcome to elixir \#{String.downcase \"school\"}"
Word List
La lista de palabras puede ser útil de vez en cuando. Puede ahorrar tiempo, pulsaciones de teclas y posiblemente reducir la complejidad dentro del código. Por ejemplo:
iex> ~w/i love elixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love elixir school/
["i", "love", "elixir", "school"]
Podemos ver que el delimitador es espacio en blanco. Sin embargo, no hay diferencia entre estos dos ejemplos. De nuevo, la diferencia viene con las secuencias de interpolación y escape. Por ejemplo:
iex> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]
NaiveDateTime
Un NaiveDateTime puede ser útil para crear rápidamente una estructura para representar un DateTime sin una zona horaria.
En su mayor parte, deberíamos evitar crear una estructura NaiveDateTime directamente. Sin embargo, es muy útil para la coincidencia de patrones. Por ejemplo:
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") == {:ok, ~N[2015-01-23 23:50:07]}
Crear un Sigils
Uno de los objetivos de Elixir es ser un lenguaje de programación extensible. No debería sorprender entonces que pueda crear fácilmente sus propios sigils personalizados. En este ejemplo, crearemos un sigils para convertir una cadena en mayúscula. Como ya existe una función para esto en Elixir Core (String.upcase/1), envolveremos nuestro sigils alrededor de esa función.
iex> defmodule MySigils do
...> def sigil_u(string, []), do: String.upcase(string)
...> end
iex> import MySigils
nil
iex> ~u/elixir school/
ELIXIR SCHOOL
Primero definimos un módulo llamado MySigils y dentro de ese módulo, creamos una función llamada sigil_u. Como no existe un sigilo en el espacio de sigilo existente, lo usaremos. El _u indica que deseamos usar u como el carácter después de ~ . La definición de la función debe tomar dos argumentos, una entrada y una lista.
Suscribirse a:
Entradas (Atom)