diff options
Diffstat (limited to 'es-es')
39 files changed, 3095 insertions, 1292 deletions
diff --git a/es-es/amd-es.html.markdown b/es-es/amd-es.html.markdown index 40aa6647..83c705c3 100644 --- a/es-es/amd-es.html.markdown +++ b/es-es/amd-es.html.markdown @@ -16,6 +16,7 @@ lang: es-es El API del **Módulo de Definición Asíncrono** especifica un mecanismo para definir módulos JavaScript de manera tal que tanto el módulo como sus dependencias puedan ser cargadas de manera asíncrona. Esto es particularmente adecuado para el entorno del navegador donde la carga sincronizada de los módulos genera problemas de rendimiento, usabilidad, depuración y acceso de multi-dominios. ### Conceptos básicos + ```javascript // El API básico de AMD consiste en tan solo dos métodos: `define` y `require` // y se basa en la definición y consumo de los módulos: @@ -137,6 +138,7 @@ require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolL coolLib.doFancyStuffWith(helpers.transform($('#foo'))); }); ``` + Las aplicaciones basadas en `require.js` usualmente tendrán un solo punto de entrada (`main.js`) que se pasa a la etiqueta del script `require.js` como un atributo de datos. Será cargado y ejecutado automáticamente al cargar la página: ```html @@ -158,16 +160,19 @@ Muchas personas prefieren usar AMD para la organización del código durante el `require.js` incluye un script llamado `r.js` (el que probablemente correrás en node.js, aunque Rhino también es soportado) que puede analizar el gráfico de dependencias de tu proyecto, y armar un solo fichero que contenga todos tus módulos (adecuadamente nombrados), minificado y listo para consumo. Instálalo usando `npm`: + ```shell $ npm install requirejs -g ``` Ahora puedes alimentarlo con un fichero de configuración: + ```shell $ r.js -o app.build.js ``` Para nuestro ejemplo anterior el archivo de configuración luciría así: + ```javascript /* file : app.build.js */ ({ @@ -184,6 +189,7 @@ Para nuestro ejemplo anterior el archivo de configuración luciría así: ``` Para usar el fichero creado en producción, simplemente intercambia `data-main`: + ```html <script src="require.js" data-main="app/main-built"></script> ``` diff --git a/es-es/asciidoc-es.html.markdown b/es-es/asciidoc-es.html.markdown index 6e357915..31406ee1 100644 --- a/es-es/asciidoc-es.html.markdown +++ b/es-es/asciidoc-es.html.markdown @@ -5,7 +5,7 @@ contributors: translators: - ["Abel Salgado Romero", "https://twitter.com/abelsromero"] lang: es-es -filename: asciidoc-es.md +filename: asciidoc-es.adoc --- AsciiDoc es un lenguaje de marcas similar a Markdown que puede ser usado para cualquier uso, desde libros a blogs. diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown index 8da8f024..1ee12956 100644 --- a/es-es/awk-es.html.markdown +++ b/es-es/awk-es.html.markdown @@ -11,8 +11,8 @@ lang: es-es AWK es una herramienta estándar en cada sistema UNIX compatible con POSIX. Es como un Perl restringido, perfecto para tareas de procesamiento de texto y -otras necesidades de scripting. Tiene una sintaxis similar a C, pero sin -puntos y comas, manejo manual de memoria y tipado estático. Puedes llamarlo +otras necesidades de scripting. Tiene una sintaxis similar a C, pero sin +puntos y comas, manejo manual de memoria y tipado estático. Puedes llamarlo desde un script de shell o usarlo como un lenguaje stand-alone para scripting. ¿Por qué elegir AWK sobre Perl? Principalmente, porque AWK es parte de UNIX. @@ -74,8 +74,8 @@ BEGIN { # Bloques formados por múltiples líneas usan llaves while (a < 10) { - print "La concatenación de strings se hace " " con series " - print " de" " strings separados por espacios" + print "La concatenación de strings se hace " " con series " + print " de" " strings separados por espacios" print a a++ @@ -153,13 +153,13 @@ function arithmetic_functions(a, b, c, localvar) { # Todo es global. No es problema en scripts pequeños, pero sí para # scripts más grandes. - # Hay un work-around (mmm... hack). Los argumentos de las funciones son + # Hay un work-around (mmm... hack). Los argumentos de las funciones son # locales para la función, y AWK permite definir más argumentos de función - # de los que necesita, por lo que define las variables locales en la + # de los que necesita, por lo que define las variables locales en la # declaración como en la función de arriba. Como convención, agrega - # espacios en blanco para distinguir los parámetros de la función de las - # variables locales. En este ejemplo, a, b y c son parámetros y localvar es una - # variable local. + # espacios en blanco para distinguir los parámetros de la función de las + # variables locales. En este ejemplo, a, b y c son parámetros y localvar es + # una variable local. # Ahora, a demostrar las funciones aritméticas @@ -196,7 +196,7 @@ function string_functions( localvar, arr) { # Ambas regresan el número de matches remplazados. localvar = "fooooobar" sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar" - gsub("e+", ".", localvar) # localvar => "m..t m. at th. bar" + gsub("e", ".", localvar) # localvar => "M..t m. at th. bar" # Buscar una cadena que haga match con una expresión regular # index() hace lo mismo, pero no permite expresiones regulares @@ -222,10 +222,10 @@ function io_functions( localvar) { # También hay printf printf("%s %d %d %d\n", "Testing", 1, 2, 3) - # AWK no tiene handles de archivos en sí mismo. Automáticamente abrirá un - # handle de archivo cuando use algo que necesite uno. El string que usaste - # para esto puede ser tratada como un handle de archivo para propósitos de I/O. - # Esto lo hace similar al scripting de shell: + # AWK no tiene handles de archivos en sí mismo. Automáticamente abrirá un + # handle de archivo cuando use algo que necesite uno. El string que usaste + # para esto puede ser tratada como un handle de archivo para propósitos + # de I/O. Esto lo hace similar al scripting de shell: print "foobar" >"/tmp/foobar.txt" @@ -247,17 +247,17 @@ function io_functions( localvar) { close("/tmp/foobar.txt") } -# Como dije al inicio, los programas en AWK son una colección de patrones y +# Como dije al inicio, los programas en AWK son una colección de patrones y # acciones. Ya conociste el patrón BEGIN. otros patrones sólo se usan si estás # procesando líneas desde archivos o stdin. -# Cuando pasas argumentos a AWK, son tratados como nombres de archivos a -# procesar. Los va a procesar todos, en orden. Imagínalos como un ciclo for +# Cuando pasas argumentos a AWK, son tratados como nombres de archivos a +# procesar. Los va a procesar todos, en orden. Imagínalos como un ciclo for # implícito, iterando sobre las líneas de estos archivos. Estos patrones y # acciones son como instrucciones switch dentro del ciclo. /^fo+bar$/ { - + # Esta acción se ejecutará por cada línea que haga match con la expresión # regular /^fo+bar$/, y será saltada por cualquier línea que no haga match. # Vamos a sólo mostrar la línea: @@ -268,7 +268,7 @@ function io_functions( localvar) { # $0 es el nombre de la línea actual que se está procesando. # Se crea automáticamente para ti. - # Probablemente puedas adivinar que hay otras variables $. Cada línea es + # Probablemente puedas adivinar que hay otras variables $. Cada línea es # separada implícitamente antes de que se llame cada acción, justo como lo # hace shell. Y, como shell, cada campo puede ser accesado con $. @@ -301,7 +301,7 @@ a > 0 { # Y ya te das una idea. Procesar archivos de texto, leyendo una línea a la vez, # y haciendo algo con ella, particularmente separando en un deliminator, es tan # común en UNIX que AWK es un lenguaje de scripting que hace todo eso por ti -# sin que tengas que pedirlo. Basta con escribir los patrones y acciones +# sin que tengas que pedirlo. Basta con escribir los patrones y acciones # basados en lo que esperas de la entrada y lo quieras quieras hacer con ella. # Aquí está un ejemplo de un script simple, para lo que AWK es perfecto. @@ -343,7 +343,7 @@ $1 == name { nlines++ } -# Otro patrón especial es END. Va a ejecutarse después de procesar todos los +# Otro patrón especial es END. Va a ejecutarse después de procesar todos los # archivos de texto. A diferencia de BEGIN, sólo se ejecuta si le das dado una # entrada a procesar. Se ejecutará después de que todos los archivos hayan sido # leídos y procesados según las reglas y acciones que programaste. El propósito @@ -356,8 +356,10 @@ END { } ``` + Más información: * [Tutorial de AWK](http://www.grymoire.com/Unix/Awk.html) * [Página man de AWK](https://linux.die.net/man/1/awk) -* [La guía del usuario de GNU Awk](https://www.gnu.org/software/gawk/manual/gawk.html): GNU Awk se encuentra en la mayoría de los sistemas Linux. +* [La guía del usuario de GNU Awk](https://www.gnu.org/software/gawk/manual/gawk.html): + GNU Awk se encuentra en la mayoría de los sistemas Linux. diff --git a/es-es/bash-es.html.markdown b/es-es/bash-es.html.markdown index fb89b2a0..27070e79 100644 --- a/es-es/bash-es.html.markdown +++ b/es-es/bash-es.html.markdown @@ -18,7 +18,7 @@ Tutorial de Shell en español. Bash es el nombre del shell de unix, el cual también es distribuido como el shell del sistema operativo GNU. También es el shell -por defecto de Linux y Mac OS X. Casi todos los ejemplos abajo pueden +por defecto de Linux y macOS. Casi todos los ejemplos abajo pueden ser parte de un script shell o ser ejecutados directamente en la terminal. [Leer más aquí.](http://www.gnu.org/software/bash/manual/bashref.html) diff --git a/es-es/c++-es.html.markdown b/es-es/c++-es.html.markdown index 2c3762d5..f624d3c7 100644 --- a/es-es/c++-es.html.markdown +++ b/es-es/c++-es.html.markdown @@ -1,5 +1,5 @@ --- -language: c++ +language: C++ filename: learncpp-es.cpp contributors: - ["Steven Basart", "http://github.com/xksteven"] @@ -8,6 +8,7 @@ contributors: - ["Connor Waters", "http://github.com/connorwaters"] translators: - ["Gerson Lázaro", "https://gersonlazaro.com"] + - ["Diego Ramirez", "https://DiddiLeija.github.io"] lang: es-es --- @@ -101,8 +102,8 @@ void print(int myInt) int main() { - print("Hello"); // Resolves to void print(const char*) - print(15); // Resolves to void print(int) + print("Hello"); // Corresponde a void print(const char*) + print(15); // Corresponde a void print(int) } //////////////////////////////////// @@ -114,7 +115,7 @@ int main() void doSomethingWithInts(int a = 1, int b = 4) { - // Hacer algo con los enteros aqui + // Hacer algo con los enteros aquí } int main() @@ -134,7 +135,7 @@ void invalidDeclaration(int a = 1, int b) // Error! // Espacios de nombre ///////////////////// -// Espacios de nombres proporcionan ámbitos separados para variable, función y +// Los espacios de nombres proporcionan ámbitos separados para variable, función y // otras declaraciones. // Los espacios de nombres se pueden anidar. @@ -184,7 +185,7 @@ int main() #include <iostream> // Incluir para el flujo de entrada/salida -using namespace std; // Los streams estan en std namespace (libreria estandar) +using namespace std; // Los streams estan en el espacio de nombre std (libreria estandar) int main() { @@ -208,7 +209,7 @@ int main() // Las cadenas en C++ son objetos y tienen muchas funciones #include <string> -using namespace std; // Strings también estan en namespace std +using namespace std; // Las cadenas también estan en el nombre de espacio std string myString = "Hola"; string myOtherString = " Mundo"; @@ -252,7 +253,7 @@ fooRef = bar; const string& barRef = bar; // Crea una referencia constante a bar. // Como en C, los valores constantes (y punteros y referencias) no pueden ser // modificados. -barRef += ". Hola!"; // Error, referencia constante no puede ser modificada. +barRef += ". Hola!"; // Error, una referencia constante no puede ser modificada. // Sidetrack: Antes de hablar más sobre referencias, hay que introducir un // concepto llamado objeto temporal. Supongamos que tenemos el siguiente código: @@ -264,7 +265,7 @@ string retVal = tempObjectFun(); // - Una nueva cadena se construye con el objeto devuelto como argumento al // constructor // - El objeto devuelto es destruido -// El objeto devuelto se llama objeto temporal. Objetos temporales son +// El objeto devuelto se llama objeto temporal. Los objetos temporales son // creados cada vez que una función devuelve un objeto, y es destruido en el // fin de la evaluación de la expresión que encierra (Bueno, esto es lo que la // norma dice, pero los compiladores están autorizados a cambiar este @@ -295,7 +296,7 @@ void someFun(string&& s) { ... } // Referencia a objeto temporal string foo; someFun(foo); // Llama la función con referencia regular -someFun(tempObjectFun()); // Llama la versión con referencia temporal +someFun(tempObjectFun()); // Llama la función con referencia temporal // Por ejemplo, puedes ver estas dos versiones de constructores para // std::basic_string: @@ -305,7 +306,7 @@ basic_string(basic_string&& other); // La idea es que si estamos construyendo una nueva cadena de un objeto temporal // (que va a ser destruido pronto de todos modos), podemos tener un constructor // mas eficiente que "rescata" partes de esa cadena temporal. Usted verá este -// Concepto denominado "movimiento semántico". +// concepto denominado "movimiento semántico". //////////////////////////////////////////// // Clases y programación orientada a objetos @@ -322,9 +323,7 @@ class Dog { int weight; // Todos los miembros siguientes de este son públicos -// Hasta que se encuentre "private" o "protected". -// All members following this are public -// until "private:" or "protected:" is found. +// hasta que se encuentre "private" o "protected". public: // Constructor por defecto @@ -339,8 +338,8 @@ public: void setWeight(int dogsWeight); // Funciones que no modifican el estado del objeto - // Deben marcarse como const. - // Esto le permite llamarlas si se envia una referencia constante al objeto. + // deben marcarse como const. + // Esto le permite llamarlas si se envía una referencia constante al objeto. // También tenga en cuenta que las funciones deben ser declaradas // explícitamente como _virtual_ para que sea reemplazada en las clases // derivadas. @@ -357,8 +356,8 @@ public: // Esto permite paradigmas potentes como RAII // (mira abajo) // El destructor debe ser virtual si una clase es dervada desde el; - // Si no es virtual, entonces la clase derivada destructor - // No será llamada si el objeto se destruye a través de una referencia de + // Si no es virtual, entonces la clase destructora derivada + // no será llamada si el objeto se destruye a través de una referencia de // la clase base o puntero. virtual ~Dog(); @@ -373,7 +372,7 @@ Dog::Dog() } // Objetos (tales como cadenas) deben ser pasados por referencia -// Si los estas modificando o referencia constante en caso contrario. +// si los estás modificando, o referencia constante en caso contrario. void Dog::setName(const std::string& dogsName) { name = dogsName; @@ -413,9 +412,9 @@ class OwnedDog : public Dog { // Reemplaza el comportamiento de la función de impresión // de todos los OwnedDogs. Mira // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping - // Para una introducción más general si no está familiarizado con el + // para una introducción más general si no está familiarizado con el // polimorfismo de subtipo. - // La palabra clave override es opcional, pero asegura que estás + // La palabra clave override es opcional, pero asegúrate de que estás // reemplazando el método de una clase base. void print() const override; @@ -460,8 +459,8 @@ public: // pero inicializa el punto al valor por defecto (0, 0) Point() { }; - // The following syntax is known as an initialization list - // and is the proper way to initialize class member values + // La siguiente sintaxis se conoce como lista de inicialización + // y es la forma correcta de inicializar los valores de los miembros de la clase Point (double a, double b) : x(a), y(b) @@ -474,7 +473,7 @@ public: Point& operator+=(const Point& rhs); // También tendría sentido añadir los operadores - y -=, - // Pero vamos a omitirlos por razones de brevedad. + // pero vamos a omitirlos por razones de brevedad. }; Point Point::operator+(const Point& rhs) const @@ -496,7 +495,7 @@ int main () { // Llama al operador + de Point // Point llama la función + con right como parámetro Point result = up + right; - // Prints "Result is upright (1,1)" + // Imprime "Result is upright (1,1)" cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; return 0; } @@ -525,7 +524,7 @@ public: // plantilla con parámetros sustituidos, por lo que la definición completa // de la clase debe estar presente en cada invocación. // Es por esto que usted verá clases de plantilla definidas -// Enteramente en archivos de cabecera. +// enteramente en archivos de cabecera. //Para crear una instancia de una clase de plantilla en la pila: Box<int> intBox; @@ -544,7 +543,7 @@ boxOfBox.insert(intBox); // A veces verás // template<typename T> -// en su lugar. La palabra clave "class" y las palabras clave "typename" son +// en su lugar. La palabra clave "class" y la palabra clave "typename" son // mayormente intercambiables en este caso. Para la explicación completa, mira // http://en.wikipedia.org/wiki/Typename // (sí, esa palabra clave tiene su propia página de Wikipedia). @@ -568,7 +567,7 @@ Dog fluffy; fluffy.setName("Fluffy") barkThreeTimes(fluffy); // Imprime "Fluffy barks" 3 veces. -Los parámetros de la plantilla no tienen que ser las clases: +// Los parámetros de la plantilla no tienen que ser las clases: template<int Y> void printMessage() { cout << "Aprende C++ en " << Y << " minutos!" << endl; @@ -604,7 +603,7 @@ printMessage<10>(); // Prints "Aprende C++ rapido en solo 10 minutos!" //Todas las excepciones lanzadas dentro del bloque _try_ pueden ser // capturados por los siguientes manejadores _catch_. try { - // No asignar excepciones en el heap usando _new_. + // No asigne excepciones en el heap usando _new_. throw std::runtime_error("Ocurrió un problema"); } @@ -629,10 +628,10 @@ catch (...) // (Adquisición de recursos es inicialización). // A menudo se considera el paradigma más poderoso en C++ // Y el concepto es simple: un constructor de un objeto -// Adquiere recursos de ese objeto y el destructor les libera. +// adquiere recursos de ese objeto y el destructor les libera. // Para entender cómo esto es útil, -// Considere una función que utiliza un identificador de archivo C: +// considere una función que utiliza un identificador de archivo C: void doSomethingWithAFile(const char* filename) { // Para empezar, asuma que nada puede fallar. @@ -691,11 +690,11 @@ bool doSomethingWithAFile(const char* filename) failure: fclose(fh); - return false; // Propagate el error + return false; // Propaga el error } // Si las funciones indican errores mediante excepciones, -// Las cosas son un poco más claras, pero pueden optimizarse mas. +// las cosas son un poco más claras, pero pueden optimizarse más. void doSomethingWithAFile(const char* filename) { FILE* fh = fopen(filename, "r"); // Abrir el archivo en modo lectura @@ -732,9 +731,9 @@ void doSomethingWithAFile(const std::string& filename) // Esto tiene ventajas _enormes_: // 1. No importa lo que pase, -// El recurso (en este caso el manejador de archivo) será limpiado. +// el recurso (en este caso el manejador de archivo) será limpiado. // Una vez que escribes el destructor correctamente, -// Es _imposible_ olvidar cerrar el identificador y permitir +// es _imposible_ olvidar cerrar el identificador y permitir // fugas del recurso. // 2. Tenga en cuenta que el código es mucho más limpio. // El destructor se encarga de cerrar el archivo detrás de cámaras diff --git a/es-es/c-es.html.markdown b/es-es/c-es.html.markdown index 8bc1eabb..ae357d91 100644 --- a/es-es/c-es.html.markdown +++ b/es-es/c-es.html.markdown @@ -1,10 +1,11 @@ --- -language: c +language: C filename: learnc-es.c contributors: - ["Adam Bard", "http://adambard.com/"] translators: - ["Francisco García", "http://flaskbreaker.tumblr.com/"] + - ["Heitor P. de Bittencourt", "https://github.com/heitorPB/"] lang: es-es --- @@ -423,7 +424,7 @@ libro de C, escrito por Dennis Ritchie, creador de C y Brian Kernighan. Aún as se cuidadoso, es antiguo, contiene algunas inexactitudes, y algunas prácticas han cambiado. -Otro buen recurso es [Learn C the hard way](http://c.learncodethehardway.org/book/). +Otro buen recurso es [Learn C the hard way](http://learncodethehardway.org/c/). Si tienes una pregunta, lee [compl.lang.c Frequently Asked Questions](http://c-faq.com). diff --git a/es-es/chapel-es.html.markdown b/es-es/chapel-es.html.markdown new file mode 100644 index 00000000..732ee298 --- /dev/null +++ b/es-es/chapel-es.html.markdown @@ -0,0 +1,1219 @@ +--- +language: chapel +filename: learnchapel.chpl +contributors: + - ["Ian J. Bertolacci", "https://www.cs.arizona.edu/~ianbertolacci/"] + - ["Ben Harshbarger", "https://github.com/benharsh/"] +translators: + - ["Ivan Alburquerque", "https://github.com/AlburIvan"] +lang: es-es +--- + +Puede leer todo sobre Chapel en [el sitio web oficial de Chapel de Cray](https://chapel-lang.org). +En resumen, Chapel es un lenguaje de programación paralela, código abierto, de alta productividad +desarrolladp en Cray Inc. y está diseñado para ejecutarse en PC multi-nucleos, +así como en supercomputadoras multi-kilocore. + + +Puede encontrar más información y asistencia al final de este documento. + +```chapel +// Los comentarios son de estilo de la familia C + +// comentario de una línea +/* + comentario de múltiples lineas +*/ + +// Impresión básica + +write("Hola, "); +writeln("Mundo!"); + +// write y writeln pueden tomar una lista de cosas para imprimir. +// Cada cosa está impresa justo al lado de las demás, ¡así que incluye espacios! +writeln("hay ", 3, " comas (\",\") en esta línea de código"); + +// Diferentes canales de salida: +stdout.writeln("Esto va a la salida estándar, al igual que lo hace writeln()"); +stderr.writeln("Esto va al error estándar"); + + +// Las variables no tienen que escribirse explícitamente +// mientras el compilador pueda determinar el tipo que contendrá. + +// 10 es un entero, asi que myVar es explícitamente un entero +var myVar = 10; +myVar = -10; +var mySecondVar = myVar; +// var anError; sería un error en tiempo de compilación + +// Podemos (y debemos) escribir cosas explícitamente. +var myThirdVar: real; +var myFourthVar: real = -1.234; +myThirdVar = myFourthVar; + +// Tipos + +// Hay varios tipos básicos. +var myInt: int = -1000; // Enteros firmados +var myUint: uint = 1234; // Enteros sin-firmar +var myReal: real = 9.876; // Números de punto flotante +var myImag: imag = 5.0i; // Números imaginarios +var myCplx: complex = 10 + 9i; // Números complejos +myCplx = myInt + myImag; // Otra manera de formar números complejos +var myBool: bool = false; // Booleanos +var myStr: string = "Una cadena..."; // Cadenas +var singleQuoteStr = 'Otra cadena...'; // Cadena literal con comillas simples + +// Algunos tipos pueden tener tamaños. +var my8Int: int(8) = 10; // Entero de 8 bit (one byte); +var my64Real: real(64) = 1.516; // Real de 64 bit (8 bytes) + +// Conversion de tipos. +var intFromReal = myReal : int; +var intFromReal2: int = myReal : int; + +// Alias de tipo. +type chroma = int; // Tipo de un solo tono +type RGBColor = 3*chroma; // Tipo que representa un color completo +var black: RGBColor = (0,0,0); +var white: RGBColor = (255, 255, 255); + +// Constantes y Parámetros + +// una variable const es una constante y no se puede cambiar después de +// establecerla en tiempo de ejecución. +const almostPi: real = 22.0/7.0; + +// Un parámetro es una constante cuyo valor debe conocerse estáticamente +// en tiempo de compilación. + +param compileTimeConst: int = 16; + +// El modificador de configuración permite establecer valores en la línea de comando. +// Establece valores con --varCmdLineArg=Value o --varCmdLineArg Value en tiempo de ejecución. +config var varCmdLineArg: int = -123; +config const constCmdLineArg: int = 777; + +// config param se puede configurar en tiempo de compilación. +// Establece valores con --set paramCmdLineArg=value en tiempo de compilación. +config param paramCmdLineArg: bool = false; +writeln(varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg); + +// Referencias + +// ref funciona de manera muy similar a una referencia en C ++. En Chapel, +// no se puede hacer una referencia como alias a una variable distinta +// de la variable con la que se inicializa. + +// Aquí, refToActual se refiere a actual. +var actual = 10; +ref refToActual = actual; +writeln(actual, " == ", refToActual); // imprime el mismo valor +actual = -123; // modificar actual (a lo que refToActual se refiere) +writeln(actual, " == ", refToActual); // imprime el mismo valor +refToActual = 99999999; // modificar a qué se refiere refToActual (que es actual) +writeln(actual, " == ", refToActual); // imprime el mismo valor + +// Operadores + +// Operadores matemáticos: +var a: int, thisInt = 1234, thatInt = 5678; +a = thisInt + thatInt; // Adicción +a = thisInt * thatInt; // Multiplicación +a = thisInt - thatInt; // Substracción +a = thisInt / thatInt; // División +a = thisInt ** thatInt; // Exponenciación +a = thisInt % thatInt; // residuo (módulo) + +// Operadores logicos: +var b: bool, thisBool = false, thatBool = true; +b = thisBool && thatBool; // Lógico y +b = thisBool || thatBool; // Lógico o +b = !thisBool; // Lógico negación + +// Operadores relacionales: +b = thisInt > thatInt; // Mas grande que +b = thisInt >= thatInt; // Mas grande o igual que +b = thisInt < a && a <= thatInt; // Menor que, y, Menor o igual que +b = thisInt != thatInt; // No es igual a +b = thisInt == thatInt; // es igual a + +// Operadores bit a bit: +a = thisInt << 10; // Desplazamiento de bit izquierdo por 10 bits; +a = thatInt >> 5; // Desplazamiento de bit derecho por 5 bits; +a = ~thisInt; // Negación bit a bit +a = thisInt ^ thatInt; // bit a bit exclusivo o + +// Operadores de asignación compuesta: +a += thisInt; // Adición-igual (a = a + thisInt;) +a *= thatInt; // Multiplicación-igual (a = a * thatInt;) +b &&= thatBool; // Lógico e igual (b = b && thatBool;) +a <<= 3; // Desplazamiento a la izquierda igual (a = a << 10;) + +// A diferencia de otros lenguajes de familia C, no hay operadores de +// pre / post-incremento / decremento, tales como: +// +// ++j, --j, j++, j-- + +// Operador de intercambio: +var old_this = thisInt; +var old_that = thatInt; +thisInt <=> thatInt; // Intercambia los valores de thisInt y thatInt +writeln((old_this == thatInt) && (old_that == thisInt)); + +// También se pueden definir sobrecargas del operador, como veremos con los procedimientos. + +// Tuplas + +// Las tuplas pueden ser del mismo tipo o de diferentes tipos. +var sameTup: 2*int = (10, -1); +var sameTup2 = (11, -6); +var diffTup: (int,real,complex) = (5, 1.928, myCplx); +var diffTupe2 = (7, 5.64, 6.0+1.5i); + +// Se puede acceder a las tuplas usando corchetes o paréntesis, +// y están indexadas en base 1. +writeln("(", sameTup[1], ",", sameTup(2), ")"); +writeln(diffTup); + +// Las tuplas también se pueden escribir. +diffTup(1) = -1; + +// Los valores de tupla se pueden expandir a sus propias variables. +var (tupInt, tupReal, tupCplx) = diffTup; +writeln(diffTup == (tupInt, tupReal, tupCplx)); + +// También son útiles para imprimit una lista de variables, +// como es común en la depuración. +writeln((a,b,thisInt,thatInt,thisBool,thatBool)); + +// Flujo de control + +// if - then - else funciona como cualquier otro lenguaje de la familia C. +if 10 < 100 then + writeln("All is well"); + +if -1 < 1 then + writeln("Continuando creyendo en la realidad"); +else + writeln("¡Envia un matemático!, algo está mal"); + +// Puedes usar paréntesis si lo prefieres. +if (10 > 100) { + writeln("El Universo está roto, Por favor reinicie el universo."); +} + +if a % 2 == 0 { + writeln(a, " es par."); +} else { + writeln(a, " es impar."); +} + +if a % 3 == 0 { + writeln(a, " es divisible entre 3."); +} else if a % 3 == 1 { + writeln(a, " es divisible entre 3 con un residuo de 1."); +} else { + writeln(b, " es divisible entre 3 con un residuo de 2."); +} + +// Ternario: if - then - else en una declaración. +var maximum = if thisInt < thatInt then thatInt else thisInt; + +// las declaraciones select son muy parecidas a las declaraciones switch +// en otros idiomas. Sin embargo, las declaraciones select no caen +// en cascada como en C o Java. +var inputOption = "anOption"; +select inputOption { + when "anOption" do writeln("Escoge 'anOption'"); + when "otherOption" { + writeln("Escoge 'otherOption'"); + writeln("Que tiene un cuerpo"); + } + otherwise { + writeln("Cualquier otra entrada"); + writeln("El caso otherwise no necesita hacerse si el cuerpo es de una línea"); + } +} + +// Los bucles while y do-while también se comportan como sus contrapartes en C. +var j: int = 1; +var jSum: int = 0; +while (j <= 1000) { + jSum += j; + j += 1; +} +writeln(jSum); + +do { + jSum += j; + j += 1; +} while (j <= 10000); +writeln(jSum); + +// Los bucles for son muy parecidos a los de Python porque iteran en un rango. +// Los rangos (como la expresión 1..10 a continuación) son un objeto de primera clase +// en Chapel, y como tal pueden almacenarse en variables. +for i in 1..10 do write(i, ", "); +writeln(); + +var iSum: int = 0; +for i in 1..1000 { + iSum += i; +} +writeln(iSum); + +for x in 1..10 { + for y in 1..10 { + write((x,y), "\t"); + } + writeln(); +} + +// Rangos y Dominios + +// Los bucles y matrices utilizan rangos y dominios para definir un conjunto de índices +// que se pueden iterar. Los rangos son índices enteros unidimensionales, mientras +// que los dominios pueden ser multidimensionales y representan índices +// de diferentes tipos. + +// Son tipos ciudadanos de primera clase y pueden asignarse a variables. +var range1to10: range = 1..10; // 1, 2, 3, ..., 10 +var range2to11 = 2..11; // 2, 3, 4, ..., 11 +var rangeThisToThat: range = thisInt..thatInt; // usando variables +var rangeEmpty: range = 100..-100; // esto es válido pero no contiene índices + +// Los rangos pueden ser ilimitados. +var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ; // 1, 2, 3, 4, 5, ... +var rangeNegInfTo1 = ..1; // ..., -4, -3, -2, -1, 0, 1 + +// Los rangos se pueden andar (y revertir) utilizando el operador by. +var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10 +var reverse2to10by2 = 2..10 by -2; // 10, 8, 6, 4, 2 + +var trapRange = 10..1 by -1; // No te dejes engañar, esto sigue siendo un rango vacío +writeln("Size of range ", trapRange, " = ", trapRange.length); + +// Note: range(boundedType= ...) and range(stridable= ...) solo son necesarios +// si escribimos explícitamente la variable. + +// El punto final de un rango se puede determinar utilizando el operador de conteo (#). +var rangeCount: range = -5..#12; // intervalo de -5 to 6 + +// Los operadores pueden ser mixtos. +var rangeCountBy: range(stridable=true) = -5..#12 by 2; // -5, -3, -1, 1, 3, 5 +writeln(rangeCountBy); + +// Se pueden consultar las propiedades del rango. +// En este ejemplo, imprime el primer índice, el último índice, el número de índices, +// el paso y si 2 se incluye en el rango. +writeln((rangeCountBy.first, rangeCountBy.last, rangeCountBy.length, + rangeCountBy.stride, rangeCountBy.member(2))); + +for i in rangeCountBy { + write(i, if i == rangeCountBy.last then "\n" else ", "); +} + +// Los dominios rectangulares se definen usando la misma sintaxis de rango, +// pero se requiere que estén delimitados (a diferencia de los rangos). +var domain1to10: domain(1) = {1..10}; // 1D domain from 1..10; +var twoDimensions: domain(2) = {-2..2,0..2}; // 2D domain over product of ranges +var thirdDim: range = 1..16; +var threeDims: domain(3) = {thirdDim, 1..10, 5..10}; // using a range variable + +// Los dominios también pueden ser redimensionados +var resizedDom = {1..10}; +writeln("antes, resizedDom = ", resizedDom); +resizedDom = {-10..#10}; +writeln("despues, resizedDom = ", resizedDom); + +// Los índices pueden iterarse como tuplas. +for idx in twoDimensions do + write(idx, ", "); +writeln(); + +// Estas tuplas también pueden ser deconstruidas. +for (x,y) in twoDimensions { + write("(", x, ", ", y, ")", ", "); +} +writeln(); + +// Los dominios asociativos actúan como conjuntos. +var stringSet: domain(string); // empty set of strings +stringSet += "a"; +stringSet += "b"; +stringSet += "c"; +stringSet += "a"; // Redundant add "a" +stringSet -= "c"; // Remove "c" +writeln(stringSet.sorted()); + +// Los dominios asociativos también pueden tener una sintaxis literal +var intSet = {1, 2, 4, 5, 100}; + +// Tanto los rangos como los dominios se pueden dividir para producir un rango +// o dominio con la intersección de los índices. +var rangeA = 1.. ; // range from 1 to infinity +var rangeB = ..5; // range from negative infinity to 5 +var rangeC = rangeA[rangeB]; // resulting range is 1..5 +writeln((rangeA, rangeB, rangeC)); + +var domainA = {1..10, 5..20}; +var domainB = {-5..5, 1..10}; +var domainC = domainA[domainB]; +writeln((domainA, domainB, domainC)); + +// Matrices + +// Las matrices son similares a otros lenguajes. +// Sus tamaños son definidos usndo dominions que repretsenten sus indices. +var intArray: [1..10] int; +var intArray2: [{1..10}] int; // equivalent + +// Pueden ser accedidos usando brackets o paréntesis +for i in 1..10 do + intArray[i] = -i; +writeln(intArray); + +// No podemos acceder a intArray[0] porque existe fuera del conjunto de índices, +// {1..10}, que definimos al principio. +// intArray [11] es ilegal por la misma razón. +var realDomain: domain(2) = {1..5,1..7}; +var realArray: [realDomain] real; +var realArray2: [1..5,1..7] real; // equivalent +var realArray3: [{1..5,1..7}] real; // equivalent + +for i in 1..5 { + for j in realDomain.dim(2) { // Solo use la segunda dimensión del dominio + realArray[i,j] = -1.61803 * i + 0.5 * j; // Acceso usando la lista de índice + var idx: 2*int = (i,j); // Nota: 'índice' es una palabra reservada + realArray[idx] = - realArray[(i,j)]; // Indice usando tuplas + } +} + +// Las matrices tienen dominios como miembros y pueden ser iterados de manera normal. +for idx in realArray.domain { // De nuevo, idx es una tupla 2*int + realArray[idx] = 1 / realArray[idx[1], idx[2]]; // Acceso por tupla y lista +} + +writeln(realArray); + +// Los valores de una matriz también se pueden iterar directamente. +var rSum: real = 0; +for value in realArray { + rSum += value; // Read a value + value = rSum; // Write a value +} +writeln(rSum, "\n", realArray); + +// Las matrices asociativas (diccionarios) se pueden crear utilizando dominios asociativos. +var dictDomain: domain(string) = { "one", "two" }; +var dict: [dictDomain] int = ["one" => 1, "two" => 2]; +dict["three"] = 3; // Adiciona 'three' a 'dictDomain' implícitamente +for key in dictDomain.sorted() do + writeln(dict[key]); + +// Las matrices se pueden asignar entre sí de diferentes maneras. +// Estos arreglos se usarán en el ejemplo. + +var thisArray : [0..5] int = [0,1,2,3,4,5]; +var thatArray : [0..5] int; + +// Primero, simplemente asigna uno al otro. Esto copia esta matriz en +// thatArray, en lugar de simplemente crear una referencia. Por lo tanto, modificando +// thisArray tampoco modifica thatArray. +thatArray = thisArray; +thatArray[1] = -1; +writeln((thisArray, thatArray)); + +// Asigna un segmento de una matriz a un segmento (del mismo tamaño) en el otro. +thatArray[4..5] = thisArray[1..2]; +writeln((thisArray, thatArray)); + +// Las operaciones también se pueden promover para trabajar en arreglos. +// 'thisPlusThat' también es una matriz. +var thisPlusThat = thisArray + thatArray; +writeln(thisPlusThat); + +// Continuando, las matrices y los bucles también pueden ser expresiones, donde +// la expresión del cuerpo del bucle es el resultado de cada iteración. +var arrayFromLoop = for i in 1..10 do i; +writeln(arrayFromLoop); + +// Una expresión puede resultar en nada, como cuando se filtra con una expresión if. +var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i; + +writeln(arrayFromLoop); + +// Las expresiones de matriz también se pueden escribir con una notación de paréntesis. +// Nota: esta sintaxis utiliza el concepto paralelo forall discutido más adelante. +var evensOrFivesAgain = [i in 1..10] if (i % 2 == 0 || i % 5 == 0) then i; + +// They can also be written over the values of the array. +arrayFromLoop = [value in arrayFromLoop] value + 1; + + +// Procedimientos + +// Los procedimientos de Chapel tienen funciones de sintaxis similares en otros idiomas. +proc fibonacci(n : int) : int { + if n <= 1 then return n; + return fibonacci(n-1) + fibonacci(n-2); +} + +// Los parámetros de entrada pueden estar sin tipo para crear un procedimiento genérico. +proc doublePrint(thing): void { + write(thing, " ", thing, "\n"); +} + +// Se puede inferir el tipo de retorno, siempre que el compilador pueda resolverlo. +proc addThree(n) { + return n + 3; +} + +doublePrint(addThree(fibonacci(20))); + +// También es posible tomar un número variable de parámetros. +proc maxOf(x ...?k) { + // x se refiere a una tupla de un tipo, con k elementos + var maximum = x[1]; + for i in 2..k do maximum = if maximum < x[i] then x[i] else maximum; + return maximum; +} +writeln(maxOf(1, -10, 189, -9071982, 5, 17, 20001, 42)); + +// Los procedimientos pueden tener valores de parámetros predeterminados, y +// los parámetros pueden nombrarse en la llamada, incluso fuera de orden. +proc defaultsProc(x: int, y: real = 1.2634): (int,real) { + return (x,y); +} + +writeln(defaultsProc(10)); +writeln(defaultsProc(x=11)); +writeln(defaultsProc(x=12, y=5.432)); +writeln(defaultsProc(y=9.876, x=13)); + +// El operador ? se llama operador de consulta y se usa para tomar valores +// indeterminados como tuplas o tamaños de matriz y tipos genéricos. +// Por ejemplo, tomar matrices como parámetros. + +// El operador de consulta se utiliza para determinar el dominio de A. +// Esto es útil para definir el tipo de retorno, aunque no es obligatorio. +proc invertArray(A: [?D] int): [D] int{ + for a in A do a = -a; + return A; +} + +writeln(invertArray(intArray)); + +// Podemos consultar el tipo de argumentos a los procedimientos genéricos. +// Aquí definimos un procedimiento que toma dos argumentos del mismo tipo, +// pero no definimos cuál es ese tipo. +proc genericProc(arg1 : ?valueType, arg2 : valueType): void { + select(valueType) { + when int do writeln(arg1, " and ", arg2, " are ints"); + when real do writeln(arg1, " and ", arg2, " are reals"); + otherwise writeln(arg1, " and ", arg2, " are somethings!"); + } +} + +genericProc(1, 2); +genericProc(1.2, 2.3); +genericProc(1.0+2.0i, 3.0+4.0i); + +// También podemos imponer una forma de polimorfismo con la cláusula where +// Esto permite que el compilador decida qué función usar. + +// Nota: Eso significa que toda la información debe conocerse en tiempo de compilación. +// El modificador param en el argumento se usa para imponer esta restricción. +proc whereProc(param N : int): void + where (N > 0) { + writeln("N is greater than 0"); +} + +proc whereProc(param N : int): void + where (N < 0) { + writeln("N is less than 0"); +} + +whereProc(10); +whereProc(-1); + +// whereProc(0) daría lugar a un error del compilador porque no hay funciones +// que satisfagan la condición de la cláusula where. +// Podríamos haber definido un whereProc sin una cláusula where que +// hubiera servido como captura para todos los demás casos (de los cuales solo hay uno). + +// Las cláusulas where también se pueden usar para restringir según el tipo de argumento. +proc whereType(x: ?t) where t == int { + writeln("Inside 'int' version of 'whereType': ", x); +} + +proc whereType(x: ?t) { + writeln("Inside general version of 'whereType': ", x); +} + +whereType(42); +whereType("hello"); + +// Intenciones + +/* Los modificadores de intención en los argumentos transmiten cómo esos argumentos se pasan al procedimiento. + + * in: copia arg adentro, pero no afuera + * out: copia arg, pero no dentro + * inout: copia arg adentro, copia arg afuera + * ref: pasa arg por referencia +*/ +proc intentsProc(in inarg, out outarg, inout inoutarg, ref refarg) { + writeln("Adentro antes: ", (inarg, outarg, inoutarg, refarg)); + inarg = inarg + 100; + outarg = outarg + 100; + inoutarg = inoutarg + 100; + refarg = refarg + 100; + writeln("Adentro después: ", (inarg, outarg, inoutarg, refarg)); +} + +var inVar: int = 1; +var outVar: int = 2; +var inoutVar: int = 3; +var refVar: int = 4; +writeln("Afuera antes: ", (inVar, outVar, inoutVar, refVar)); +intentsProc(inVar, outVar, inoutVar, refVar); +writeln("Afuera después: ", (inVar, outVar, inoutVar, refVar)); + +// Del mismo modo, podemos definir intentos en el tipo de retorno. +// refElement devuelve una referencia a un elemento de la matriz. Esto tiene más sentido +// práctico para los métodos de clase donde las referencias a elementos en una estructura +// de datos se devuelven a través de un método o iterador. +proc refElement(array : [?D] ?T, idx) ref : T { + return array[idx]; +} + +var myChangingArray : [1..5] int = [1,2,3,4,5]; +writeln(myChangingArray); +ref refToElem = refElement(myChangingArray, 5); // Almacena una referencia al elemento en variable de referencia +writeln(refToElem); +refToElem = -2; // modifica referencia que, a su vez, modifica el valor real en la matriz +writeln(refToElem); +writeln(myChangingArray); + +// Definiciones del operador + +// Chapel permite que los operadores se sobrecarguen. +// Podemos definir los operadores unarios: +// + - ! ~ +// y los operadores binarios: +// + - * / % ** == <= >= < > << >> & | ˆ by +// += -= *= /= %= **= &= |= ˆ= <<= >>= <=> + +// Exclusivo u operador booleano. +proc ^(left : bool, right : bool): bool { + return (left || right) && !(left && right); +} + +writeln(true ^ true); +writeln(false ^ true); +writeln(true ^ false); +writeln(false ^ false); + +// Define un operador * en cualquiera de los dos tipos que devuelve una tupla de esos tipos. +proc *(left : ?ltype, right : ?rtype): (ltype, rtype) { + writeln("\tIn our '*' overload!"); + return (left, right); +} + +writeln(1 * "a"); // Utiliza nuestro * operador. +writeln(1 * 2); // Utiliza el operador predeterminado *. + +// Note: Podrías romper todo si te descuidas con tus sobrecargas. +// Esto aquí lo romperá todo. No lo hagas + +/* + proc +(left: int, right: int): int { + return left - right; + } +*/ + +// Iteradores + +// Los iteradores son hermanas del procedimiento, y casi todo lo relacionado +// con los procedimientos también se aplica a los iteradores. Sin embargo, en lugar de +// devolver un solo valor, los iteradores pueden generar múltiples valores en un bucle. + +// Esto es útil cuando se necesita un conjunto u orden complicado de iteraciones, +// ya que permite que el código que define las iteraciones +// se separe del cuerpo del bucle. +iter oddsThenEvens(N: int): int { + for i in 1..N by 2 do + yield i; // yield values instead of returning. + for i in 2..N by 2 do + yield i; +} + +for i in oddsThenEvens(10) do write(i, ", "); +writeln(); + +// Los iteradores también pueden ceder condicionalmente, cuyo resultado puede ser nada +iter absolutelyNothing(N): int { + for i in 1..N { + if N < i { // Always false + yield i; // Yield statement never happens + } + } +} + +for i in absolutelyNothing(10) { + writeln("Woa there! absolutelyNothing yielded ", i); +} + +// Podemos comprimir dos o más iteradores (que tienen el mismo número de iteraciones) +// usando zip () para crear un solo iterador comprimido, donde cada iteración +// del iterador comprimido produce una tupla de un valor de cada iterador. +for (positive, negative) in zip(1..5, -5..-1) do + writeln((positive, negative)); + +// La iteración de la cremallera es bastante importante en la asignación de matrices, +// segmentos de matrices y expresiones de matriz / bucle. +var fromThatArray : [1..#5] int = [1,2,3,4,5]; +var toThisArray : [100..#5] int; + +// Algunas operaciones de cierre implementan otras operaciones. +// La primera declaración y el bucle son equivalentes. +toThisArray = fromThatArray; +for (i,j) in zip(toThisArray.domain, fromThatArray.domain) { + toThisArray[i] = fromThatArray[j]; +} + +// Estos dos pedazos también son equivalentes. +toThisArray = [j in -100..#5] j; +writeln(toThisArray); + +for (i, j) in zip(toThisArray.domain, -100..#5) { + toThisArray[i] = j; +} +writeln(toThisArray); + +/* + Esto es muy importante para entender por qué esta declaración + exhibe un error de tiempo de ejecución. +*/ + +/* + var iterArray : [1..10] int = [i in 1..10] if (i % 2 == 1) then i; +*/ + +// Aunque el dominio de la matriz y la expresión de bucle son del mismo tamaño, +// el cuerpo de la expresión puede considerarse como un iterador. +// Debido a que los iteradores pueden producir nada, ese iterador produce un número +// diferente de cosas que el dominio de la matriz o bucle, que no está permitido. + +// Clases + +// Las clases son similares a las de C ++ y Java, asignadas en el montón. +class MyClass { + +// Variables miembro + var memberInt : int; + var memberBool : bool = true; + +// Inicializador definido explícitamente. +// También obtenemos el inicializador generado por el compilador, con un argumento por campo. +// Tenga en cuenta que pronto no habrá un inicializador generado por el compilador +// cuando definamos los inicializadores explícitamente. + proc init(val : real) { + this.memberInt = ceil(val): int; + } + +// Desinicializador explícitamente definido. +// Si no escribiéramos uno, obtendríamos el desinicializador generado por el compilador, +// que tiene un cuerpo vacío. + proc deinit() { + writeln("MyClass deinitializer called ", (this.memberInt, this.memberBool)); + } + +// Métodos de clase. + proc setMemberInt(val: int) { + this.memberInt = val; + } + + proc setMemberBool(val: bool) { + this.memberBool = val; + } + + proc getMemberInt(): int{ + return this.memberInt; + } + + proc getMemberBool(): bool { + return this.memberBool; + } +} // termina MyClass + +// Llame al inicializador generado por el compilador, +// utilizando el valor predeterminado para memberBool. +var myObject = new MyClass(10); + myObject = new MyClass(memberInt = 10); // Equivalente +writeln(myObject.getMemberInt()); + +// Same, but provide a memberBool value explicitly. +var myDiffObject = new MyClass(-1, true); + myDiffObject = new MyClass(memberInt = -1, memberBool = true); // Equivalente +writeln(myDiffObject); + +// Llame al inicializador que escribimos. +var myOtherObject = new MyClass(1.95); + myOtherObject = new MyClass(val = 1.95); // Equivalente +writeln(myOtherObject.getMemberInt()); + +// También podemos definir un operador en nuestra clase, +// pero la definición tiene que estar fuera de la definición de la clase. +proc +(A : MyClass, B : MyClass) : MyClass { + return new MyClass(memberInt = A.getMemberInt() + B.getMemberInt(), + memberBool = A.getMemberBool() || B.getMemberBool()); +} + +var plusObject = myObject + myDiffObject; +writeln(plusObject); + +// Destrucción. +delete myObject; +delete myDiffObject; +delete myOtherObject; +delete plusObject; + +// Las clases pueden heredar de una o más clases primarias +class MyChildClass : MyClass { + var memberComplex: complex; +} + +// Aquí hay un ejemplo de clases genéricas. +class GenericClass { + type classType; + var classDomain: domain(1); + var classArray: [classDomain] classType; + +// Constructor explícito. + proc GenericClass(type classType, elements : int) { + this.classDomain = {1..#elements}; + } + +// Copiar constructor. +// Nota: Todavía tenemos que poner el tipo como argumento, pero podemos usar +// el operador de consulta (?) como predeterminado para el tipo del otro objeto. +// Además, podemos aprovechar esto para permitir a nuestro constructor de copias +// copiar clases de diferentes tipos y emitir sobre la marcha. + proc GenericClass(other : GenericClass(?otherType), + type classType = otherType) { + this.classDomain = other.classDomain; + // Copiar y Convertir + for idx in this.classDomain do this[idx] = other[idx] : classType; + } + +// Defina la notación de corchetes en un objeto GenericClass +// para que pueda comportarse como una matriz normal +// i.e. objVar[i] or objVar(i) + proc this(i : int) ref : classType { + return this.classArray[i]; + } + +// Definir un iterador implícito para que la clase produzca +// valores de la matriz a un bucle +// i.e. for i in objVar do ... + iter these() ref : classType { + for i in this.classDomain do + yield this[i]; + } +} // end GenericClass + +// Podemos asignar a la matriz de miembros del objeto usando la notación de +// corchete que definimos. +var realList = new GenericClass(real, 10); +for i in realList.classDomain do realList[i] = i + 1.0; + +// Podemos iterar sobre los valores en nuestra lista con el iterador +// que definimos. +for value in realList do write(value, ", "); +writeln(); + +// Haga una copia de realList usando el constructor de copias. +var copyList = new GenericClass(realList); +for value in copyList do write(value, ", "); +writeln(); + +// Haga una copia de realList y cambie el tipo, también utilizando el constructor de copias. +var copyNewTypeList = new GenericClass(realList, int); +for value in copyNewTypeList do write(value, ", "); +writeln(); + + +// Módulos + +// Los módulos son la forma en que Chapel administra los espacios de nombres. +// Los archivos que contienen estos módulos no necesitan ser nombrados después +// de los módulos (como en Java), pero los archivos implícitamente nombran módulos. +// Por ejemplo, este archivo nombra implícitamente el módulo learnChapelInYMinutes + +module OurModule { + +// Podemos usar módulos dentro de otros módulos. +// Time es uno de los módulos estándar. + use Time; + +// Usaremos este procedimiento en la sección de paralelismo. + proc countdown(seconds: int) { + for i in 1..seconds by -1 { + writeln(i); + sleep(1); + } + } + +// Es posible crear nidos de módulos arbitrariamente profundos. +// i.e. submódulos de OurModule + module ChildModule { + proc foo() { + writeln("ChildModule.foo()"); + } + } + + module SiblingModule { + proc foo() { + writeln("SiblingModule.foo()"); + } + } +} // end OurModule + +// Usando OurModule también usa todos los módulos que usa. +// Como OurModule usa Time, nosotros también usamos Time. +use OurModule; + +// En este punto no hemos usado ChildModule o SiblingModule, por lo que sus símbolos +// (es decir, foo) no están disponibles para nosotros. Sin embargo, los nombres de +// los módulos están disponibles y podemos llamar explícitamente a foo () a través de ellos. +SiblingModule.foo(); +OurModule.ChildModule.foo(); + +// Ahora usamos ChildModule, que permite llamadas no calificadas. +use ChildModule; +foo(); + +// Paralelismo + +// En otros idiomas, el paralelismo generalmente se realiza con librerias complicadas +// y extrañas jerarquías de estructura de clases. +// Chapel lo tiene directamente en el idioma. + +// Podemos declarar un procedimiento principal, pero todo el código anterior +// a main todavía se ejecuta. +proc main() { + +// Una declaración de inicio hará girar el cuerpo de esa declaración en una nueva tarea. +// Una declaración de sincronización garantizará que el progreso de la tarea principal +// no avance hasta que los hijos hayan sincronizado nuevamente. + + sync { + begin { // Inicio del cuerpo de la nueva tarea. + var a = 0; + for i in 1..1000 do a += 1; + writeln("Done: ", a); + } // Fin del nuevo cuerpo de tareas + writeln("escindió una tarea!"); + } + writeln("De nuevo juntos"); + + proc printFibb(n: int) { + writeln("fibonacci(",n,") = ", fibonacci(n)); + } + +// Una declaración de cobegin girará cada declaración del cuerpo en una nueva tarea. +// Observe aquí que las impresiones de cada declaración pueden ocurrir en +// cualquier orden. + cobegin { + printFibb(20); // nueva tarea + printFibb(10); // nueva tarea + printFibb(5); // nueva tarea + { + // Este es un cuerpo de declaración anidado y, por lo tanto, es una + // declaración única para la declaración principal, ejecutada + // por una sola tarea. + writeln("esto se "); + writeln("ejecuta"); + writeln("como un todo"); + } + } + +// Un bucle coforall creará una nueva tarea para CADA iteración. +// Nuevamente vemos que las impresiones suceden en cualquier orden. +// NOTA: ¡coforall debe usarse solo para crear tareas! +// ¡Usarlo para iterar sobre una estructura es una muy mala idea! + var num_tasks = 10; // Number of tasks we want + coforall taskID in 1..#num_tasks { + writeln("Hola de tarea# ", taskID); + } + +// los bucles forall son otro bucle paralelo, pero solo crean un número +// menor de tareas, específicamente --dataParTasksPerLocale = número de tareas. + forall i in 1..100 { + write(i, ", "); + } + writeln(); + +// Aquí vemos que hay secciones que están en orden, seguidas de una sección +// que no seguiría (por ejemplo, 1, 2, 3, 7, 8, 9, 4, 5, 6,). +// Esto se debe a que cada tarea está asumiendo un fragmento del rango 1..10 +// (1..3, 4..6 o 7..9) haciendo ese fragmento en serie, pero cada tarea ocurre en paralelo. +// Sus resultados pueden depender de su máquina y configuración + +// Para los bucles forall y coforall, la ejecución de la tarea principal +// no continuará hasta que todos los hijos se sincronicen. + +// los bucles forall son particularmente útiles para la iteración paralela sobre matrices. +// Hagamos un experimento para ver qué tan rápido es un ciclo paralelo. + + use Time; // Importe el módulo Time para usar objetos de Timer + var timer: Timer; + var myBigArray: [{1..4000,1..4000}] real; // Gran matriz en la que escribiremos + +// Experimento en serie: + timer.start(); // Iniciar temporizador + for (x,y) in myBigArray.domain { // Iteración en serie + myBigArray[x,y] = (x:real) / (y:real); + } + timer.stop(); // Detener temporizador + writeln("Serial: ", timer.elapsed()); // Imprimir tiempo transcurrido + timer.clear(); // Limpia el temporizador para bucle paralelo + +// Experimento Paralelo: + timer.start(); // Iniciar temporizador + forall (x,y) in myBigArray.domain { // Iteración paralela + myBigArray[x,y] = (x:real) / (y:real); + } + timer.stop(); // Detener temporizador + writeln("Parallel: ", timer.elapsed()); // Imprimir tiempo transcurrido + timer.clear(); + +// Puede que hayas notado que (dependiendo de cuántos núcleos tengas) +// el ciclo paralelo fue más rápido que el ciclo serial. + +// La expresión de bucle estilo corchete descrita mucho antes utiliza +// implícitamente un bucle forall. + [val in myBigArray] val = 1 / val; // Operación paralela + +// Las variables atómicas, comunes a muchos idiomas, son aquellas cuyas operaciones +// ocurren sin interrupciones. Por lo tanto, varios subprocesos pueden modificar +// las variables atómicas y pueden saber que sus valores son seguros. +// Las variables atómicas de la capilla pueden ser de tipo bool, int, uint y real. + var uranium: atomic int; + uranium.write(238); // escribir atómicamente una variable + writeln(uranium.read()); // leer atómicamente una variable + +// Las operaciones atómicas se describen como funciones, por lo que puede definir +// las suyas propias. + uranium.sub(3); // restar atómicamente una variable + writeln(uranium.read()); + + var replaceWith = 239; + var was = uranium.exchange(replaceWith); + writeln("El uranio era", was, ", pero ahora es ", replaceWith); + + var isEqualTo = 235; + if uranium.compareExchange(isEqualTo, replaceWith) { + writeln("El uranio era igual a ", isEqualTo, + " pero valor reemplazado por", replaceWith); + } else { + writeln("uranio no era igual a ", isEqualTo, + " así que el valor permanece igual... sea lo que sea"); + } + + sync { + begin { // Tarea del lector + writeln("Lector: esperando que el uranio sea ", isEqualTo); + uranium.waitFor(isEqualTo); + writeln("Lector: el uranio fue configurado (por alguien) para ", isEqualTo); + } + + begin { // Tarea de escritor + writeln("Escritor: establecerá uranio en el valor ", isEqualTo, " en..."); + countdown(3); + uranium.write(isEqualTo); + } + } + +// las variables de sincronización tienen dos estados: vacío y lleno. +// Si lee una variable vacía o escribe una variable completa, +// se espera hasta que la variable esté llena o vacía nuevamente. + var someSyncVar$: sync int; // varName$ Es una convención, no una ley. + sync { + begin { // Tarea del lector + writeln("Lector: esperando leer."); + var read_sync = someSyncVar$; + writeln("Lector: el valor es ", read_sync); + } + + begin { // Tarea de escritor + writeln("Escritor: escribirá en..."); + countdown(3); + someSyncVar$ = 123; + } + } + +// las variales individuales solo se pueden escribir una vez. +// Una lectura en un solo no escrito da como resultado una espera, +// pero cuando la variable tiene un valor, puede leerse indefinidamente. + var someSingleVar$: single int; // varName$ Es una convención, no una ley. + sync { + begin { // Tarea del lector + writeln("Lector: esperando leer."); + for i in 1..5 { + var read_single = someSingleVar$; + writeln("Lector: iteración ", i,", y el valor es ", read_single); + } + } + + begin { // Tarea de escritor + writeln("Escritor: escribirá en ..."); + countdown(3); + someSingleVar$ = 5; // primero y único escrito. + } + } + +// Aquí hay un ejemplo usando atómica y una variable de sincronización +// para crear un mutex de cuenta regresiva +// (también conocido como multiplexor). + var count: atomic int; // nuestro mostrador + var lock$: sync bool; // la cerradura mutex + + count.write(2); // Solo deje dos tareas a la vez. + lock$.writeXF(true); // Establezca lock$ en completo (desbloqueado) + // Nota: el valor en realidad no importa, solo el estado + // (completo: desbloqueado / vacio: bloqueado) + // Además, writeXF() llena (F) la variable de sincronización independientemente de su estado (X) + + coforall task in 1..#5 { // Generar tareas + // Create a barrier + do { + lock$; // Leer lock$ (espera) + } while (count.read() < 1); // Sigue esperando hasta que se abra un lugar + + count.sub(1); //disminuir el contador + lock$.writeXF(true); // Establezca lock$ en completo (señal) + + // 'Trabajo' actual + writeln("Tarea #", task, " trabajando"); + sleep(2); + + count.add(1); // Incrementa el contador + lock$.writeXF(true); // Establezca lock$ en completo (señal) + } + +// Podemos definir las operaciones + * & | ^ && || min max minloc maxloc +// sobre una matriz completa usando escaneos y reducciones. +// Las reducciones aplican la operación en toda la matriz +// y dan como resultado un valor escalar. + + var listOfValues: [1..10] int = [15,57,354,36,45,15,456,8,678,2]; + var sumOfValues = + reduce listOfValues; + var maxValue = max reduce listOfValues; // 'max' da solo el valor máximo + +// maxloc proporciona el valor máximo y el índice del valor máximo. +// Nota: Tenemos que comprimir la matriz y el dominio junto con el iterador zip. + var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues, + listOfValues.domain); + + writeln((sumOfValues, maxValue, idxOfMax, listOfValues[idxOfMax])); + +// Los escaneos aplican la operación de forma incremental y devuelven una matriz +// con los valores de la operación en ese índice a medida que avanza a través +// de la matriz desde array.domain.low hasta array.domain.high. + var runningSumOfValues = + scan listOfValues; + var maxScan = max scan listOfValues; + writeln(runningSumOfValues); + writeln(maxScan); +} // end main() +``` + +¿Para quién es este tutorial? +------------------------- + +Este tutorial es para personas que desean aprender las cuerdas de chapel sin tener +que escuchar sobre qué mezcla de fibras son las cuerdas, o cómo fueron trenzadas, +o cómo las configuraciones de trenzas difieren entre sí. No le enseñará cómo +desarrollar código increíblemente eficaz, y no es exhaustivo. +Referirse a [especificación de idioma](https://chapel-lang.org/docs/latest/language/spec.html)(en) y +a [documentación del módulo](https://chapel-lang.org/docs/latest/)(en) para más detalles. + +Ocasionalmente, vuelva aquí en el [website de Chapel](https://chapel-lang.org) +para ver si se han agregado más temas o se han creado más tutoriales. + +### Lo que le falta a este tutorial: + + * Exposición de los [módulos estándar](https://chapel-lang.org/docs/latest/modules/standard.html) + * Múltiples configuraciones regionales (sistema de memoria distribuida) + * Registros + * Iteradores paralelos + +¡Sus comentarios, preguntas y descubrimientos son importantes para los desarrolladores! +----------------------------------------------------------------------- + +El lenguaje Chapel todavía está en desarrollo activo, por lo que +ocasionalmente hay problemas con el rendimiento y +las características del lenguaje. + +Cuanta más información brinde al equipo de desarrollo de Chapel +sobre los problemas que encuentre o las características que le gustaría ver, +mejor será el lenguaje. + + +Hay varias formas de interactuar con los desarrolladores: ++ [Chat de Gitter](https://gitter.im/chapel-lang/chapel) ++ [lista de emails de Sourceforge](https://sourceforge.net/p/chapel/mailman) + +Si está realmente interesado en el desarrollo del compilador o en contribuir al proyecto, +[consulte el repositorio maestro de GitHub](https://github.com/chapel-lang/chapel). +Está bajo el [La licencia Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Instalar el compilador +----------------------- + +[La documentación oficial de Chapel detalla cómo descargar y compilar el compilador de Chapel.](https://chapel-lang.org/docs/usingchapel/QUICKSTART.html) + +Chapel se puede construir e instalar en su máquina promedio 'nix (y cygwin). +[Descargue la última versión de lanzamiento](https://github.com/chapel-lang/chapel/releases/) +y es tan fácil como + + 1. `tar -xvf chapel-<VERSION>.tar.gz` + 2. `cd chapel-<VERSION>` + 3. `source util/setchplenv.bash # or .sh or .csh or .fish` + 4. `make` + 5. `make check # optional` + +You will need to `source util/setchplenv.EXT` from within the Chapel directory +(`$CHPL_HOME`) every time your terminal starts so it's suggested that you drop +that command in a script that will get executed on startup (like .bashrc). + +Necesitará `source util/setchplenv.EXT` desde el directorio de Chapel (`$CHPL_HOME`) +cada vez que se inicie su terminal, por lo que se sugiere que suelte ese comando +en un script que se ejecutará al inicio (como .bashrc). + +Chapel se instala fácilmente con Brew para OS X + + 1. `brew update` + 2. `brew install chapel` + +Compilando Código +-------------- + +Construye como otros compiladores: + +`chpl myFile.chpl -o myExe` + +Argumentos notables: + + * `--fast`: habilita varias optimizaciones y deshabilita las comprobaciones + de los límites de la matriz Solo debe habilitarse cuando la aplicación es estable. + * `--set <Nombre del Symbolo>=<Valor>`: establece el param de configuracion + `<Nombre del Symbolo>` a `<Valor>`en tiempo de compilación. + * `--main-module <Nombre del módulo>`: use el procedimiento main() que se encuentra en el módulo + `<Nombre del módulo>` como principal del ejecutable. + * `--module-dir <Directorio>`: incluye `<Directorio>` en la ruta de búsqueda del módulo. diff --git a/es-es/clojure-es.html.markdown b/es-es/clojure-es.html.markdown index 150d0bb2..9f25425c 100644 --- a/es-es/clojure-es.html.markdown +++ b/es-es/clojure-es.html.markdown @@ -9,28 +9,30 @@ translators: lang: es-es --- -Clojure es un lenguaje de la familia Lisp desarrollado sobre la Máquina Virtual -de Java. Tiene un énfasis mayor en la [programación funcional](https://es.wikipedia.org/wiki/Programación_funcional) pura -que Common Lisp, pero incluyendo la posibilidad de usar [SMT](https://es.wikipedia.org/wiki/Memoria_transacional) para manipular +Clojure es un lenguaje de la familia Lisp desarrollado para la Máquina Virtual +de Java. Tiene un énfasis mayor en la +[programación funcional](https://es.wikipedia.org/wiki/Programación_funcional) +pura que Common Lisp, pero incluye varias utilidades de +[SMT](https://es.wikipedia.org/wiki/Memoria_transacional) para manipular el estado según se presente. -Esta combinación le permite gestionar la concurrencia de manera muy sencilla -y a menudo automáticamente. +Esta combinación le permite gestionar el procesamiento concurrente de manera +muy sencilla, y a menudo automáticamente. -(Necesitas la versión de Clojure 1.2 o posterior) +(Necesitas la versión de Clojure 1.2 o reciente) ```clojure -; Los comentatios comienzan con punto y coma. +; Los comentarios comienzan con punto y coma. -; Clojure se escribe mediante "forms" (patrones), los cuales son -; listas de objectos entre paréntesis, separados por espacios en blanco. +; Clojure se escribe mediante patrones ("forms"), los cuales son +; listas de cosas entre paréntesis, separados por espacios en blanco. -; El "reader" (lector) de Clojure asume que el primer objeto es una -; función o una macro que se va a llamar, y que el resto son argumentos. +; El lector ("reader") de Clojure asume que la primera cosa es una +; función o una macro a llamar, y el resto son argumentos. -; El primer form en un archivo debe ser ns, para establecer el namespace (espacio de -; nombres) +; La primera llamada en un archivo debe ser ns, para establecer el espacio de +; nombres ("namespace") (ns learnclojure) ; Algunos ejemplos básicos: @@ -51,69 +53,70 @@ y a menudo automáticamente. ; También es necesaria la negación para las operaciones lógicas (not true) ; => false -; Cuando se anidan Los patrones, estos funcionan de la manera esperada +; Los patrones anidados funcionan como esperas (+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2 ; Tipos ;;;;;;;;;;;;; -; Clojure usa los tipos de objetos de Java para booleanos, strings (cadenas de -; caracteres) y números. -; Usa class para saber de qué tipo es. -(class 1); Los enteros son java.lang.Long por defecto -(class 1.); Los numeros en coma flotante son java.lang.Double -(class ""); Los strings van entre comillas dobles, y son -; son java.lang.String -(class false); Los Booleanos son java.lang.Boolean +; Clojure usa los tipos de objetos de Java para booleanos, cadenas de +; caracteres ("strings") y números. +; Usa class para inspeccionarlos. +(class 1); Los números enteros literales son java.lang.Long por defecto +(class 1.); Los números en coma flotante literales son java.lang.Double +(class ""); Los strings siempre van entre comillas dobles, y son + ; java.lang.String +(class false); Los booleanos son java.lang.Boolean (class nil); El valor "null" se escribe nil -; Si quieres crear una lista de datos, precedela con una comilla -; simple para evitar su evaluación +; Si quieres crear una lista literal de datos, usa ' para evitar su evaluación '(+ 1 2) ; => (+ 1 2) -; (que es una abreviatura de (quote (+ 1 2)) ) +; (que es una abreviatura de (quote (+ 1 2))) -; Puedes evaluar una lista precedida por comilla con eval +; Puedes evaluar una lista precedida por una comilla con eval (eval '(+ 1 2)) ; => 3 ; Colecciones & Secuencias ;;;;;;;;;;;;;;;;;;; -; Las Listas están basadas en las listas enlazadas, mientras que los Vectores en -; arrays. +; Las Listas están basadas en listas enlazadas, mientras que los Vectores en +; arreglos. ; ¡Los Vectores y las Listas también son clases de Java! (class [1 2 3]); => clojure.lang.PersistentVector (class '(1 2 3)); => clojure.lang.PersistentList -; Una lista podría ser escrita como (1 2 3), pero debemos ponerle una -; comilla simple delante para evitar que el reader piense que es una función. +; Una lista podría ser escrita como (1 2 3), pero debemos precederle una +; comilla para evitar que el lector ("reader") piense que es una función. ; Además, (list 1 2 3) es lo mismo que '(1 2 3) -; Las "Colecciones" son solo grupos de datos -; Tanto las listas como los vectores son colecciones: +; Las Colecciones ("collections") son solo grupos de datos +; Tanto las Listas como los Vectores son colecciones: (coll? '(1 2 3)) ; => true (coll? [1 2 3]) ; => true -; Las "Secuencias" (seqs) son descripciones abstractas de listas de datos. -; Solo las listas son seqs. +; Las Secuencias ("seqs") son descripciones abstractas de listas de datos. +; Solo las listas son secuencias ("seqs"). (seq? '(1 2 3)) ; => true (seq? [1 2 3]) ; => false -; Una seq solo necesita proporcionar una entrada cuando es accedida. -; Así que, las seqs pueden ser perezosas -- pueden establecer series infinitas: +; Una secuencia solo necesita proporcionar uno de sus elementos cuando es +; accedido. +; Así que, las secuencias pueden ser perezosas -- pueden definir series +; infinitas: (range 4) ; => (0 1 2 3) (range) ; => (0 1 2 3 4 ...) (una serie infinita) (take 4 (range)) ; (0 1 2 3) -; Usa cons para agregar un elemento al inicio de una lista o vector +; Usa cons para agregar un elemento al inicio de una Lista o Vector (cons 4 [1 2 3]) ; => (4 1 2 3) (cons 4 '(1 2 3)) ; => (4 1 2 3) ; conj agregará un elemento a una colección en la forma más eficiente. -; Para listas, se añade al inicio. Para vectores, al final. +; Para Listas, se añade al inicio. Para vectores, al final. (conj [1 2 3] 4) ; => [1 2 3 4] (conj '(1 2 3) 4) ; => (4 1 2 3) -; Usa concat para concatenar listas o vectores +; Usa concat para concatenar Listas o Vectores (concat [1 2] '(3 4)) ; => (1 2 3 4) ; Usa filter y map para actuar sobre colecciones @@ -125,7 +128,7 @@ y a menudo automáticamente. ; = (+ (+ (+ 1 2) 3) 4) ; => 10 -; reduce puede tener un argumento indicando su valor inicial. +; reduce puede tomar un argumento como su valor inicial también (reduce conj [] '(3 2 1)) ; = (conj (conj (conj [] 3) 2) 1) ; => [3 2 1] @@ -137,43 +140,42 @@ y a menudo automáticamente. ; su última expresión (fn [] "Hello World") ; => fn -; (Necesitas rodearlo con paréntesis para invocarla) +; (Necesitas rodearlo con paréntesis para llamarla) ((fn [] "Hello World")) ; => "Hello World" -; Puedes crear una var (variable) mediante def +; Puedes definir una variable ("var") mediante def (def x 1) x ; => 1 -; Asigna una función a una var +; Asignar una función a una variable ("var") (def hello-world (fn [] "Hello World")) (hello-world) ; => "Hello World" -; Puedes defn como atajo para lo anterior +; Puedes usar defn como atajo para lo anterior (defn hello-world [] "Hello World") -; El [] es el vector de argumentos de la función. +; El [] es el Vector de argumentos de la función. (defn hello [name] (str "Hello " name)) (hello "Steve") ; => "Hello Steve" -; Otra abreviatura para crear funciones es: +; Puedes usar esta abreviatura para definir funciones: (def hello2 #(str "Hello " %1)) (hello2 "Fanny") ; => "Hello Fanny" -; Puedes tener funciones multi-variadic: funciones con un numero variable de -; argumentos +; Puedes tener funciones multi-variables ("multi-variadic") también (defn hello3 ([] "Hello World") ([name] (str "Hello " name))) (hello3 "Jake") ; => "Hello Jake" (hello3) ; => "Hello World" -; Las funciones pueden usar argumentos extras dentro de un seq utilizable en la función +; Las funciones pueden empaquetar argumentos extras en una secuencia para ti (defn count-args [& args] (str "You passed " (count args) " args: " args)) (count-args 1 2 3) ; => "You passed 3 args: (1 2 3)" -; Y puedes mezclarlos con el resto de argumentos declarados de la función. +; Puedes combinar los argumentos regulares y los empaquetados (defn hello-count [name & args] (str "Hello " name ", you passed " (count args) " extra args")) (hello-count "Finn" 1 2 3) @@ -183,17 +185,18 @@ x ; => 1 ; Mapas ;;;;;;;;;; -; Mapas de Hash y mapas de arrays comparten una misma interfaz. Los mapas de Hash -; tienen búsquedas más rápidas pero no mantienen el orden de las claves. +; Los Mapas de Hash ("HashMap") y Mapas de Arreglo ("ArrayMap") comparten una +; interfaz. Los Mapas de Hash tienen búsquedas más rápidas pero no mantienen el +; orden de las llaves. (class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap (class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap -; Los mapas de arrays se convertidos en mapas de Hash en la mayoría de -; operaciones si crecen mucho, por lo que no debes preocuparte. +; Los Mapas de Arreglo se convierten automáticamente en Mapas de Hash en la +; mayoría de operaciones si crecen mucho, por lo que no debes preocuparte. -; Los mapas pueden usar cualquier tipo para sus claves, pero generalmente las -; keywords (palabras clave) son lo habitual. -; Las keywords son parecidas a cadenas de caracteres con algunas ventajas de eficiencia +; Los Mapas pueden usar cualquier tipo para sus llaves, pero generalmente las +; Claves ("keywords") son lo habitual. +; Las Claves son como strings con algunas ventajas de eficiencia (class :a) ; => clojure.lang.Keyword (def stringmap {"a" 1, "b" 2, "c" 3}) @@ -205,28 +208,28 @@ keymap ; => {:a 1, :c 3, :b 2} ; Por cierto, las comas son equivalentes a espacios en blanco y no hacen ; nada. -; Recupera un valor de un mapa tratandolo como una función +; Recupera un valor de un Mapa tratándola como una función (stringmap "a") ; => 1 (keymap :a) ; => 1 -; ¡Las keywords pueden ser usadas para recuperar su valor del mapa, también! +; ¡Las Claves pueden ser usadas para recuperar su valor del mapa, también! (:b keymap) ; => 2 ; No lo intentes con strings. ;("a" stringmap) ; => Exception: java.lang.String cannot be cast to clojure.lang.IFn -; Si preguntamos por una clave que no existe nos devuelve nil +; Recuperando una clave no existente nos devuelve nil (stringmap "d") ; => nil -; Usa assoc para añadir nuevas claves a los mapas de Hash +; Usa assoc para añadir nuevas claves a los Mapas de Hash (def newkeymap (assoc keymap :d 4)) newkeymap ; => {:a 1, :b 2, :c 3, :d 4} ; Pero recuerda, ¡los tipos de Clojure son inmutables! keymap ; => {:a 1, :b 2, :c 3} -; Usa dissoc para eliminar llaves +; Usa dissoc para eliminar claves (dissoc keymap :a :b) ; => {:c 3} ; Conjuntos @@ -238,50 +241,86 @@ keymap ; => {:a 1, :b 2, :c 3} ; Añade un elemento con conj (conj #{1 2 3} 4) ; => #{1 2 3 4} -; Elimina elementos con disj +; Elimina uno con disj (disj #{1 2 3} 1) ; => #{2 3} -; Comprueba su existencia usando el conjunto como una función: +; Comprueba su existencia usando al Conjunto como una función: (#{1 2 3} 1) ; => 1 (#{1 2 3} 4) ; => nil -; Hay más funciones en el namespace clojure.sets +; Hay más funciones en el espacio de nombres clojure.sets ; Patrones útiles ;;;;;;;;;;;;;;;;; -; Las construcciones lógicas en clojure son macros, y presentan el mismo aspecto -; que el resto de forms. +; Los operadores lógicos en clojure son solo macros, y presentan el mismo +; aspecto que el resto de patrones. (if false "a" "b") ; => "b" (if false "a") ; => nil -; Usa let para crear un binding (asociación) temporal +; Usa let para definir ("binding") una variable temporal (let [a 1 b 2] (> a b)) ; => false -; Agrupa expresiones mediante do +; Agrupa sentencias mediante do (do (print "Hello") "World") ; => "World" (prints "Hello") -; Las funciones tienen implicita la llamada a do +; Las funciones tienen un do implícito (defn print-and-say-hello [name] (print "Saying hello to " name) (str "Hello " name)) (print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff") -; Y el let también +; Y let también (let [name "Urkel"] (print "Saying hello to " name) (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel") +; Usa las macros de tubería ("threading", "arrow", "pipeline" o "chain") +; (-> y ->>) para expresar la transformación de datos de una manera más clara. + +; La macro Tubería-primero ("Thread-first") (->) inserta en cada patrón el +; resultado de los previos, como el primer argumento (segundo elemento) +(-> + {:a 1 :b 2} + (assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3) + (dissoc :b)) ;=> (dissoc (assoc {:a 1 :b 2} :c 3) :b) + +; Esta expresión podría ser escrita como: +; (dissoc (assoc {:a 1 :b 2} :c 3) :b) +; y evalua a {:a 1 :c 3} + +; La macro Tubería-último ("Thread-last") hace lo mismo, pero inserta el +; resultado de cada línea al *final* de cada patrón. Esto es útil para las +; operaciones de colecciones en particular: +(->> + (range 10) + (map inc) ;=> (map inc (range 10) + (filter odd?) ;=> (filter odd? (map inc (range 10)) + (into [])) ;=> (into [] (filter odd? (map inc (range 10))) + ; Result: [1 3 5 7 9] + +; Cuando estés en una situación donde quieras tener más libertad en donde +; poner el resultado de transformaciones previas de datos en una expresión, +; puedes usar la macro as->. Con ella, puedes asignar un nombre especifico +; a la salida de la transformaciones y usarlo como identificador en tus +; expresiones encadenadas ("chain"). + +(as-> [1 2 3] input + (map inc input);=> You can use last transform's output at the last position + (nth input 2) ;=> and at the second position, in the same expression + (conj [4 5 6] input [8 9 10])) ;=> or in the middle ! + + ; Módulos ;;;;;;;;;;;;;;; ; Usa use para obtener todas las funciones del módulo (use 'clojure.set) -; Ahora podemos usar más operaciones de conjuntos +; Ahora podemos usar más operaciones de Conjuntos (intersection #{1 2 3} #{2 3 4}) ; => #{2 3} (difference #{1 2 3} #{2 3 4}) ; => #{1} @@ -291,19 +330,18 @@ keymap ; => {:a 1, :b 2, :c 3} ; Usa require para importar un módulo (require 'clojure.string) -; Usa / para llamar a las funciones de un módulo +; Usa / para llamar las funciones de un módulo ; Aquí, el módulo es clojure.string y la función es blank? (clojure.string/blank? "") ; => true -; Puedes asignarle una abreviatura a un modulo al importarlo +; Puedes asignarle una sobrenombre a un modulo al importarlo (require '[clojure.string :as str]) (str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst." -; (#"" es una expresión regular) +; (#"" es una expresión regular literal) -; Puedes usar require (y use, pero no lo hagas) desde un espacio de nombre +; Puedes usar require (y use, pero no lo hagas) desde un espacio de nombres ; usando :require, -; No necesitas preceder con comilla simple tus módulos si lo haces de esta -; forma. +; No necesitas preceder con comilla tus módulos si lo haces de esta manera. (ns test (:require [clojure.string :as str] @@ -312,8 +350,8 @@ keymap ; => {:a 1, :b 2, :c 3} ; Java ;;;;;;;;;;;;;;;;; -; Java tiene una enorme librería estándar, por lo que resulta util -; aprender como interactuar con ella. +; Java tiene una enorme y útil librería estándar, por lo que querrás +; aprender como hacer uso de ella. ; Usa import para cargar un módulo de java (import java.util.Date) @@ -326,14 +364,15 @@ keymap ; => {:a 1, :b 2, :c 3} ; Usa el nombre de la clase con un "." al final para crear una nueva instancia (Date.) ; <un objeto Date> -; Usa "." para llamar a métodos o usa el atajo ".método" +; Usa "." para llamar métodos. O, usa el atajo ".método" (. (Date.) getTime) ; <un timestamp> -(.getTime (Date.)) ; exactamente la misma cosa +(.getTime (Date.)) ; exactamente lo mismo. ; Usa / para llamar métodos estáticos. (System/currentTimeMillis) ; <un timestamp> (System siempre está presente) -; Usa doto para hacer frente al uso de clases (mutables) más tolerable +; Usa doto para lidiar con el uso de clases (mutables) de una manera más +; tolerable (import java.util.Calendar) (doto (Calendar/getInstance) (.set 2000 1 1 0 0 0) @@ -342,9 +381,9 @@ keymap ; => {:a 1, :b 2, :c 3} ; STM ;;;;;;;;;;;;;;;;; -; Software Transactional Memory es un mecanismo que usa clojure para gestionar -; el estado persistente. Hay unas cuantas construcciones en clojure que -; hacen uso de este mecanismo. +; La Memoria Transaccional ("Software Transactional Memory" / "STM") es un +; mecanismo que usa clojure para gestionar la persistecia de estado. Hay unas +; cuantas construcciones en clojure que hacen uso de él. ; Un atom es el más sencillo. Se le da un valor inicial (def my-atom (atom {})) @@ -352,14 +391,16 @@ keymap ; => {:a 1, :b 2, :c 3} ; Actualiza un atom con swap! ; swap! toma una función y la llama con el valor actual del atom ; como su primer argumento, y cualquier argumento restante como el segundo -(swap! my-atom assoc :a 1) ; Establece my-atom al resultado de (assoc {} :a 1) -(swap! my-atom assoc :b 2) ; Establece my-atom al resultado de (assoc {:a 1} :b 2) +(swap! my-atom assoc :a 1) ; Establece my-atom al resultado + ; de (assoc {} :a 1) +(swap! my-atom assoc :b 2) ; Establece my-atom al resultado + ; de (assoc {:a 1} :b 2) -; Usa '@' para no referenciar al atom sino para obtener su valor +; Usa '@' para no referenciar al atom y obtener su valor my-atom ;=> Atom<#...> (Regresa el objeto Atom) @my-atom ; => {:a 1 :b 2} -; Un sencillo contador usando un atom sería +; Aquí está un sencillo contador usando un atom (def counter (atom 0)) (defn inc-counter [] (swap! counter inc)) @@ -372,22 +413,25 @@ my-atom ;=> Atom<#...> (Regresa el objeto Atom) @counter ; => 5 -; Otros forms que utilizan STM son refs y agents. +; Otras construcciones de STM son refs y agents. ; Refs: http://clojure.org/refs ; Agents: http://clojure.org/agents +``` + ### Lectura adicional -Ésto queda lejos de ser exhaustivo, pero espero que sea suficiente para que puedas empezar tu camino. +Ésto queda lejos de ser exhaustivo, pero ojalá que sea suficiente para que +puedas empezar tu camino. Clojure.org tiene muchos artículos: -[http://clojure.org/](http://clojure.org/) +[http://clojure.org](http://clojure.org) Clojuredocs.org contiene documentación con ejemplos para la mayoría de funciones principales (pertenecientes al core): -[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) +[http://clojuredocs.org/quickref](http://clojuredocs.org/quickref) 4Clojure es una genial forma de mejorar tus habilidades con clojure/FP: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) -Clojure-doc.org (sí, de verdad) tiene un buen número de artículos con los que iniciarse en Clojure: -[http://clojure-doc.org/](http://clojure-doc.org/) +Clojure-doc.org (sí, de verdad) tiene un buen número de artículos con los que +iniciarse en Clojure: [http://clojure-doc.org](http://clojure-doc.org) diff --git a/es-es/css-es.html b/es-es/css-es.html deleted file mode 100644 index 506a9467..00000000 --- a/es-es/css-es.html +++ /dev/null @@ -1,327 +0,0 @@ ---- -language: css -contributors: - - ["Mohammad Valipour", "https://github.com/mvalipour"] - - ["Marco Scannadinari", "https://github.com/marcoms"] - - ["Geoffrey Liu", "https://github.com/g-liu"] - - ["Connor Shea", "https://github.com/connorshea"] - - ["Deepanshu Utkarsh", "https://github.com/duci9y"] - - ["Brett Taylor", "https://github.com/glutnix"] - - ["Tyler Mumford", "https://tylermumford.com"] -translators: - - ["miky ackerman", "https://github.com/mikyackerman"] -lang: es-es -filename: learncss-es.css ---- - -Paginas web estan contruidas en HTML, lo cual especifica el contenido de una pagina -CSS(Hoja de Estilos en Cascada) es un lenguaje separado el cual especifica -la **apariencia** de una pagina. - -codigo CSS esta hecho de *reglas* estaticas. Cada regla toma uno o mas *selectores* y da *valores* especificos a un numero de *propiedades* visuales. Esas propiedades estan entonces aplicadas a los elementos indicados en una pagina por los selectores - -Esta guia ha sido escrita con CSS 2 en mente, la cual es extendida por una nueva caracterica de CSS 3. - -**NOTA:** Debido a que CSS produce resultados visuales, para aprenderlo, necesitas -Probar todo en un patio de juegos CSS como [dabblet] (http://dabblet.com/). -El objetivo principal de este artículo es la sintaxis y algunos consejos generales. - -## Sintaxis - -```css -/* Los comentarios aparecen dentro de un diagonal-asterisco, justo como esta linea - no hay "comentarios en una linea"; este es el unico estilo de comentario.*/ - - -/* #################### - ## SELECTORS - #################### */ - -/* el selector es usado para apuntar a un elemento de la pagina. */ -selector { property: value; /* more properties...*/ } - -/* -Here is an example element: - -<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' /> -*/ - -/* You can target it using one of its CSS classes */ -.class1 { } - -/* or both classes! */ -.class1.class2 { } - -/* or its name */ -div { } - -/* or its id */ -#anID { } - -/* or using the fact that it has an attribute! */ -[attr] { font-size:smaller; } - -/* or that the attribute has a specific value */ -[attr='value'] { font-size:smaller; } - -/* starts with a value (CSS 3) */ -[attr^='val'] { font-size:smaller; } - -/* or ends with a value (CSS 3) */ -[attr$='ue'] { font-size:smaller; } - -/* or contains a value in a space-separated list */ -[otherAttr~='foo'] { } -[otherAttr~='bar'] { } - -/* or contains a value in a dash-separated list, e.g., "-" (U+002D) */ -[otherAttr|='en'] { font-size:smaller; } - - -/* You can combine different selectors to create a more focused selector. Don't - put spaces between them. */ -div.some-class[attr$='ue'] { } - -/* You can select an element which is a child of another element */ -div.some-parent > .class-name { } - -/* or a descendant of another element. Children are the direct descendants of - their parent element, only one level down the tree. Descendants can be any - level down the tree. */ -div.some-parent .class-name { } - -/* Warning: the same selector without a space has another meaning. - Can you guess what? */ -div.some-parent.class-name { } - -/* You may also select an element based on its adjacent sibling */ -.i-am-just-before + .this-element { } - -/* or any sibling preceding it */ -.i-am-any-element-before ~ .this-element { } - -/* There are some selectors called pseudo classes that can be used to select an - element only when it is in a particular state */ - -/* for example, when the cursor hovers over an element */ -selector:hover { } - -/* or a link has been visited */ -selector:visited { } - -/* or hasn't been visited */ -selected:link { } - -/* or an element is in focus */ -selected:focus { } - -/* any element that is the first child of its parent */ -selector:first-child {} - -/* any element that is the last child of its parent */ -selector:last-child {} - -/* Just like pseudo classes, pseudo elements allow you to style certain parts of - a document */ - -/* matches a virtual first child of the selected element */ -selector::before {} - -/* matches a virtual last child of the selected element */ -selector::after {} - -/* At appropriate places, an asterisk may be used as a wildcard to select every - element */ -* { } /* all elements */ -.parent * { } /* all descendants */ -.parent > * { } /* all children */ - -/* #################### - ## PROPERTIES - #################### */ - -selector { - - /* Units of length can be absolute or relative. */ - - /* Relative units */ - width: 50%; /* percentage of parent element width */ - font-size: 2em; /* multiples of element's original font-size */ - font-size: 2rem; /* or the root element's font-size */ - font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */ - font-size: 2vh; /* or its height */ - font-size: 2vmin; /* whichever of a vh or a vw is smaller */ - font-size: 2vmax; /* or greater */ - - /* Absolute units */ - width: 200px; /* pixels */ - font-size: 20pt; /* points */ - width: 5cm; /* centimeters */ - min-width: 50mm; /* millimeters */ - max-width: 5in; /* inches */ - - /* Colors */ - color: #F6E; /* short hex format */ - color: #FF66EE; /* long hex format */ - color: tomato; /* a named color */ - color: rgb(255, 255, 255); /* as rgb values */ - color: rgb(10%, 20%, 50%); /* as rgb percentages */ - color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */ - color: transparent; /* equivalent to setting the alpha to 0 */ - color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */ - color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */ - - /* Borders */ - border-width:5px; - border-style:solid; - border-color:red; /* similar to how background-color is set */ - border: 5px solid red; /* this is a short hand approach for the same */ - border-radius:20px; /* this is a CSS3 property */ - - /* Images as backgrounds of elements */ - background-image: url(/img-path/img.jpg); /* quotes inside url() optional */ - - /* Fonts */ - font-family: Arial; - /* if the font family name has a space, it must be quoted */ - font-family: "Courier New"; - /* if the first one is not found, the browser uses the next, and so on */ - font-family: "Courier New", Trebuchet, Arial, sans-serif; -} -``` - -## Usage - -Save a CSS stylesheet with the extension `.css`. - -```html -<!-- You need to include the css file in your page's <head>. This is the - recommended method. Refer to http://stackoverflow.com/questions/8284365 --> -<link rel='stylesheet' type='text/css' href='path/to/style.css'> - -<!-- You can also include some CSS inline in your markup. --> -<style> - a { color: purple; } -</style> - -<!-- Or directly set CSS properties on the element. --> -<div style="border: 1px solid red;"> -</div> -``` - -## Precedence or Cascade - -An element may be targeted by multiple selectors and may have a property set on -it in more than once. In these cases, one of the rules takes precedence over -others. Rules with a more specific selector take precedence over a less specific -one, and a rule occurring later in the stylesheet overwrites a previous one -(which also means that if two different linked stylesheets contain rules for an -element and if the rules are of the same specificity, then order of linking -would take precedence and the sheet linked latest would govern styling) . - -This process is called cascading, hence the name Cascading Style Sheets. - -Given the following CSS: - -```css -/* A */ -p.class1[attr='value'] - -/* B */ -p.class1 { } - -/* C */ -p.class2 { } - -/* D */ -p { } - -/* E */ -p { property: value !important; } -``` - -and the following markup: - -```html -<p style='/*F*/ property:value;' class='class1 class2' attr='value'> -``` - -The precedence of style is as follows. Remember, the precedence is for each -**property**, not for the entire block. - -* `E` has the highest precedence because of the keyword `!important`. It is -recommended that you avoid its usage. -* `F` is next, because it is an inline style. -* `A` is next, because it is more "specific" than anything else. It has 3 - specifiers: The name of the element `p`, its class `class1`, an attribute - `attr='value'`. -* `C` is next, even though it has the same specificity as `B`. - This is because it appears after `B`. -* `B` is next. -* `D` is the last one. - -## Media Queries - -CSS Media Queries are a feature in CSS 3 which allows you to specify when certain CSS rules should be applied, such as when printed, or when on a screen with certain dimensions or pixel density. They do not add to the selector's specificity. - -```css -/* A rule that will be used on all devices */ -h1 { - font-size: 2em; - color: white; - background-color: black; -} - -/* change the h1 to use less ink on a printer */ -@media print { - h1 { - color: black; - background-color: white; - } -} - -/* make the font bigger when shown on a screen at least 480px wide */ -@media screen and (min-width: 480px) { - h1 { - font-size: 3em; - font-weight: normal; - } -} -``` - -Media queries can include these features: -`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Most of these features can be prefixed with `min-` or `max-`. - -The `resolution` feature is not supported by older devices, instead use `device-pixel-ratio`. - -Many smartphones and tablets will attempt to render the page as if it were on a desktop unless you provide a `viewport` meta-tag. - -```html -<head> - <meta name="viewport" content="width=device-width; initial-scale=1.0"> -</head> -``` - -## Compatibility - -Most of the features in CSS 2 (and many in CSS 3) are available across all -browsers and devices. But it's always good practice to check before using -a new feature. - -## Resources - -* [CanIUse](http://caniuse.com) (Detailed compatibility info) -* [Dabblet](http://dabblet.com/) (CSS playground) -* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference) -* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference) - -## Further Reading - -* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) -* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/) -* [QuirksMode CSS](http://www.quirksmode.org/css/) -* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) -* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing -* [CSS-Tricks](https://css-tricks.com) - - diff --git a/es-es/css-es.html.markdown b/es-es/css-es.html.markdown index 6395f5fd..506a9467 100644 --- a/es-es/css-es.html.markdown +++ b/es-es/css-es.html.markdown @@ -1,253 +1,327 @@ --- language: css -filename: learncss-es.css contributors: - ["Mohammad Valipour", "https://github.com/mvalipour"] - ["Marco Scannadinari", "https://github.com/marcoms"] + - ["Geoffrey Liu", "https://github.com/g-liu"] + - ["Connor Shea", "https://github.com/connorshea"] + - ["Deepanshu Utkarsh", "https://github.com/duci9y"] + - ["Brett Taylor", "https://github.com/glutnix"] + - ["Tyler Mumford", "https://tylermumford.com"] translators: - - ["Daniel Zendejas","https://github.com/DanielZendejas"] + - ["miky ackerman", "https://github.com/mikyackerman"] lang: es-es +filename: learncss-es.css --- -Tutorial de CSS en español +Paginas web estan contruidas en HTML, lo cual especifica el contenido de una pagina +CSS(Hoja de Estilos en Cascada) es un lenguaje separado el cual especifica +la **apariencia** de una pagina. -En los primeros días de la web no había elementos visuales, todo -era texto plano. Pero después, con el desarrollo de los navegadores, -las páginas con contenido visual empezaron a ser más comunes. -CSS es el lenguaje estándar que existe para separar el contenido -(HTML) y el aspecto visual de las páginas web. +codigo CSS esta hecho de *reglas* estaticas. Cada regla toma uno o mas *selectores* y da *valores* especificos a un numero de *propiedades* visuales. Esas propiedades estan entonces aplicadas a los elementos indicados en una pagina por los selectores -Lo que CSS hace es proveer con una sintaxis que te permite apuntar a distintos -elementos HTML y asignarles diferentes propiedades visuales. +Esta guia ha sido escrita con CSS 2 en mente, la cual es extendida por una nueva caracterica de CSS 3. -CSS, como cualquier otro lenguaje, tiene múltiples versiones. Aquí nos enfocamos -en CSS 2.0. No es la versión más reciente pero sí la más soportada y compatible. +**NOTA:** Debido a que CSS produce resultados visuales, para aprenderlo, necesitas +Probar todo en un patio de juegos CSS como [dabblet] (http://dabblet.com/). +El objetivo principal de este artículo es la sintaxis y algunos consejos generales. -**NOTA:** Como los resultados de CSS son efectos visuales, para aprenderlo, -necesitarás probar todo tipo de cosas en ambientes como -[dabblet](http://dabblet.com/). Este artículo se enfoca, principalmente, en -la sintaxis y consejos generales. +## Sintaxis ```css -/* ¡Los comentarios aparecen dentro de diagonal-asterisco, justo como esta línea! */ +/* Los comentarios aparecen dentro de un diagonal-asterisco, justo como esta linea + no hay "comentarios en una linea"; este es el unico estilo de comentario.*/ + /* #################### - ## SELECTORES - ####################*/ - -/* Generalmente, la sentencia principal en CSS es muy simple. */ -selector { propiedad: valor; /* más propiedades separados por punto y coma...*/ } - -/* El selector es usado para apuntar a (seleccionar) un elemento en la página. + ## SELECTORS + #################### */ -¡Puedes apuntar a todos los elementos en la página con el asterisco! */ -* { color:red; } +/* el selector es usado para apuntar a un elemento de la pagina. */ +selector { property: value; /* more properties...*/ } /* -Dado un elemento como este en la página: +Here is an example element: -<div class='una-clase clase2' id='unaId' attr='valor' /> +<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' /> */ -/* puedes seleccionar el <div> por el nombre de su clase */ -.una-clase { } +/* You can target it using one of its CSS classes */ +.class1 { } -/*¡O por sus dos clases! */ -.una-clase.clase2 { } +/* or both classes! */ +.class1.class2 { } -/* O por el nombre de su elemento */ +/* or its name */ div { } -/* O por su Id */ -#unaId { } +/* or its id */ +#anID { } -/* ¡O por el hecho de que tiene un atributo! */ +/* or using the fact that it has an attribute! */ [attr] { font-size:smaller; } -/* O por el hecho de que el atributo tiene un valor determinado */ -[attr='valor'] { font-size:smaller; } +/* or that the attribute has a specific value */ +[attr='value'] { font-size:smaller; } -/* Empieza con un valor ('val' en este caso)*/ +/* starts with a value (CSS 3) */ [attr^='val'] { font-size:smaller; } -/* O termina con un valor ('or' en este caso) */ -[attr$='or'] { font-size:smaller; } +/* or ends with a value (CSS 3) */ +[attr$='ue'] { font-size:smaller; } + +/* or contains a value in a space-separated list */ +[otherAttr~='foo'] { } +[otherAttr~='bar'] { } + +/* or contains a value in a dash-separated list, e.g., "-" (U+002D) */ +[otherAttr|='en'] { font-size:smaller; } + -/* O incluso contiene un valor ('lo' en este caso) */ -[attr~='lo'] { font-size:smaller; } +/* You can combine different selectors to create a more focused selector. Don't + put spaces between them. */ +div.some-class[attr$='ue'] { } -/*Más importante, puedes combinar estos criterios de búsqueda entre sí. -No debe existir ningún espacio entre estas partes porque hace que el -significado cambie.*/ -div.una-clase[attr$='or'] { } +/* You can select an element which is a child of another element */ +div.some-parent > .class-name { } -/* También puedes seleccionar un elemento HTML basándote en sus padres*/ +/* or a descendant of another element. Children are the direct descendants of + their parent element, only one level down the tree. Descendants can be any + level down the tree. */ +div.some-parent .class-name { } -/* Un elemento que es hijo directo de otro elemento (Seleccionado de la forma que -vimos anteriormente) */ +/* Warning: the same selector without a space has another meaning. + Can you guess what? */ +div.some-parent.class-name { } -div.un-padre > .nombre-clase {} +/* You may also select an element based on its adjacent sibling */ +.i-am-just-before + .this-element { } -/* O cualquiera de sus ancestros en la jerarquía*/ -/* La siguiente sentencia selecciona a cualquier elemento que tenga una clase -"nombre-clase" y sea hijo de un div con clase "un-padre" EN CUALQUIER PROFUNDIDAD*/ -div.un-padre .nombre-clase {} +/* or any sibling preceding it */ +.i-am-any-element-before ~ .this-element { } -/* advertencia: el mismo selector sin espacio tiene otro significado. ¿Puedes -identificar la diferencia?*/ +/* There are some selectors called pseudo classes that can be used to select an + element only when it is in a particular state */ -/* También puedes seleccionar un elemento basado en su hermano inmediato previo*/ -.yo-estoy-antes + .este-elemento { } +/* for example, when the cursor hovers over an element */ +selector:hover { } -/*o cualquier hermano previo */ -.yo-soy-cualquiera-antes ~ .estes-elemento {} +/* or a link has been visited */ +selector:visited { } -/* Existen algunas pseudo-clases que permiten seleccionar un elemento -basado en el comportamiendo de la página (a diferencia de la estructura de -la página) */ +/* or hasn't been visited */ +selected:link { } -/* Por ejemplo, para cuando pasas el mouse por encima de un elemento */ -:hover {} +/* or an element is in focus */ +selected:focus { } -/* o una liga visitada*/ -:visited {} +/* any element that is the first child of its parent */ +selector:first-child {} -/* o una liga no visitada aún*/ -:link {} +/* any element that is the last child of its parent */ +selector:last-child {} -/* o un elemento de un formulario que esté seleccionado */ -:focus {} +/* Just like pseudo classes, pseudo elements allow you to style certain parts of + a document */ +/* matches a virtual first child of the selected element */ +selector::before {} + +/* matches a virtual last child of the selected element */ +selector::after {} + +/* At appropriate places, an asterisk may be used as a wildcard to select every + element */ +* { } /* all elements */ +.parent * { } /* all descendants */ +.parent > * { } /* all children */ /* #################### - ## PROPIEDADES - ####################*/ + ## PROPERTIES + #################### */ selector { - - /* Unidades */ - width: 50%; /* en porcentaje */ - font-size: 2em; /* dos veces el tamaño de la fuente actual */ - width: 200px; /* en pixeles */ - font-size: 20pt; /* en puntos */ - width: 5cm; /* en centimetros */ - width: 50mm; /* en milimetros */ - width: 5in; /* en pulgadas */ - - /* Colores */ - background-color: #F6E; /* en hexadecimal corto */ - background-color: #F262E2; /* en hexadecimal largo */ - background-color: tomato; /* puede ser un color con nombre */ - background-color: rgb(255, 255, 255); /* en rgb */ - background-color: rgb(10%, 20%, 50%); /* en rgb percent */ - background-color: rgba(255, 0, 0, 0.3); /* en rgb semi-transparente (con valor alfa)*/ - - /* Imagenes */ - background-image: url(/ruta-a-la-imagen/imagen.jpg); - - /* Fuentes */ + + /* Units of length can be absolute or relative. */ + + /* Relative units */ + width: 50%; /* percentage of parent element width */ + font-size: 2em; /* multiples of element's original font-size */ + font-size: 2rem; /* or the root element's font-size */ + font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */ + font-size: 2vh; /* or its height */ + font-size: 2vmin; /* whichever of a vh or a vw is smaller */ + font-size: 2vmax; /* or greater */ + + /* Absolute units */ + width: 200px; /* pixels */ + font-size: 20pt; /* points */ + width: 5cm; /* centimeters */ + min-width: 50mm; /* millimeters */ + max-width: 5in; /* inches */ + + /* Colors */ + color: #F6E; /* short hex format */ + color: #FF66EE; /* long hex format */ + color: tomato; /* a named color */ + color: rgb(255, 255, 255); /* as rgb values */ + color: rgb(10%, 20%, 50%); /* as rgb percentages */ + color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */ + color: transparent; /* equivalent to setting the alpha to 0 */ + color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */ + color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */ + + /* Borders */ + border-width:5px; + border-style:solid; + border-color:red; /* similar to how background-color is set */ + border: 5px solid red; /* this is a short hand approach for the same */ + border-radius:20px; /* this is a CSS3 property */ + + /* Images as backgrounds of elements */ + background-image: url(/img-path/img.jpg); /* quotes inside url() optional */ + + /* Fonts */ font-family: Arial; - font-family: "Courier New"; /* si el nombre contiene espacios, debe ir entre comillas */ - font-family: "Courier New", Trebuchet, Arial; /* si la primera fuente no se encontró - entonces se busca la seguna, o la tercera, así recursivamente*/ + /* if the font family name has a space, it must be quoted */ + font-family: "Courier New"; + /* if the first one is not found, the browser uses the next, and so on */ + font-family: "Courier New", Trebuchet, Arial, sans-serif; } - ``` -## Uso +## Usage -Guarda cualquier CSS que quieras en un archivo con extensión `.css`. +Save a CSS stylesheet with the extension `.css`. -```xml -<!-- Necesitas incluir tu archivo CSS en el elemento <head> de tu HTML: --> -<link rel='stylesheet' type='text/css' href='ruta/archivoDeEstilos.css' /> +```html +<!-- You need to include the css file in your page's <head>. This is the + recommended method. Refer to http://stackoverflow.com/questions/8284365 --> +<link rel='stylesheet' type='text/css' href='path/to/style.css'> -<!-- -también puedes incluir CSS dentro del archivo HTML. Esta no es una buena práctica -y debe ser evitada. ---> +<!-- You can also include some CSS inline in your markup. --> <style> - selector { propiedad:valor; } + a { color: purple; } </style> -<!-- -También se pueden aplicar propiedades al elemento directamente. -Esta práctica también debe ser evitada a toda costa ---> -<div style='propiedad:valor;'> +<!-- Or directly set CSS properties on the element. --> +<div style="border: 1px solid red;"> </div> - ``` -## Preferencia y orden +## Precedence or Cascade + +An element may be targeted by multiple selectors and may have a property set on +it in more than once. In these cases, one of the rules takes precedence over +others. Rules with a more specific selector take precedence over a less specific +one, and a rule occurring later in the stylesheet overwrites a previous one +(which also means that if two different linked stylesheets contain rules for an +element and if the rules are of the same specificity, then order of linking +would take precedence and the sheet linked latest would govern styling) . -Como te habrás dado cuenta un elemento puede ser seleccionado por más -de un selector. En este caso alguna de las reglas cobra preferencia -sobre las otras: +This process is called cascading, hence the name Cascading Style Sheets. -Dado el siguiente CSS: +Given the following CSS: ```css -/*A*/ -p.clase1[attr='valor'] +/* A */ +p.class1[attr='value'] -/*B*/ -p.clase1 {} +/* B */ +p.class1 { } -/*C*/ -p.clase2 {} +/* C */ +p.class2 { } -/*D*/ -p {} +/* D */ +p { } -/*E*/ -p { propiedad: valor !important; } +/* E */ +p { property: value !important; } +``` +and the following markup: + +```html +<p style='/*F*/ property:value;' class='class1 class2' attr='value'> ``` -Y el siguiente HTML: +The precedence of style is as follows. Remember, the precedence is for each +**property**, not for the entire block. + +* `E` has the highest precedence because of the keyword `!important`. It is +recommended that you avoid its usage. +* `F` is next, because it is an inline style. +* `A` is next, because it is more "specific" than anything else. It has 3 + specifiers: The name of the element `p`, its class `class1`, an attribute + `attr='value'`. +* `C` is next, even though it has the same specificity as `B`. + This is because it appears after `B`. +* `B` is next. +* `D` is the last one. + +## Media Queries + +CSS Media Queries are a feature in CSS 3 which allows you to specify when certain CSS rules should be applied, such as when printed, or when on a screen with certain dimensions or pixel density. They do not add to the selector's specificity. + +```css +/* A rule that will be used on all devices */ +h1 { + font-size: 2em; + color: white; + background-color: black; +} -```xml -<p style='/*F*/ propiedad:valor;' class='clase1 clase2' attr='valor'> -</p> +/* change the h1 to use less ink on a printer */ +@media print { + h1 { + color: black; + background-color: white; + } +} + +/* make the font bigger when shown on a screen at least 480px wide */ +@media screen and (min-width: 480px) { + h1 { + font-size: 3em; + font-weight: normal; + } +} ``` -El orden respetado es el siguiente: -Recuerda, la preferencia es por cada **property**, no para el bloque completo. +Media queries can include these features: +`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Most of these features can be prefixed with `min-` or `max-`. -* `E` tiene la preferencia más elevada gracias a la palabra `!important`. - Es recomendado evitar esto a menos que sea estrictamente necesario incluirlo. -* `F` le sigue, porque es estilo incrustado directamente en el HTML. -* `A` le sigue, porque es más específico que cualquier otra opción. - más específico = más especificadores. Aquí hay tres especificadores: elemento `p` + - nombre de la clase `clase1` + un atributo `attr='valor'` -* `C` le sigue. Aunque tiene el mismo número de especificadores como `B` - pero aparece después. -* Luego va `B` -* y al final `D`. +The `resolution` feature is not supported by older devices, instead use `device-pixel-ratio`. -## Compatibilidad +Many smartphones and tablets will attempt to render the page as if it were on a desktop unless you provide a `viewport` meta-tag. -La mayoría de las funcionalidades de CSS2 (y gradualmente de CSS3) son compatibles -en todos los navegadores y dispositivos. Pero siempre es vital tener en mente la -compatibilidad y disponibilidad del CSS que uses con respecto a los navegadores -y dispositivos para los que desarrolles. +```html +<head> + <meta name="viewport" content="width=device-width; initial-scale=1.0"> +</head> +``` + +## Compatibility -[QuirksMode CSS](http://www.quirksmode.org/css/) es una excelente referencia para esto. +Most of the features in CSS 2 (and many in CSS 3) are available across all +browsers and devices. But it's always good practice to check before using +a new feature. -## Recursos +## Resources -* Para ejecutar un test de compatibilidad, revisa [CanIUse](http://caniuse.com). -* CSS Playground [Dabblet](http://dabblet.com/). -* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS). -* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/). +* [CanIUse](http://caniuse.com) (Detailed compatibility info) +* [Dabblet](http://dabblet.com/) (CSS playground) +* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference) +* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference) -## Otras lecturas +## Further Reading -* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/). -* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/). -* [QuirksMode CSS](http://www.quirksmode.org/css/). +* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) +* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/) +* [QuirksMode CSS](http://www.quirksmode.org/css/) * [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) -* [SASS](http://sass-lang.com/) y [LESS](http://lesscss.org/) para preprocesamiento CSS. -* [CSS-Tricks](https://css-tricks.com). +* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing +* [CSS-Tricks](https://css-tricks.com) + diff --git a/es-es/docker-es.html.markdown b/es-es/docker-es.html.markdown new file mode 100644 index 00000000..81e3cefe --- /dev/null +++ b/es-es/docker-es.html.markdown @@ -0,0 +1,167 @@ +--- +language: docker +filename: docker-es.bat +contributors: + - ["Ruslan López", "http://javapro.org/"] + - ["Michael Chen", "https://github.com/ML-Chen"] +lang: es-es +--- + +```bat +:: descargar, instalar y ejecutar la imágen del hola mundo +docker run hello-world + +:: Si esta es la primera vez, deberíais de poder ver el mensaje +:: Unable to find image 'hello-world:latest' locally +:: latest: Pulling from library/hello-world +:: 1b930d010525: Pull complete +:: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064 +:: Status: Downloaded newer image for hello-world:latest +:: +:: Hello from Docker! +:: This message shows that your installation appears to be working correctly. +:: +:: To generate this message, Docker took the following steps: +:: 1. The Docker client contacted the Docker daemon. +:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. +:: (amd64) +:: 3. The Docker daemon created a new container from that image which runs the +:: executable that produces the output you are currently reading. +:: 4. The Docker daemon streamed that output to the Docker client, which sent it +:: to your terminal. +:: +:: To try something more ambitious, you can run an Ubuntu container with: +:: $ docker run -it ubuntu bash +:: +:: Share images, automate workflows, and more with a free Docker ID: +:: https://hub.docker.com/ +:: +:: For more examples and ideas, visit: +:: https://docs.docker.com/get-started/ +:: El susodicho mensaje se podría traducir como: +:: +:: Hola desde Docker! +:: Este mensaje muestra que su instalación parece estar funcionando crrectamente. +:: +:: Para generar este mensaje, Docker realizó los siguientes pasos: +:: 1. El cliente de Docker contactó a Docker daemon. +:: 2. El Docker daemon obtubo la imágen "hello-world" desde Docker Hub. +:: (amd64) +:: 3. El Docker daemon creó un nuevo contenedor a partir de esa imagen con la cual ejecuta el +:: ejecutable que produce la salida que estás leyendo. +:: 4. El Docker daemon transmitió dicha salida el cliente Docker, el cual +:: la envió a tu terminal. +:: +:: Para intentar algo más ambicioso, puede correr un contenedor Ubuntu mediante: +:: $ docker run -it ubuntu bash +:: +:: Comparte imágenes, automatice flujos y más con un Docker ID gratuito: +:: https://hub.docker.com/ + +:: ahora veamos las imágenes que se están ejecutando actualmente +docker ps +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES + +:: veamos las imágenes que hemos ejecutado previamente +docker ps -a + +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES +:: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago +:: happy_poincare +:: la parte del nombre se genera automáticamente, así que probablemente sea diferente para vos + +:: eliminemos nuestra imagen previamente generada +docker rm happy_poincare + +:: verifiquemos si realmente fue borrada +docker ps -a +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES + +:: especifiquemos un nombre personalizado para el contenedor +docker run --name test_container hello-world +:: Hello from Docker! +:: This message shows that your installation appears to be working correctly. +:: +:: To generate this message, Docker took the following steps: +:: 1. The Docker client contacted the Docker daemon. +:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. +:: (amd64) +:: 3. The Docker daemon created a new container from that image which runs the +:: executable that produces the output you are currently reading. +:: 4. The Docker daemon streamed that output to the Docker client, which sent it +:: to your terminal. +:: +:: To try something more ambitious, you can run an Ubuntu container with: +:: $ docker run -it ubuntu bash +:: +:: Share images, automate workflows, and more with a free Docker ID: +:: https://hub.docker.com/ +:: +:: For more examples and ideas, visit: +:: https://docs.docker.com/get-started/ + +docker ps -a +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES +:: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago +:: test_container +:: tal como podeis ver el nombre es el que especificamos + +:: obtener los registros de un contenedor nombrado +docker logs test_container +:: Hello from Docker! +:: This message shows that your installation appears to be working correctly. +:: +:: To generate this message, Docker took the following steps: +:: 1. The Docker client contacted the Docker daemon. +:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. +:: (amd64) +:: 3. The Docker daemon created a new container from that image which runs the +:: executable that produces the output you are currently reading. +:: 4. The Docker daemon streamed that output to the Docker client, which sent it +:: to your terminal. +:: +:: To try something more ambitious, you can run an Ubuntu container with: +:: $ docker run -it ubuntu bash +:: +:: Share images, automate workflows, and more with a free Docker ID: +:: https://hub.docker.com/ +:: +:: For more examples and ideas, visit: +:: https://docs.docker.com/get-started/ + +docker rm test_container + +docker run ubuntu +:: Unable to find image 'ubuntu:latest' locally +:: latest: Pulling from library/ubuntu +:: 2746a4a261c9: Pull complete +:: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4 +:: Status: Downloaded newer image for ubuntu:latest + +docker ps -a +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES +:: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago +:: relaxed_nobel + +:: ejecutando un contenedor en modo interactivo +docker run -it ubuntu +:: root@e2cac48323d2:/# uname +:: Linux +:: root@e2cac48323d2:/# exit +:: exit + +docker rm relaxed_nobel + +docker ps -a +:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS +:: NAMES +:: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago +:: nifty_goldwasser + +docker rm nifty_goldwasser +``` diff --git a/es-es/elixir-es.html.markdown b/es-es/elixir-es.html.markdown index 885165a6..37acf6ad 100644 --- a/es-es/elixir-es.html.markdown +++ b/es-es/elixir-es.html.markdown @@ -1,5 +1,5 @@ --- -language: elixir +language: Elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] - ["Dzianis Dashkevich", "https://github.com/dskecse"] @@ -23,10 +23,10 @@ y otras características más. # No hay comentarios multilinea, # pero se pueden apilar varios comentarios. -# Para usar el shell de elixir se usa el comando `iex`. +# Para usar el shell de Elixir se usa el comando `iex`. # Los módulos se compilan con el comando `elixirc`. -# Ambos deberían estar en la ruta si elixir se instaló correctamente. +# Ambos deberían estar en la ruta si Elixir se instaló correctamente. ## --------------------------- ## -- Tipos básicos @@ -55,7 +55,7 @@ elem({1, 2, 3}, 0) #=> 1 head #=> 1 tail #=> [2,3] -# En elixir, solo como Erlang, el `=` denota la coincidencia de patrones y +# En Elixir, solo como Erlang, el `=` denota la coincidencia de patrones y # no una asignación. # # This is how the above example of accessing the head and tail of a list works. @@ -87,7 +87,7 @@ string. <<?a, ?b, ?c>> #=> "abc" [?a, ?b, ?c] #=> 'abc' -# `?a` en elixir devuelve el valor ASCII para el caracter `a` +# `?a` en Elixir devuelve el valor ASCII para el caracter `a` ?a #=> 97 # Para concatenar listas se usa `++`, para binarios `<>` @@ -120,7 +120,7 @@ genders.gillian #=> "female" 5 * 2 #=> 10 10 / 2 #=> 5.0 -# En elixir el operador `/` siempre devuelve un número flotante +# En Elixir el operador `/` siempre devuelve un número flotante # Para hacer la división de número entero se debe usar `div` div(10, 2) #=> 5 @@ -175,7 +175,7 @@ else end # Se acuerda de la coincidencia de patrones? -# Muchas estructuras de control de flujo en elixir confían en ella. +# Muchas estructuras de control de flujo en Elixir confían en ella. # `case` permite comparar un valor con muchos patrones: case {:one, :two} do @@ -305,7 +305,7 @@ Geometry.area({:circle, 3}) #=> 28.25999999999999801048 # Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 -# Debido a la inmutabilidad, la recursión es una gran parte de elixir +# Debido a la inmutabilidad, la recursión es una gran parte de Elixir defmodule Recursion do def sum_list([head | tail], acc) do sum_list(tail, acc + head) @@ -380,7 +380,7 @@ end ## --------------------------- # Elixir confía en el modelo actor para la concurrencia. Todo lo que se necesita para escribir -# programas concurrentes en elixir son tres primitivas: procesos de desove, +# programas concurrentes en Elixir son tres primitivas: procesos de desove, # envío de mensajes y recepción de mensajes. # Para empezar un nuevo proceso se usa la función `spawn`, diff --git a/es-es/factor-es.html.markdown b/es-es/factor-es.html.markdown new file mode 100644 index 00000000..67c60de7 --- /dev/null +++ b/es-es/factor-es.html.markdown @@ -0,0 +1,200 @@ +--- +language: factor +contributors: + - ["hyphz", "http://github.com/hyphz/"] +translators: + - ["Roberto R", "https://github.com/rrodriguze"] +filename: learnfactor-es.factor + +lang: es-es +--- +Factor es un lenguaje moderno basado en la pila, basado en Forth, creado por +Slava Pestov. + +El código de este archivo puede escribirse en Factor, pero no importa +directamente porque el encabezado del vocabulario de importación haria que el +comienzo fuera totalmente confuso. + +```factor +! Esto es un comentario + +! Como Forth, toda la programación se realiza mediante la manipulación de la +! pila. +! La intruducción de un valor literal lo coloca en la pila +5 2 3 56 76 23 65 ! No hay salida pero la pila se imprime en modo interactivo + +! Esos números se agregan a la pila de izquierda a derecha +! .s imprime la pila de forma no destructiva. +.s ! 5 2 3 56 76 23 65 + +! La aritmética funciona manipulando datos en la pila. +5 4 + ! Sem saída + +! `.` muestra el resultado superior de la pila y lo imprime. +. ! 9 + +! Más ejemplos de aritmética: +6 7 * . ! 42 +1360 23 - . ! 1337 +12 12 / . ! 1 +13 2 mod . ! 1 + +99 neg . ! -99 +-99 abs . ! 99 +52 23 max . ! 52 +52 23 min . ! 23 + +! Se proporcionan varias palabras para manipular la pila, conocidas +colectivamente como palabras codificadas. + +3 dup - ! duplica el primer item (1st ahora igual a 2nd): 3 - 3 +2 5 swap / ! intercambia el primero con el segundo elemento: 5 / 2 +4 0 drop 2 / ! elimina el primer item (no imprime en pantalla): 4 / 2 +1 2 3 nip .s ! elimina el segundo item (semejante a drop): 1 3 +1 2 clear .s ! acaba con toda la pila +1 2 3 4 over .s ! duplica el segundo item superior: 1 2 3 4 3 +1 2 3 4 2 pick .s ! duplica el tercer item superior: 1 2 3 4 2 3 + +! Creando Palabras +! La palabra `:` factoriza los conjuntos en modo de compilación hasta que vea +la palabra`;`. +: square ( n -- n ) dup * ; ! Sin salida +5 square . ! 25 + +! Podemos ver lo que las palabra hacen también. +! \ suprime la evaluación de una palabra y coloca su identificador en la pila. +\ square see ! : square ( n -- n ) dup * ; + +! Después del nombre de la palabra para crear, la declaración entre paréntesis +da efecto a la pila. +! Podemos usar los nombres que queramos dentro de la declaración: +: weirdsquare ( camel -- llama ) dup * ; + +! Mientras su recuento coincida con el efecto de pila de palabras: +: doubledup ( a -- b ) dup dup ; ! Error: Stack effect declaration is wrong +: doubledup ( a -- a a a ) dup dup ; ! Ok +: weirddoubledup ( i -- am a fish ) dup dup ; ! Além disso Ok + +! Donde Factor difiere de Forth es en el uso de las citaciones. +! Una citacion es un bloque de código que se coloca en la pila como un valor. +! [ inicia el modo de citación; ] termina. +[ 2 + ] ! La cita que suma dos queda en la pila +4 swap call . ! 6 + +! Y así, palabras de orden superior. TONOS de palabras de orden superior +2 3 [ 2 + ] dip .s ! Tomar valor de la parte superior de la pilar, cotizar, retroceder: 4 3 +3 4 [ + ] keep .s ! Copiar el valor desde la parte superior de la pila, cotizar, enviar copia: 7 4 +1 [ 2 + ] [ 3 + ] bi .s ! Ejecute cada cotización en el valor superior, empuje amabos resultados: 3 4 +4 3 1 [ + ] [ + ] bi .s ! Las citas en un bi pueden extraer valores más profundos de la pila: 4 5 ( 1+3 1+4 ) +1 2 [ 2 + ] bi@ .s ! Citar en primer y segundo valor +2 [ + ] curry ! Inyecta el valor dado al comienzo de la pila: [ 2 + ] se deja en la pila + +! Condicionales +! Cualquier valor es verdadero, excepto el valor interno f. +! no existe un valor interno, pero su uso no es esencial. +! Los condicionales son palabras de orden superior, como con los combinadores +! anteriores + +5 [ "Five is true" . ] when ! Cinco es verdadero +0 [ "Zero is true" . ] when ! Cero es verdadero +f [ "F is true" . ] when ! Sin salida +f [ "F is false" . ] unless ! F es falso +2 [ "Two is true" . ] [ "Two is false" . ] if ! Two es verdadero + +! Por defecto, los condicionales consumen el valor bajo prueba, pero las +! variantes con un +! asterisco se dejan solo si es verdad: + +5 [ . ] when* ! 5 +f [ . ] when* ! Sin salida, pila vacía, se consume porque f es falso + + +! Lazos +! Lo has adivinado... estas son palabras de orden superior también. + +5 [ . ] each-integer ! 0 1 2 3 4 +4 3 2 1 0 5 [ + . ] each-integer ! 0 2 4 6 8 +5 [ "Hello" . ] times ! Hello Hello Hello Hello Hello + +! Here's a list: +{ 2 4 6 8 } ! Goes on the stack as one item + +! Aqui está uma lista: +{ 2 4 6 8 } [ 1 + . ] each ! Exibe 3 5 7 9 +{ 2 4 6 8 } [ 1 + ] map ! Salida { 3 5 7 9 } de la pila + +! Reduzir laços ou criar listas: +{ 1 2 3 4 5 } [ 2 mod 0 = ] filter ! Solo mantenga miembros de la lista para los cuales la cita es verdadera: { 2 4 } +{ 2 4 6 8 } 0 [ + ] reduce . ! Como "fold" en lenguajes funcinales: exibe 20 (0+2+4+6+8) +{ 2 4 6 8 } 0 [ + ] accumulate . . ! Como reducir, pero mantiene los valores intermedios en una lista: { 0 2 6 12 } así que 20 +1 5 [ 2 * dup ] replicate . ! Repite la cita 5 veces y recoge los resultados en una lista: { 2 4 8 16 32 } +1 [ dup 100 < ] [ 2 * dup ] produce ! Repite la segunda cita hasta que la primera devuelva falso y recopile los resultados: { 2 4 8 16 32 64 128 } + +! Si todo lo demás falla, un propósito general a repetir. +1 [ dup 10 < ] [ "Hello" . 1 + ] while ! Escribe "Hello" 10 veces + ! Sí, es dificil de leer + ! Para eso están los bucles variantes + +! Variables +! Normalmente, se espera que los programas de Factor mantengan todos los datos +! en la pila. +! El uso de variables con nombre hace que la refactorización sea más difícil +! (y se llama Factor por una razón) +! Variables globales, si las necesitas: + +SYMBOL: name ! Crea un nombre como palabra de identificación +"Bob" name set-global ! Sin salída +name get-global . ! "Bob" + +! Las variables locales nombradas se consideran una extensión, pero están +! disponibles +! En una cita .. +[| m n ! La cita captura los dos valores principales de la pila en m y n + | m n + ] ! Leerlos + +! Ou em uma palavra.. +:: lword ( -- ) ! Tenga en cuenta los dos puntos dobles para invocar la extensión de variable léxica + 2 :> c ! Declara la variable inmutable c para contener 2 + c . ; ! Imprimirlo + +! En una palabra declarada de esta manera, el lado de entrada de la declaración +! de la pila +! se vuelve significativo y proporciona los valores de las variables en las que +! se capturan los valores de pila +:: double ( a -- result ) a 2 * ; + +! Las variables se declaran mutables al terminar su nombre con su signo de +! exclamación +:: mword2 ( a! -- x y ) ! Capture la parte superior de la pila en la variable mutable a + a ! Empujar a + a 2 * a! ! Multiplique por 2 y almacenar el resultado en a + a ; ! Empujar el nuevo valor de a +5 mword2 ! Pila: 5 10 + +! Listas y Secuencias +! Vimos arriba cómo empujar una lista a la pila + +0 { 1 2 3 4 } nth ! Acceder a un miembro específico de una lista: 1 +10 { 1 2 3 4 } nth ! Error: índice de secuencia fuera de los límites +1 { 1 2 3 4 } ?nth ! Lo mismo que nth si el índice está dentro de los límites: 2 +10 { 1 2 3 4 } ?nth ! Sin errores si está fuera de los límites: f + +{ "at" "the" "beginning" } "Append" prefix ! { "Append" "at" "the" "beginning" } +{ "Append" "at" "the" } "end" suffix ! { "Append" "at" "the" "end" } +"in" 1 { "Insert" "the" "middle" } insert-nth ! { "Insert" "in" "the" "middle" } +"Concat" "enate" append ! "Concatenate" - strings are sequences too +"Concatenate" "Reverse " prepend ! "Reverse Concatenate" +{ "Concatenate " "seq " "of " "seqs" } concat ! "Concatenate seq of seqs" +{ "Connect" "subseqs" "with" "separators" } " " join ! "Connect subseqs with separators" + +! Y si desea obtener meta, las citas son secuencias y se pueden desmontar +0 [ 2 + ] nth ! 2 +1 [ 2 + ] nth ! + +[ 2 + ] \ - suffix ! Quotation [ 2 + - ] + + +``` + +##Listo para más? + +* [Documentación de Factor](http://docs.factorcode.org/content/article-help.home.html) diff --git a/es-es/forth-es.html.markdown b/es-es/forth-es.html.markdown index edc5d38c..61123151 100644 --- a/es-es/forth-es.html.markdown +++ b/es-es/forth-es.html.markdown @@ -13,7 +13,7 @@ Forth fue criado por Charles H. Moore en los 70s. Forth es un lenguaje imperativ Nota: Este articulo enfoca predominantemente en la Gforth implementación de Forth, pero casi todo de lo que esta escrito aquí debe funcionar en otro sitio. -``` +```forth \ Este es un comentario ( Este es un comentario también pero solo esta usado cuando definiendo palabras. ) diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown index 749365d1..c93584d8 100644 --- a/es-es/git-es.html.markdown +++ b/es-es/git-es.html.markdown @@ -410,10 +410,8 @@ $ git rm /directorio/del/archivo/FooBar.c * [SalesForce Chuleta](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf) -* [GitGuys](http://www.gitguys.com/) - * [Git - La guía simple](http://rogerdudler.github.io/git-guide/index.html) * [Pro Git](http://www.git-scm.com/book/en/v2) -* [Una introducción a Git y Github para principiantes (Tutorial)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) +* [Una introducción a Git y GitHub para principiantes (Tutorial)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) diff --git a/es-es/go-es.html.markdown b/es-es/go-es.html.markdown index 78267695..17bf4a22 100644 --- a/es-es/go-es.html.markdown +++ b/es-es/go-es.html.markdown @@ -88,7 +88,7 @@ saltos de línea.` // mismo tipo cadena // Literal no ASCII. Los ficheros fuente de Go son UTF-8. g := 'Σ' // Tipo rune, un alias de int32, alberga un carácter unicode. - f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit. + f := 3.14159 // float64, el estándar IEEE-754 de coma flotante 64-bit. c := 3 + 4i // complex128, representado internamente por dos float64. // Sintaxis var con iniciadores. var u uint = 7 // Sin signo, pero la implementación depende del tamaño @@ -425,7 +425,7 @@ func consultaAlServidor() { ## Más información La raíz de todas las cosas sobre Go es el -[sitio web oficial de Go](http://golang.org/). +[sitio web oficial de Go](https://go.dev/). Allí puedes seguir el tutorial, jugar interactivamente y leer mucho más. La definición del lenguaje es altamente recomendada. Es fácil de leer y @@ -433,17 +433,17 @@ sorprendentemente corta (como la definición del lenguaje Go en estos días). Puedes jugar con el código en el -[parque de diversiones Go](https://play.golang.org/p/ncRC2Zevag). ¡Trata +[parque de diversiones Go](https://go.dev/play/p/ncRC2Zevag). ¡Trata de cambiarlo y ejecutarlo desde tu navegador! Ten en cuenta que puedes -utilizar [https://play.golang.org]( https://play.golang.org) como un +utilizar [https://go.dev/play/]( https://go.dev/play/) como un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) para probar cosas y el código en el navegador, sin ni siquiera instalar Go. En la lista de lecturas para estudiantes de Go está el -[código fuente de la biblioteca estándar](http://golang.org/src/pkg/). +[código fuente de la biblioteca estándar](https://go.dev/src/). Ampliamente documentado, que demuestra lo mejor del legible y comprensible Go, con su característico estilo y modismos. ¡O puedes hacer clic en un -nombre de función en [la documentación](http://golang.org/pkg/) y +nombre de función en [la documentación](https://go.dev/pkg/) y aparecerá el código fuente! Otro gran recurso para aprender Go está en diff --git a/es-es/hq9+-es.html.markdown b/es-es/hq9+-es.html.markdown new file mode 100644 index 00000000..0e1a36e1 --- /dev/null +++ b/es-es/hq9+-es.html.markdown @@ -0,0 +1,44 @@ +--- +language: HQ9+ +filename: hq9+-es.html +contributors: + - ["Alexey Nazaroff", "https://github.com/rogaven"] +translators: + - ["Roberto R", "https://github.com/rrodriguze"] +lang: es-es +--- + +HQ9+ es una parodia de los lenguajes de programación esotéricos y fue creado +por Cliff Biffle. +El lenguaje tiene solo cuatro comandos y no está completo de Turing. + +``` +Solo hay cuatro comandos, representados por los siguientes cuatro caracteres +H: imprime "Hello, world!" +Q: imprime el código fuente del programa (ein Quine) +9: imprime la letra de "99 Bottles of Beer" ++: aumenta el acumulador en uno (el valod del acumulador no se puede leer) +Cualquier otro caracter es ignorado. + +Ok. Escribamos el programa: + HQ + +Resultado: + Hello world! + HQ + +HQ9+ es muy simple, pero te permite hacer cosas en él. Otros lenguajes son muy +difíciles.Por ejemplo, el siguiente programa imprime tres copias de sí mismo en +la pantalla: + QQQ +Esto imprime: + QQQ + QQQ + QQQ +``` + +Y esto es todo. Hay muchos intérpretes para HQ9+. +A continuación encontrarás uno de ellos. + ++ [One of online interpreters](https://almnet.de/esolang/hq9plus.php) ++ [HQ9+ official website](http://cliffle.com/esoterica/hq9plus.html) diff --git a/es-es/hy-es.html.markdown b/es-es/hy-es.html.markdown new file mode 100644 index 00000000..bfad3b6e --- /dev/null +++ b/es-es/hy-es.html.markdown @@ -0,0 +1,176 @@ +--- +language: hy +filename: learnhy-es.hy +contributors: + - ["Abhishek L", "http://twitter.com/abhishekl"] +translators: + - ["Roberto R", "https://github.com/rrodriguze"] +lang: es-es +--- + +Hy es un lenguaje de Lisp escrito sobre Python. Esto es posible convirtiendo +código Hy en un árbol abstracto de Python (ast). Por lo que, esto permite a +Hy llamar a código Pyhton nativo y viceversa. + +Este tutorial funciona para hy >= 0.9.12 + +```clojure +;; Esto es una intrucción muy básica a Hy, como la del siguiente enlace +;; http://try-hy.appspot.com +;; +; Comentarios usando punto y coma, como en otros LISPS + +;; Nociones básicas de expresiones +; Los programas List están hechos de expresiones simbólicas como la siguiente +(some-function args) +; ahora el esencial "Hola Mundo" +(print "hello world") + +;; Tipos de datos simples +; Todos los tipos de datos simples son exactamente semejantes a sus homólogos +; en python +42 ; => 42 +3.14 ; => 3.14 +True ; => True +4+10j ; => (4+10j) un número complejo + +; Vamos a comenzar con un poco de arimética simple +(+ 4 1) ;=> 5 +; el operador es aplicado a todos los argumentos, como en otros lisps +(+ 4 1 2 3) ;=> 10 +(- 2 1) ;=> 1 +(* 4 2) ;=> 8 +(/ 4 1) ;=> 4 +(% 4 2) ;=> 0 o operador módulo +; la exponenciación es representada por el operador ** como python +(** 3 2) ;=> 9 +; las funciones anidadas funcionan como lo esperado +(+ 2 (* 4 2)) ;=> 10 +; también los operadores lógicos igual o no igual se comportan como se espera +(= 5 4) ;=> False +(not (= 5 4)) ;=> True + +;; variables +; las variables se configuran usando SETV, los nombres de las variables pueden +; usar utf-8, excepto for ()[]{}",'`;#| +(setv a 42) +(setv π 3.14159) +(def *foo* 42) +;; otros tipos de datos de almacenamiento +; strings, lists, tuples & dicts +; estos son exactamente los mismos tipos de almacenamiento en python +"hello world" ;=> "hello world" +; las operaciones de cadena funcionan de manera similar en python +(+ "hello " "world") ;=> "hello world" +; Las listas se crean usando [], la indexación comienza en 0 +(setv mylist [1 2 3 4]) +; las tuplas son estructuras de datos inmutables +(setv mytuple (, 1 2)) +; los diccionarios son pares de valor-clave +(setv dict1 {"key1" 42 "key2" 21}) +; :nombre se puede usar para definir palabras clave en Hy que se pueden usar para claves +(setv dict2 {:key1 41 :key2 20}) +; usar 'get' para obtener un elemento en un índice/key +(get mylist 1) ;=> 2 +(get dict1 "key1") ;=> 42 +; Alternativamente, si se usan palabras clave que podrían llamarse directamente +(:key1 dict2) ;=> 41 + +;; funciones y otras estructuras de programa +; las funciones son definidas usando defn, o el último sexp se devuelve por defecto +(defn greet [name] + "A simple greeting" ; un docstring opcional + (print "hello " name)) + +(greet "bilbo") ;=> "hello bilbo" + +; las funciones pueden tener argumentos opcionales, así como argumentos-clave +(defn foolists [arg1 &optional [arg2 2]] + [arg1 arg2]) + +(foolists 3) ;=> [3 2] +(foolists 10 3) ;=> [10 3] + +; las funciones anonimas son creadas usando constructores 'fn' y 'lambda' +; que son similares a 'defn' +(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16] + +;; operaciones de secuencia +; hy tiene algunas utilidades incluidas para operaciones de secuencia, etc. +; recuperar el primer elemento usando 'first' o 'car' +(setv mylist [1 2 3 4]) +(setv mydict {"a" 1 "b" 2}) +(first mylist) ;=> 1 + +; corte listas usando 'slice' +(slice mylist 1 3) ;=> [2 3] + +; obtener elementos de una lista o dict usando 'get' +(get mylist 1) ;=> 2 +(get mydict "b") ;=> 2 +; la lista de indexación comienza a partir de 0, igual que en python +; assoc puede definir elementos clave/índice +(assoc mylist 2 10) ; crear mylist [1 2 10 4] +(assoc mydict "c" 3) ; crear mydict {"a" 1 "b" 2 "c" 3} +; hay muchas otras funciones que hacen que trabajar con secuencias sea +; entretenido + +;; Python interop +;; los import funcionan exactamente como en python +(import datetime) +(import [functools [partial reduce]]) ; importa fun1 e fun2 del module1 +(import [matplotlib.pyplot :as plt]) ; haciendo una importación en foo como en bar +; todos los métodos de python incluídos etc. son accesibles desde hy +; a.foo(arg) is called as (.foo a arg) +(.split (.strip "hello world ")) ;=> ["hello" "world"] + +;; Condicionales +; (if condition (body-if-true) (body-if-false) +(if (= passcode "moria") + (print "welcome") + (print "Speak friend, and Enter!")) + +; anidar múltiples cláusulas 'if else if' con condiciones +(cond + [(= someval 42) + (print "Life, universe and everything else!")] + [(> someval 42) + (print "val too large")] + [(< someval 42) + (print "val too small")]) + +; declaraciones de grupo con 'do', son ejecutadas secuencialmente +; formas como defn tienen un 'do' implícito +(do + (setv someval 10) + (print "someval is set to " someval)) ;=> 10 + +; crear enlaces léxicos con 'let', todas las variables definidas de esta manera +; tienen alcance local +(let [[nemesis {"superman" "lex luther" + "sherlock" "moriarty" + "seinfeld" "newman"}]] + (for [(, h v) (.items nemesis)] + (print (.format "{0}'s nemesis was {1}" h v)))) + +;; clases +; las clases son definidas de la siguiente manera +(defclass Wizard [object] + [[--init-- (fn [self spell] + (setv self.spell spell) ; init the attr magic + None)] + [get-spell (fn [self] + self.spell)]]) + +;; acesse hylang.org +``` + +### Otras lecturas + +Este tutorial apenas es una introducción básica para hy/lisp/python. + +Docs Hy: [http://hy.readthedocs.org](http://hy.readthedocs.org) + +Repo Hy en GitHub: [http://github.com/hylang/hy](http://github.com/hylang/hy) + +Acceso a freenode irc con #hy, hashtag en twitter: #hylang diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown index 31512dc4..050154c7 100644 --- a/es-es/javascript-es.html.markdown +++ b/es-es/javascript-es.html.markdown @@ -1,7 +1,7 @@ --- language: javascript contributors: - - ["Adam Brenecki", "http://adam.brenecki.id.au"] + - ["Leigh Brenecki", "https://leigh.net.au"] - ["Ariel Krakowski", "http://www.learneroo.com"] translators: - ["Daniel Zendejas","https://github.com/DanielZendejas"] @@ -19,8 +19,8 @@ para front-end que Java. Sin embargo, JavaScript no sólo se limita a los navegadores web: Node.js, un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular. ¡La retroalimentación es bienvenida! Puedes encontrarme en: -[@adambrenecki](https://twitter.com/adambrenecki), o -[adam@brenecki.id.au](mailto:adam@brenecki.id.au). +[@ExcitedLeigh](https://twitter.com/ExcitedLeigh), o +[l@leigh.net.au](mailto:l@leigh.net.au). ```js // Los comentarios en JavaScript son los mismos como comentarios en C. diff --git a/es-es/julia-es.html.markdown b/es-es/julia-es.html.markdown index e4181609..355c7f29 100644 --- a/es-es/julia-es.html.markdown +++ b/es-es/julia-es.html.markdown @@ -28,7 +28,7 @@ En Julia los programas están organizados entorno al [despacho múltiple](http:/ * [Buen desempeño](http://julialang.org/benchmarks), comparado al de lenguajes **estáticamente compilados** como C. * [Gestor de paquetes](http://docs.julialang.org/en/release-0.3/stdlib/pkg) integrado. * [Macros tipo Lisp](http://docs.julialang.org/en/release-0.3/manual/metaprogramming/#macros) y otras comodidades para la [meta programación](http://docs.julialang.org/en/release-0.3/manual/metaprogramming). -* Llamar funciones de otros lenguajes, mediante paquetes como: **Python** ([PyCall](https://github.com/stevengj/PyCall.jl)), [Mathematica](http://github.com/one-more-minute/Mathematica.jl), **Java** ([JavaCall](http://github.com/aviks/JavaCall.jl)), **R** ([Rif](http://github.com/lgautier/Rif.jl) y [RCall](http://github.com/JuliaStats/RCall.jl)) y **Matlab** ([MATLAB](http://github.com/JuliaLang/MATLAB.jl)). +* Llamar funciones de otros lenguajes, mediante paquetes como: **Python** ([PyCall](https://github.com/stevengj/PyCall.jl)), [Mathematica](http://github.com/one-more-minute/Mathematica.jl), **Java** ([JavaCall](http://github.com/aviks/JavaCall.jl)), **R** ([Rif](http://github.com/lgautier/Rif.jl) y [RCall](http://github.com/JuliaStats/RCall.jl)) y **MATLAB** ([MATLAB](http://github.com/JuliaLang/MATLAB.jl)). * [Llamar funciones de C y Fortran](http://docs.julialang.org/en/release-0.3/manual/calling-c-and-fortran-code) **directamente**: sin necesidad de usar envoltorios u APIs especiales. * Poderosas características de **línea de comandos** para [gestionar otros procesos](http://docs.julialang.org/en/release-0.3/manual/running-external-programs). * Diseñado para la [computación paralela y distribuida](http://docs.julialang.org/en/release-0.3/manual/parallel-computing) **desde el principio**. diff --git a/es-es/matlab-es.html.markdown b/es-es/matlab-es.html.markdown index 9f1656bb..9290e505 100644 --- a/es-es/matlab-es.html.markdown +++ b/es-es/matlab-es.html.markdown @@ -1,5 +1,5 @@ --- -language: Matlab +language: MATLAB filename: learnmatlab-es.mat contributors: - ["mendozao", "http://github.com/mendozao"] @@ -31,7 +31,7 @@ esto % Dos símbolos de porcentaje denotan el comienzo de una nueva sección de código. % Secciones de código individuales pueden ser ejecutadas moviendo el cursor hacia la sección, % seguida por un clic en el botón de “Ejecutar Sección” -% o usando Ctrl+Shift+Enter (Windows) o Cmd+Shift+Return (OS X) +% o usando Ctrl+Shift+Enter (Windows) o Cmd+Shift+Return (macOS) %% Este es el comienzo de una sección de código % Una forma de usar las secciones es separar un código de inicio costoso que no cambia, como cargar datos @@ -139,7 +139,7 @@ A.d.e = false; % Vectores x = [4 32 53 7 1] -x(2) % ans = 32, los índices en Matlab comienzan 1, no 0 +x(2) % ans = 32, los índices en MATLAB comienzan 1, no 0 x(2:3) % ans = 32 53 x(2:end) % ans = 32 53 7 1 @@ -506,7 +506,7 @@ find(x) % Encuentra todos los elementos distintos de cero de x y devuelve sus í % Clases -% Matlab puede soportar programación orientada a objetos. +% MATLAB puede soportar programación orientada a objetos. % Las clases deben colocarse en un archivo del nombre de la clase con la extensión .m. % Para comenzar, creamos una clase simple para almacenar puntos de referencia de GPS. % Comience WaypointClass.m @@ -528,7 +528,7 @@ classdef WaypointClass % El nombre de la clase. end % Si queremos agregar dos objetos Waypoint juntos sin llamar - % a una función especial, podemos sobrecargar la aritmética de Matlab así: + % a una función especial, podemos sobrecargar la aritmética de MATLAB así: function r = plus(o1,o2) r = WaypointClass([o1.latitude] +[o2.latitude], ... [o1.longitude]+[o2.longitude]); @@ -540,7 +540,7 @@ end % Podemos crear un objeto de la clase usando el constructor a = WaypointClass(45.0, 45.0) -% Las propiedades de clase se comportan exactamente como estructuras de Matlab. +% Las propiedades de clase se comportan exactamente como estructuras de MATLAB. a.latitude = 70.0 a.longitude = 25.0 @@ -551,15 +551,15 @@ ans = multiplyLatBy(a,3) % no necesita ser pasado al método. ans = a.multiplyLatBy(a,1/3) -% Las funciones de Matlab pueden sobrecargarse para manejar objetos. -% En el método anterior, hemos sobrecargado cómo maneja Matlab +% Las funciones de MATLAB pueden sobrecargarse para manejar objetos. +% En el método anterior, hemos sobrecargado cómo maneja MATLAB % la adición de dos objetos Waypoint. b = WaypointClass(15.0, 32.0) c = a + b ``` -## Más sobre Matlab +## Más sobre MATLAB * [The official website (EN)](http://www.mathworks.com/products/matlab/) * [The official MATLAB Answers forum (EN)](http://www.mathworks.com/matlabcentral/answers/) diff --git a/es-es/objective-c-es.html.markdown b/es-es/objective-c-es.html.markdown index 26cd14d9..28733cfb 100644 --- a/es-es/objective-c-es.html.markdown +++ b/es-es/objective-c-es.html.markdown @@ -9,7 +9,7 @@ translators: lang: es-es filename: LearnObjectiveC-es.m --- -Objective C es el lenguaje de programación principal utilizado por Apple para los sistemas operativos OS X y iOS y sus respectivos frameworks, Cocoa y Cocoa Touch. +Objective C es el lenguaje de programación principal utilizado por Apple para los sistemas operativos macOS y iOS y sus respectivos frameworks, Cocoa y Cocoa Touch. Es un lenguaje de programación para propósito general que le agrega al lenguaje de programación C una mensajería estilo "Smalltalk". diff --git a/es-es/pcre-es.html.markdown b/es-es/pcre-es.html.markdown new file mode 100644 index 00000000..279c9a39 --- /dev/null +++ b/es-es/pcre-es.html.markdown @@ -0,0 +1,84 @@ +--- +language: PCRE +filename: pcre-es.txt +contributors: + - ["Sachin Divekar", "http://github.com/ssd532"] +translators: + - ["Roberto R", "https://github.com/rrodriguze"] +lang: es-es +--- + +Una expresión regular (regex o regexp para abreviar) es una cadena especial +utilizada para definir un patrón, por ejemplo, buscar una secuencia de +caracteres; por ejemplo, `/^[a-z]+:/` se puede usar para extraer `http:` +desde la URL `http://github.com/`. + +PCRE (Pearl Compatible Regular Expressions) es una biblioteca para expresiones +muy similar a la Perls, desde ahí el nombre. Se trata de una de las sintaxis +más comunes para escribir expresiones regulares. + +Hay dos tipos de metacaracteres (caracteres con una función especial): + +* Caracteres reconocidos en todas partes excepto corchetes + +``` + \ caracter de escape + ^ buscar al principio de la cadena (o línea, en modo multilínea) + $ busca al final de la cadena (o línea, en modo multilínea) + . cualquier caracter exceptoo las nuevas líneas + [ inicio de clase de caracter + | condiciones alternativas del separador + ( inicio del subpatrón + ) fin del subpatrón + ? cuantificador "0 o 1" + * quantificatore "0 o más" + + quantificatore "1 o más" + { inicio de cuantificador numérico +``` + +* Caracteres reconocidos entre corchetes + +``` + \ caracter de escape + ^ negar la clase si es el primer caracter + - indica una serie de caracteres + [ clase de caracteres POSIX (si sigue la sintaxis POSIX) + ] termina la clase de caracteres +``` + +PCRE también proporciona clases de caracteres predefinidas + +``` + \d cifra decimal + \D cifra NO decimal + \h espacio horizontal vacío + \H espacio horizontal NO vacío + \s espacio + \S NO esoacui + \v espacio vertical vacío + \V espacio vertical NO vacío + \w palabra + \W "NO palabra" +``` + +## Ejemplos + +Usaremos la siguiente cadena para nuestras pruebas: + +``` +66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET /robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1" +``` + +Se trata de una línea de log del servidor web Apache. + +| Regex | Resultado | Comentario | +| :---- | :-------------- | :------ | +| `GET` | GET | Busque exactamente la cadena "GET" (distingue entre mayúsculas y minúsculas) | +| `\d+.\d+.\d+.\d+` | 66.249.64.13 | `\d+` identifica uno o más (cuantificador `+`) números [0-9], `\.` identifica el caracter `.` | +| `(\d+\.){3}\d+` | 66.249.64.13 | `(\d+\.){3}` busca el grupo (`\d+\.`) exactamente 3 veces. | +| `\[.+\]` | [18/Sep/2004:11:07:48 +1000] | `.+` identifica cualquier caracter, excepto las nuevas líneas; `.` indica cualquier carácter | +| `^\S+` | 66.249.64.13 | `^` buscar al inicio de la cadena, `\S+` identifica la primera cadena de caracteres que no sea espacio | +| `\+[0-9]+` | +1000 | `\+` identifica el caracter `+`. `[0-9]` indica una cifra de 0 a 9. La expresión es equivalente a `\+\d+` | + +## Otros recursos +[Regex101](https://regex101.com/) - probador de expresiones regulares diff --git a/es-es/perl-es.html.markdown b/es-es/perl-es.html.markdown index 644182ff..76e9b6e6 100644 --- a/es-es/perl-es.html.markdown +++ b/es-es/perl-es.html.markdown @@ -11,9 +11,9 @@ translators: lang: es-es --- -Perl 5 es un lenguaje de programación altamente capaz, rico en características, con más de 25 años de desarrollo. +Perl es un lenguaje de programación altamente capaz, rico en características, con más de 25 años de desarrollo. -Perl 5 corre en más de 100 plataformas, desde portátiles hasta ordenadores centrales, y es adecuado para realizar desde prototipos rápidos hasta desarrollar proyectos a gran escala. +Perl corre en más de 100 plataformas, desde portátiles hasta ordenadores centrales, y es adecuado para realizar desde prototipos rápidos hasta desarrollar proyectos a gran escala. ```perl # Comentarios de una sola línea con un carácter hash @@ -31,7 +31,7 @@ Perl 5 corre en más de 100 plataformas, desde portátiles hasta ordenadores cen my $animal = "camello"; my $respuesta = 42; -# Los valores escalares pueden ser cadenas de caracteres, números enteros o +# Los valores escalares pueden ser cadenas de caracteres, números enteros o # de punto flotante; Perl automáticamente los convertirá como sea requerido ## Arreglos @@ -52,7 +52,7 @@ my %color_fruta = ( # Los escalares, arreglos y hashes están más documentados en perldata (perldoc perldata) -# Los tipos de datos más complejos se pueden construir utilizando +# Los tipos de datos más complejos se pueden construir utilizando # referencias, las cuales le permiten construir listas y hashes dentro # de listas y hashes @@ -61,7 +61,7 @@ my %color_fruta = ( # Perl tiene la mayoría de las estructuras condicionales y de ciclos más comunes if ( $var ) { ...; -} elsif ( $var eq 'bar' ) { +} elsif ( $var eq 'bar' ) { ...; } else { ...; @@ -98,7 +98,7 @@ foreach (@array) { #### Expresiones regulares -# El soporte de expresiones regulares en Perl es muy amplio y profundo, y +# El soporte de expresiones regulares en Perl es muy amplio y profundo, y # está sujeto a una extensa documentación en perlrequick, perlretut, entre otros. # Sin embargo, resumiendo: @@ -113,7 +113,7 @@ $a =~ s/foo/bar/g; # remplaza TODAS LAS INSTANCIAS de "foo" con "bar" en #### Archivos y E/S -# Puede abrir un archivo para obtener datos o escribirlos utilizando la +# Puede abrir un archivo para obtener datos o escribirlos utilizando la # función "open()" open(my $entrada, "<" "entrada.txt") or die "No es posible abrir entrada.txt: $!"; @@ -122,7 +122,7 @@ open(my $log, ">>", "mi.log") or die "No es posible abrir mi.log: $!"; # Es posible leer desde un gestor de archivo abierto utilizando el operador "<>". # En contexto escalar, leer una sola línea desde el gestor de archivo, y -# en contexto de lista, leer el archivo completo en donde asigna +# en contexto de lista, leer el archivo completo en donde asigna # cada línea a un elemento de la lista my $linea = <$entrada>; diff --git a/es-es/powershell-es.html.markdown b/es-es/powershell-es.html.markdown index 9eb35967..5b12b961 100644 --- a/es-es/powershell-es.html.markdown +++ b/es-es/powershell-es.html.markdown @@ -34,7 +34,7 @@ $PSVersionTable Para obtener ayuda: -``` +```powershell # Si necesita encontrar algún comando Get-Command about_* # tiene por abreviación (o alias): gcm Get-Command -Verb Add # lista todos los comandos que tienen por verbo 'Add' @@ -51,7 +51,7 @@ Update-Help # Actualiza la ayuda (debe ser ejecutado en una consola elevada como Acá inicia el tutorial: -``` +```powershell # Como ya lo notó, los comentarios empiezan con # # Ejemplo de un simple hola mundo: @@ -299,7 +299,7 @@ $Shortcut.Save() Configurando el shell -``` +```powershell # $Profile es la ruta completa para su `Microsoft.PowerShell_profile.ps1` # Todo el código alojado allí será ejecutado cuando se ejecuta una nueva sesión de PS if (-not (Test-Path $Profile)) { diff --git a/es-es/pyqt-es.html.markdown b/es-es/pyqt-es.html.markdown index 6d4fdde7..9a5eab8c 100644 --- a/es-es/pyqt-es.html.markdown +++ b/es-es/pyqt-es.html.markdown @@ -16,7 +16,7 @@ Esta es una adaptación de la introducción a QT con C++ por [Aleksey Kholovchuk ```python import sys from PyQt4 import QtGui - + def window(): # Crear el objeto de la aplicación app = QtGui.QApplication(sys.argv) @@ -44,7 +44,7 @@ if __name__ == '__main__': Para poder hacer uso de las funciones más avanzades en **pyqt** necesitamos agregar elementos adicionales. Aquí mostramos cómo introducir una caja de diálogo popup, útil para permitir al usuario confirmar su decisión o para brindarnos información. -```Python +```python import sys from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -63,7 +63,7 @@ def window(): w.setWindowTitle("PyQt Dialog") w.show() sys.exit(app.exec_()) - + # Esta función debería crear una ventana de diálogo con un botón # que espera a recibir un click y luego sale del programa def showdialog(): diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown index 2b8f498a..0b21e479 100644 --- a/es-es/python-es.html.markdown +++ b/es-es/python-es.html.markdown @@ -1,26 +1,25 @@ --- -language: python +language: Python contributors: - - ["Louie Dinh", "http://ldinh.ca"] + - ["Louie Dinh", "http://pythonpracticeprojects.com"] translators: - - ["Camilo Garrido", "http://www.twitter.com/hirohope"] - - ["Fabio Souto", "http://fabiosouto.me"] + - ["Camilo Garrido", "http://twitter.com/hirohope"] lang: es-es filename: learnpython-es.py --- -Python fue creado por Guido Van Rossum en el principio de los 90. Ahora es uno -de los lenguajes más populares que existen. Me enamoré de Python por su claridad sintáctica. +Python fue creado por Guido Van Rossum en el principio de los 90'. Ahora es uno +de los lenguajes más populares en existencia. Me enamoré de Python por su claridad sintáctica. Es básicamente pseudocódigo ejecutable. ¡Comentarios serán muy apreciados! Pueden contactarme en [@louiedinh](http://twitter.com/louiedinh) o louiedinh [at] [servicio de email de google] -Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser aplicable a Python 2.x. ¡Pronto un recorrido por Python 3! - ```python + # Comentarios de una línea comienzan con una almohadilla (o signo gato) -""" Strings multilínea pueden escribirse - usando tres "'s, y comúnmente son usados + +""" Strings multilinea pueden escribirse + usando tres "'s, y comunmente son usados como comentarios. """ @@ -31,69 +30,49 @@ Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser apl # Tienes números 3 #=> 3 -# Evidentemente puedes realizar operaciones matemáticas -1 + 1 #=> 2 -8 - 1 #=> 7 -10 * 2 #=> 20 -35 / 5 #=> 7 - -# La división es un poco complicada. Es división entera y toma la parte entera -# de los resultados automáticamente. -5 / 2 #=> 2 +# Matemática es lo que esperarías +1 + 1 #=> 2 +8 - 1 #=> 7 +10 * 2 #=> 20 -# Para arreglar la división necesitamos aprender sobre 'floats' -# (números de coma flotante). -2.0 # Esto es un 'float' -11.0 / 4.0 #=> 2.75 ahhh...mucho mejor +# Excepto la división la cual por defecto retorna un número 'float' (número de coma flotante) +35 / 5 # => 7.0 +# Sin embargo también tienes disponible división entera +34 // 5 # => 6 -# Resultado de la división de enteros truncada para positivos y negativos -5 // 3 # => 1 -5.0 // 3.0 # => 1.0 # funciona con números de coma flotante --5 // 3 # => -2 --5.0 // 3.0 # => -2.0 - -# El operador módulo devuelve el resto de una división entre enteros -7 % 3 # => 1 - -# Exponenciación (x elevado a y) -2**4 # => 16 +# Cuando usas un float, los resultados son floats +3 * 2.0 # => 6.0 # Refuerza la precedencia con paréntesis -(1 + 3) * 2 #=> 8 +(1 + 3) * 2 # => 8 -# Operadores booleanos -# Nota: "and" y "or" son sensibles a mayúsculas -True and False #=> False -False or True #=> True -# Podemos usar operadores booleanos con números enteros -0 and 2 #=> 0 --5 or 0 #=> -5 -0 == False #=> True -2 == True #=> False -1 == True #=> True +# Valores 'boolean' (booleanos) son primitivos +True +False # Niega con 'not' -not True #=> False -not False #=> True +not True # => False +not False # => True + # Igualdad es == -1 == 1 #=> True -2 == 1 #=> False +1 == 1 # => True +2 == 1 # => False # Desigualdad es != -1 != 1 #=> False -2 != 1 #=> True +1 != 1 # => False +2 != 1 # => True # Más comparaciones -1 < 10 #=> True -1 > 10 #=> False -2 <= 2 #=> True -2 >= 2 #=> True +1 < 10 # => True +1 > 10 # => False +2 <= 2 # => True +2 >= 2 # => True # ¡Las comparaciones pueden ser concatenadas! -1 < 2 < 3 #=> True -2 < 3 < 2 #=> False +1 < 2 < 3 # => True +2 < 3 < 2 # => False # Strings se crean con " o ' "Esto es un string." @@ -105,40 +84,41 @@ not False #=> True # Un string puede ser tratado como una lista de caracteres "Esto es un string"[0] #=> 'E' -# % pueden ser usados para formatear strings, como esto: -"%s pueden ser %s" % ("strings", "interpolados") +# .format puede ser usaro para darle formato a los strings, así: +"{} pueden ser {}".format("strings", "interpolados") -# Una forma más reciente de formatear strings es el método 'format'. -# Este método es la forma preferida -"{0} pueden ser {1}".format("strings", "formateados") -# Puedes usar palabras clave si no quieres contar. -"{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña") +# Puedes reutilizar los argumentos de formato si estos se repiten. +"{0} sé ligero, {0} sé rápido, {0} brinca sobre la {1}".format("Jack", "vela") #=> "Jack sé ligero, Jack sé rápido, Jack brinca sobre la vela" +# Puedes usar palabras claves si no quieres contar. +"{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña") #=> "Bob quiere comer lasaña" +# También puedes interpolar cadenas usando variables en el contexto +nombre = 'Bob' +comida = 'Lasaña' +f'{nombre} quiere comer {comida}' #=> "Bob quiere comer lasaña" # None es un objeto -None #=> None +None # => None # No uses el símbolo de igualdad `==` para comparar objetos con None -# Usa `is` en lugar de +# Usa `is` en su lugar "etc" is None #=> False None is None #=> True -# El operador 'is' prueba la identidad del objeto. Esto no es -# muy útil cuando se trata de datos primitivos, pero es -# muy útil cuando se trata de objetos. - -# None, 0, y strings/listas vacíos(as) todas se evalúan como False. +# None, 0, y strings/listas/diccionarios/conjuntos vacíos(as) todos se evalúan como False. # Todos los otros valores son True -bool(0) #=> False -bool("") #=> False +bool(0) # => False +bool("") # => False +bool([]) #=> False +bool({}) #=> False +bool(set()) #=> False #################################################### ## 2. Variables y Colecciones #################################################### -# Imprimir es muy fácil -print "Soy Python. ¡Encantado de conocerte!" - +# Python tiene una función para imprimir +print("Soy Python. Encantado de conocerte") # No hay necesidad de declarar las variables antes de asignarlas. una_variable = 5 # La convención es usar guiones_bajos_con_minúsculas @@ -148,19 +128,16 @@ una_variable #=> 5 # Ve Control de Flujo para aprender más sobre el manejo de excepciones. otra_variable # Levanta un error de nombre -# 'if' puede ser usado como una expresión -"yahoo!" if 3 > 2 else 2 #=> "yahoo!" - -# Las listas almacenan secuencias +# Listas almacena secuencias lista = [] # Puedes empezar con una lista prellenada otra_lista = [4, 5, 6] # Añadir cosas al final de una lista con 'append' -lista.append(1) # lista ahora es [1] -lista.append(2) # lista ahora es [1, 2] -lista.append(4) # lista ahora es [1, 2, 4] -lista.append(3) # lista ahora es [1, 2, 4, 3] +lista.append(1) #lista ahora es [1] +lista.append(2) #lista ahora es [1, 2] +lista.append(4) #lista ahora es [1, 2, 4] +lista.append(3) #lista ahora es [1, 2, 4, 3] # Remueve del final de la lista con 'pop' lista.pop() #=> 3 y lista ahora es [1, 2, 4] # Pongámoslo de vuelta @@ -181,6 +158,12 @@ lista[1:3] #=> [2, 4] lista[2:] #=> [4, 3] # Omite el final lista[:3] #=> [1, 2, 4] +# Selecciona cada dos elementos +lista[::2] # =>[1, 4] +# Invierte la lista +lista[::-1] # => [3, 4, 2, 1] +# Usa cualquier combinación de estos para crear trozos avanzados +# lista[inicio:final:pasos] # Remueve elementos arbitrarios de una lista con 'del' del lista[2] # lista ahora es [1, 2, 3] @@ -191,14 +174,14 @@ lista + otra_lista #=> [1, 2, 3, 4, 5, 6] - Nota: lista y otra_lista no se tocan # Concatenar listas con 'extend' lista.extend(otra_lista) # lista ahora es [1, 2, 3, 4, 5, 6] -# Chequea la existencia en una lista con +# Verifica la existencia en una lista con 'in' 1 in lista #=> True -# Examina el tamaño de una lista con 'len' +# Examina el largo de una lista con 'len' len(lista) #=> 6 -# Las tuplas son como las listas, pero son inmutables. +# Tuplas son como listas pero son inmutables. tupla = (1, 2, 3) tupla[0] #=> 1 tupla[0] = 3 # Levanta un error TypeError @@ -217,7 +200,7 @@ d, e, f = 4, 5, 6 e, d = d, e # d ahora es 5 y e ahora es 4 -# Diccionarios almacenan mapeos +# Diccionarios relacionan llaves y valores dicc_vacio = {} # Aquí está un diccionario prellenado dicc_lleno = {"uno": 1, "dos": 2, "tres": 3} @@ -225,16 +208,16 @@ dicc_lleno = {"uno": 1, "dos": 2, "tres": 3} # Busca valores con [] dicc_lleno["uno"] #=> 1 -# Obtén todas las llaves como una lista -dicc_lleno.keys() #=> ["tres", "dos", "uno"] +# Obtén todas las llaves como una lista con 'keys()'. Necesitamos envolver la llamada en 'list()' porque obtenemos un iterable. Hablaremos de eso luego. +list(dicc_lleno.keys()) #=> ["tres", "dos", "uno"] # Nota - El orden de las llaves del diccionario no está garantizada. # Tus resultados podrían no ser los mismos del ejemplo. -# Obtén todos los valores como una lista -dicc_lleno.values() #=> [3, 2, 1] +# Obtén todos los valores como una lista. Nuevamente necesitamos envolverlas en una lista para sacarlas del iterable. +list(dicc_lleno.values()) #=> [3, 2, 1] # Nota - Lo mismo que con las llaves, no se garantiza el orden. -# Chequea la existencia de una llave en el diccionario con 'in' +# Verifica la existencia de una llave en el diccionario con 'in' "uno" in dicc_lleno #=> True 1 in dicc_lleno #=> False @@ -248,19 +231,18 @@ dicc_lleno.get("cuatro") #=> None dicc_lleno.get("uno", 4) #=> 1 dicc_lleno.get("cuatro", 4) #=> 4 -# El método 'setdefault' es una manera segura de añadir nuevos pares -# llave-valor en un diccionario +# El método 'setdefault' inserta en un diccionario solo si la llave no está presente dicc_lleno.setdefault("cinco", 5) #dicc_lleno["cinco"] es puesto con valor 5 dicc_lleno.setdefault("cinco", 6) #dicc_lleno["cinco"] todavía es 5 +# Remueve llaves de un diccionario con 'del' +del dicc_lleno['uno'] # Remueve la llave 'uno' de dicc_lleno + # Sets (conjuntos) almacenan ... bueno, conjuntos conjunto_vacio = set() -# Inicializar un conjunto con montón de valores -un_conjunto = set([1,2,2,3,4]) # un_conjunto ahora es set([1, 2, 3, 4]) - -# Desde Python 2.7, {} puede ser usado para declarar un conjunto -conjunto_lleno = {1, 2, 2, 3, 4} # => {1 2 3 4} +# Inicializar un conjunto con montón de valores. Yeah, se ve un poco como un diccionario. Lo siento. +un_conjunto = {1,2,2,3,4} # un_conjunto ahora es {1, 2, 3, 4} # Añade más valores a un conjunto conjunto_lleno.add(5) # conjunto_lleno ahora es {1, 2, 3, 4, 5} @@ -275,7 +257,7 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6} # Haz diferencia de conjuntos con - {1,2,3,4} - {2,3,5} #=> {1, 4} -# Chequea la existencia en un conjunto con 'in' +# Verifica la existencia en un conjunto con 'in' 2 in conjunto_lleno #=> True 10 in conjunto_lleno #=> False @@ -284,32 +266,30 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6} ## 3. Control de Flujo #################################################### -# Hagamos sólo una variable -una_variable = 5 +# Creemos una variable para experimentar +some_var = 5 -# Aquí está una declaración de un 'if'. ¡La indentación es importante en Python! +# Aquí está una declaración de un 'if'. ¡La indentación es significativa en Python! # imprime "una_variable es menor que 10" if una_variable > 10: - print "una_variable es completamente mas grande que 10." + print("una_variable es completamente mas grande que 10.") elif una_variable < 10: # Este condición 'elif' es opcional. - print "una_variable es mas chica que 10." + print("una_variable es mas chica que 10.") else: # Esto también es opcional. - print "una_variable es de hecho 10." - + print("una_variable es de hecho 10.") """ -For itera sobre listas +For itera sobre iterables (listas, cadenas, diccionarios, tuplas, generadores...) imprime: perro es un mamifero gato es un mamifero raton es un mamifero """ for animal in ["perro", "gato", "raton"]: - # Puedes usar % para interpolar strings formateados - print "%s es un mamifero" % animal + print("{} es un mamifero".format(animal)) """ -`range(número)` retorna una lista de números +`range(número)` retorna un generador de números desde cero hasta el número dado imprime: 0 @@ -318,7 +298,7 @@ imprime: 3 """ for i in range(4): - print i + print(i) """ While itera hasta que una condición no se cumple. @@ -330,18 +310,49 @@ imprime: """ x = 0 while x < 4: - print x + print(x) x += 1 # versión corta de x = x + 1 # Maneja excepciones con un bloque try/except - -# Funciona desde Python 2.6 en adelante: try: # Usa raise para levantar un error raise IndexError("Este es un error de indice") except IndexError as e: pass # Pass no hace nada. Usualmente harias alguna recuperacion aqui. +# Python oferce una abstracción fundamental llamada Iterable. +# Un iterable es un objeto que puede ser tratado como una sequencia. +# El objeto es retornado por la función 'range' es un iterable. + +dicc_lleno = {"uno": 1, "dos": 2, "tres": 3} +nuestro_iterable = dicc_lleno.keys() +print(nuestro_iterable) #=> dict_keys(['uno', 'dos', 'tres']). Este es un objeto que implementa nuestra interfaz Iterable + +# Podemos recorrerla. +for i in nuestro_iterable: + print(i) # Imprime uno, dos, tres + +# Aunque no podemos selecionar un elemento por su índice. +nuestro_iterable[1] # Genera un TypeError + +# Un iterable es un objeto que sabe como crear un iterador. +nuestro_iterator = iter(nuestro_iterable) + +# Nuestro iterador es un objeto que puede recordar el estado mientras lo recorremos. +# Obtenemos el siguiente objeto llamando la función __next__. +nuestro_iterator.__next__() #=> "uno" + +# Mantiene el estado mientras llamamos __next__. +nuestro_iterator.__next__() #=> "dos" +nuestro_iterator.__next__() #=> "tres" + +# Después que el iterador ha retornado todos sus datos, da una excepción StopIterator. +nuestro_iterator.__next__() # Genera StopIteration + +# Puedes obtener todos los elementos de un iterador llamando a list() en el. +list(dicc_lleno.keys()) #=> Retorna ["uno", "dos", "tres"] + + #################################################### ## 4. Funciones @@ -349,7 +360,7 @@ except IndexError as e: # Usa 'def' para crear nuevas funciones def add(x, y): - print "x es %s y y es %s" % (x, y) + print("x es {} y y es {}".format(x, y)) return x + y # Retorna valores con una la declaración return # Llamando funciones con parámetros @@ -358,6 +369,7 @@ add(5, 6) #=> imprime "x es 5 y y es 6" y retorna 11 # Otra forma de llamar funciones es con argumentos de palabras claves add(y=6, x=5) # Argumentos de palabra clave pueden ir en cualquier orden. + # Puedes definir funciones que tomen un número variable de argumentos def varargs(*args): return args @@ -373,10 +385,11 @@ def keyword_args(**kwargs): # Llamémosla para ver que sucede keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"} + # Puedes hacer ambas a la vez si quieres def todos_los_argumentos(*args, **kwargs): - print args - print kwargs + print(args) + print(kwargs) """ todos_los_argumentos(1, 2, a=3, b=4) imprime: (1, 2) @@ -410,23 +423,28 @@ filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7] # Podemos usar listas por comprensión para mapeos y filtros agradables [add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13] [x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7] +# también hay diccionarios +{k:k**2 for k in range(3)} #=> {0: 0, 1: 1, 2: 4} +# y conjuntos por comprensión +{c for c in "la cadena"} #=> {'d', 'l', 'a', 'n', ' ', 'c', 'e'} #################################################### -## 5. Clases +## 5. Classes #################################################### + # Heredamos de object para obtener una clase. class Humano(object): # Un atributo de clase es compartido por todas las instancias de esta clase especie = "H. sapiens" - # Constructor básico, se llama al instanciar la clase. + # Constructor basico def __init__(self, nombre): # Asigna el argumento al atributo nombre de la instancia self.nombre = nombre - # Un método de instancia. Todos los metodos toman self como primer argumento + # Un metodo de instancia. Todos los metodos toman self como primer argumento def decir(self, msg): return "%s: %s" % (self.nombre, msg) @@ -436,7 +454,7 @@ class Humano(object): def get_especie(cls): return cls.especie - # Un metodo estático es llamado sin la clase o instancia como referencia + # Un metodo estatico es llamado sin la clase o instancia como referencia @staticmethod def roncar(): return "*roncar*" @@ -444,10 +462,10 @@ class Humano(object): # Instancia una clase i = Humano(nombre="Ian") -print i.decir("hi") # imprime "Ian: hi" +print(i.decir("hi")) # imprime "Ian: hi" j = Humano("Joel") -print j.decir("hello") #imprime "Joel: hello" +print(j.decir("hello")) #imprime "Joel: hello" # Llama nuestro método de clase i.get_especie() #=> "H. sapiens" @@ -467,12 +485,12 @@ Humano.roncar() #=> "*roncar*" # Puedes importar módulos import math -print math.sqrt(16) #=> 4.0 +print(math.sqrt(16)) #=> 4.0 # Puedes obtener funciones específicas desde un módulo from math import ceil, floor -print ceil(3.7) #=> 4.0 -print floor(3.7) #=> 3.0 +print(ceil(3.7)) #=> 4.0 +print(floor(3.7))#=> 3.0 # Puedes importar todas las funciones de un módulo # Precaución: Esto no es recomendable @@ -495,52 +513,48 @@ dir(math) ## 7. Avanzado #################################################### -# Los generadores permiten evaluación perezosa +# Los generadores te ayudan a hacer un código perezoso (lazy) def duplicar_numeros(iterable): for i in iterable: yield i + i -# Un generador crea valores sobre la marcha -# En vez de generar y devolver todos los valores de una vez, crea un valor -# en cada iteración. En este ejemplo los valores mayores que 15 no serán -# procesados en duplicar_numeros. -# Nota: xrange es un generador que hace lo mismo que range. -# Crear una lista de 1 a 900000000 lleva mucho tiempo y ocupa mucho espacio. -# xrange crea un generador, mientras que range crea toda la lista. -# Añadimos un guión bajo a los nombres de variable que coinciden con palabras -# reservadas de python. -xrange_ = xrange(1, 900000000) - -# duplica todos los números hasta que encuentra un resultado >= 30 -for i in duplicar_numeros(xrange_): - print i +# Un generador crea valores sobre la marcha. +# En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración. +# Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'. +# Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse. +_rango = range(1, 900000000) +# Duplicará todos los números hasta que un resultado >= se encuentre. +for i in duplicar_numeros(_rango): + print(i) if i >= 30: break + # Decoradores -# en este ejemplo pedir rodea a hablar -# Si por_favor es True se cambiará el mensaje. +# en este ejemplo 'pedir' envuelve a 'decir' +# Pedir llamará a 'decir'. Si decir_por_favor es True entonces cambiará el mensaje a retornar from functools import wraps -def pedir(target_function): - @wraps(target_function) +def pedir(_decir): + @wraps(_decir) def wrapper(*args, **kwargs): - msg, por_favor = target_function(*args, **kwargs) - if por_favor: - return "{} {}".format(msg, "¡Por favor! Soy pobre :(") - return msg + mensaje, decir_por_favor = _decir(*args, **kwargs) + if decir_por_favor: + return "{} {}".format(mensaje, "¡Por favor! Soy pobre :(") + return mensaje return wrapper @pedir -def hablar(por_favor=False): - msg = "¿Me puedes comprar una cerveza?" - return msg, por_favor +def decir(decir_por_favor=False): + mensaje = "¿Puedes comprarme una cerveza?" + return mensaje, decir_por_favor + -print hablar() # ¿Me puedes comprar una cerveza? -print hablar(por_favor=True) # ¿Me puedes comprar una cerveza? ¡Por favor! Soy pobre :( +print(decir()) # ¿Puedes comprarme una cerveza? +print(decir(decir_por_favor=True)) # ¿Puedes comprarme una cerveza? ¡Por favor! Soy pobre :() ``` ## ¿Listo para más? @@ -549,9 +563,10 @@ print hablar(por_favor=True) # ¿Me puedes comprar una cerveza? ¡Por favor! So * [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) * [Dive Into Python](http://www.diveintopython.net/) -* [The Official Docs](http://docs.python.org/2.6/) +* [Ideas for Python Projects](http://pythonpracticeprojects.com) +* [The Official Docs](http://docs.python.org/3/) * [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) -* [Python Module of the Week](http://pymotw.com/2/) +* [Python Module of the Week](http://pymotw.com/3/) * [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) ### Encuadernados diff --git a/es-es/python3-es.html.markdown b/es-es/pythonlegacy-es.html.markdown index 3236e73a..0a7304e9 100644 --- a/es-es/python3-es.html.markdown +++ b/es-es/pythonlegacy-es.html.markdown @@ -1,25 +1,26 @@ --- -language: python3 +language: Python 2 (legacy) contributors: - - ["Louie Dinh", "http://pythonpracticeprojects.com"] + - ["Louie Dinh", "http://ldinh.ca"] translators: - - ["Camilo Garrido", "http://twitter.com/hirohope"] + - ["Camilo Garrido", "http://www.twitter.com/hirohope"] + - ["Fabio Souto", "http://fabiosouto.me"] lang: es-es -filename: learnpython3-es.py +filename: learnpythonlegacy-es.py --- -Python fue creado por Guido Van Rossum en el principio de los 90'. Ahora es uno -de los lenguajes más populares en existencia. Me enamoré de Python por su claridad sintáctica. +Python fue creado por Guido Van Rossum en el principio de los 90. Ahora es uno +de los lenguajes más populares que existen. Me enamoré de Python por su claridad sintáctica. Es básicamente pseudocódigo ejecutable. ¡Comentarios serán muy apreciados! Pueden contactarme en [@louiedinh](http://twitter.com/louiedinh) o louiedinh [at] [servicio de email de google] -```python +Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser aplicable a Python 2.x. ¡Pronto un recorrido por Python 3! +```python # Comentarios de una línea comienzan con una almohadilla (o signo gato) - -""" Strings multilinea pueden escribirse - usando tres "'s, y comunmente son usados +""" Strings multilínea pueden escribirse + usando tres "'s, y comúnmente son usados como comentarios. """ @@ -30,49 +31,69 @@ Es básicamente pseudocódigo ejecutable. # Tienes números 3 #=> 3 -# Matemática es lo que esperarías -1 + 1 #=> 2 -8 - 1 #=> 7 -10 * 2 #=> 20 +# Evidentemente puedes realizar operaciones matemáticas +1 + 1 #=> 2 +8 - 1 #=> 7 +10 * 2 #=> 20 +35 / 5 #=> 7 + +# La división es un poco complicada. Es división entera y toma la parte entera +# de los resultados automáticamente. +5 / 2 #=> 2 -# Excepto la división la cual por defecto retorna un número 'float' (número de coma flotante) -35 / 5 # => 7.0 -# Sin embargo también tienes disponible división entera -34 // 5 # => 6 +# Para arreglar la división necesitamos aprender sobre 'floats' +# (números de coma flotante). +2.0 # Esto es un 'float' +11.0 / 4.0 #=> 2.75 ahhh...mucho mejor -# Cuando usas un float, los resultados son floats -3 * 2.0 # => 6.0 +# Resultado de la división de enteros truncada para positivos y negativos +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # funciona con números de coma flotante +-5 // 3 # => -2 +-5.0 // 3.0 # => -2.0 + +# El operador módulo devuelve el resto de una división entre enteros +7 % 3 # => 1 + +# Exponenciación (x elevado a y) +2**4 # => 16 # Refuerza la precedencia con paréntesis -(1 + 3) * 2 # => 8 +(1 + 3) * 2 #=> 8 +# Operadores booleanos +# Nota: "and" y "or" son sensibles a mayúsculas +True and False #=> False +False or True #=> True -# Valores 'boolean' (booleanos) son primitivos -True -False +# Podemos usar operadores booleanos con números enteros +0 and 2 #=> 0 +-5 or 0 #=> -5 +0 == False #=> True +2 == True #=> False +1 == True #=> True # Niega con 'not' -not True # => False -not False # => True - +not True #=> False +not False #=> True # Igualdad es == -1 == 1 # => True -2 == 1 # => False +1 == 1 #=> True +2 == 1 #=> False # Desigualdad es != -1 != 1 # => False -2 != 1 # => True +1 != 1 #=> False +2 != 1 #=> True # Más comparaciones -1 < 10 # => True -1 > 10 # => False -2 <= 2 # => True -2 >= 2 # => True +1 < 10 #=> True +1 > 10 #=> False +2 <= 2 #=> True +2 >= 2 #=> True # ¡Las comparaciones pueden ser concatenadas! -1 < 2 < 3 # => True -2 < 3 < 2 # => False +1 < 2 < 3 #=> True +2 < 3 < 2 #=> False # Strings se crean con " o ' "Esto es un string." @@ -84,41 +105,40 @@ not False # => True # Un string puede ser tratado como una lista de caracteres "Esto es un string"[0] #=> 'E' -# .format puede ser usaro para darle formato a los strings, así: -"{} pueden ser {}".format("strings", "interpolados") +# % pueden ser usados para formatear strings, como esto: +"%s pueden ser %s" % ("strings", "interpolados") -# Puedes reutilizar los argumentos de formato si estos se repiten. -"{0} sé ligero, {0} sé rápido, {0} brinca sobre la {1}".format("Jack", "vela") #=> "Jack sé ligero, Jack sé rápido, Jack brinca sobre la vela" -# Puedes usar palabras claves si no quieres contar. -"{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña") #=> "Bob quiere comer lasaña" -# También puedes interpolar cadenas usando variables en el contexto -nombre = 'Bob' -comida = 'Lasaña' -f'{nombre} quiere comer {comida}' #=> "Bob quiere comer lasaña" +# Una forma más reciente de formatear strings es el método 'format'. +# Este método es la forma preferida +"{0} pueden ser {1}".format("strings", "formateados") +# Puedes usar palabras clave si no quieres contar. +"{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña") # None es un objeto -None # => None +None #=> None # No uses el símbolo de igualdad `==` para comparar objetos con None -# Usa `is` en su lugar +# Usa `is` en lugar de "etc" is None #=> False None is None #=> True -# None, 0, y strings/listas/diccionarios/conjuntos vacíos(as) todos se evalúan como False. +# El operador 'is' prueba la identidad del objeto. Esto no es +# muy útil cuando se trata de datos primitivos, pero es +# muy útil cuando se trata de objetos. + +# None, 0, y strings/listas vacíos(as) todas se evalúan como False. # Todos los otros valores son True -bool(0) # => False -bool("") # => False -bool([]) #=> False -bool({}) #=> False -bool(set()) #=> False +bool(0) #=> False +bool("") #=> False #################################################### ## 2. Variables y Colecciones #################################################### -# Python tiene una función para imprimir -print("Soy Python. Encantado de conocerte") +# Imprimir es muy fácil +print "Soy Python. ¡Encantado de conocerte!" + # No hay necesidad de declarar las variables antes de asignarlas. una_variable = 5 # La convención es usar guiones_bajos_con_minúsculas @@ -128,16 +148,19 @@ una_variable #=> 5 # Ve Control de Flujo para aprender más sobre el manejo de excepciones. otra_variable # Levanta un error de nombre -# Listas almacena secuencias +# 'if' puede ser usado como una expresión +"yahoo!" if 3 > 2 else 2 #=> "yahoo!" + +# Las listas almacenan secuencias lista = [] # Puedes empezar con una lista prellenada otra_lista = [4, 5, 6] # Añadir cosas al final de una lista con 'append' -lista.append(1) #lista ahora es [1] -lista.append(2) #lista ahora es [1, 2] -lista.append(4) #lista ahora es [1, 2, 4] -lista.append(3) #lista ahora es [1, 2, 4, 3] +lista.append(1) # lista ahora es [1] +lista.append(2) # lista ahora es [1, 2] +lista.append(4) # lista ahora es [1, 2, 4] +lista.append(3) # lista ahora es [1, 2, 4, 3] # Remueve del final de la lista con 'pop' lista.pop() #=> 3 y lista ahora es [1, 2, 4] # Pongámoslo de vuelta @@ -158,12 +181,6 @@ lista[1:3] #=> [2, 4] lista[2:] #=> [4, 3] # Omite el final lista[:3] #=> [1, 2, 4] -# Selecciona cada dos elementos -lista[::2] # =>[1, 4] -# Invierte la lista -lista[::-1] # => [3, 4, 2, 1] -# Usa cualquier combinación de estos para crear trozos avanzados -# lista[inicio:final:pasos] # Remueve elementos arbitrarios de una lista con 'del' del lista[2] # lista ahora es [1, 2, 3] @@ -174,14 +191,14 @@ lista + otra_lista #=> [1, 2, 3, 4, 5, 6] - Nota: lista y otra_lista no se tocan # Concatenar listas con 'extend' lista.extend(otra_lista) # lista ahora es [1, 2, 3, 4, 5, 6] -# Verifica la existencia en una lista con 'in' +# Chequea la existencia en una lista con 1 in lista #=> True -# Examina el largo de una lista con 'len' +# Examina el tamaño de una lista con 'len' len(lista) #=> 6 -# Tuplas son como listas pero son inmutables. +# Las tuplas son como las listas, pero son inmutables. tupla = (1, 2, 3) tupla[0] #=> 1 tupla[0] = 3 # Levanta un error TypeError @@ -200,7 +217,7 @@ d, e, f = 4, 5, 6 e, d = d, e # d ahora es 5 y e ahora es 4 -# Diccionarios relacionan llaves y valores +# Diccionarios almacenan mapeos dicc_vacio = {} # Aquí está un diccionario prellenado dicc_lleno = {"uno": 1, "dos": 2, "tres": 3} @@ -208,16 +225,16 @@ dicc_lleno = {"uno": 1, "dos": 2, "tres": 3} # Busca valores con [] dicc_lleno["uno"] #=> 1 -# Obtén todas las llaves como una lista con 'keys()'. Necesitamos envolver la llamada en 'list()' porque obtenemos un iterable. Hablaremos de eso luego. -list(dicc_lleno.keys()) #=> ["tres", "dos", "uno"] +# Obtén todas las llaves como una lista +dicc_lleno.keys() #=> ["tres", "dos", "uno"] # Nota - El orden de las llaves del diccionario no está garantizada. # Tus resultados podrían no ser los mismos del ejemplo. -# Obtén todos los valores como una lista. Nuevamente necesitamos envolverlas en una lista para sacarlas del iterable. -list(dicc_lleno.values()) #=> [3, 2, 1] +# Obtén todos los valores como una lista +dicc_lleno.values() #=> [3, 2, 1] # Nota - Lo mismo que con las llaves, no se garantiza el orden. -# Verifica la existencia de una llave en el diccionario con 'in' +# Chequea la existencia de una llave en el diccionario con 'in' "uno" in dicc_lleno #=> True 1 in dicc_lleno #=> False @@ -231,18 +248,19 @@ dicc_lleno.get("cuatro") #=> None dicc_lleno.get("uno", 4) #=> 1 dicc_lleno.get("cuatro", 4) #=> 4 -# El método 'setdefault' inserta en un diccionario solo si la llave no está presente +# El método 'setdefault' es una manera segura de añadir nuevos pares +# llave-valor en un diccionario dicc_lleno.setdefault("cinco", 5) #dicc_lleno["cinco"] es puesto con valor 5 dicc_lleno.setdefault("cinco", 6) #dicc_lleno["cinco"] todavía es 5 -# Remueve llaves de un diccionario con 'del' -del dicc_lleno['uno'] # Remueve la llave 'uno' de dicc_lleno - # Sets (conjuntos) almacenan ... bueno, conjuntos conjunto_vacio = set() -# Inicializar un conjunto con montón de valores. Yeah, se ve un poco como un diccionario. Lo siento. -un_conjunto = {1,2,2,3,4} # un_conjunto ahora es {1, 2, 3, 4} +# Inicializar un conjunto con montón de valores +un_conjunto = set([1,2,2,3,4]) # un_conjunto ahora es set([1, 2, 3, 4]) + +# Desde Python 2.7, {} puede ser usado para declarar un conjunto +conjunto_lleno = {1, 2, 2, 3, 4} # => {1 2 3 4} # Añade más valores a un conjunto conjunto_lleno.add(5) # conjunto_lleno ahora es {1, 2, 3, 4, 5} @@ -257,7 +275,7 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6} # Haz diferencia de conjuntos con - {1,2,3,4} - {2,3,5} #=> {1, 4} -# Verifica la existencia en un conjunto con 'in' +# Chequea la existencia en un conjunto con 'in' 2 in conjunto_lleno #=> True 10 in conjunto_lleno #=> False @@ -266,30 +284,32 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6} ## 3. Control de Flujo #################################################### -# Creemos una variable para experimentar -some_var = 5 +# Hagamos sólo una variable +una_variable = 5 -# Aquí está una declaración de un 'if'. ¡La indentación es significativa en Python! +# Aquí está una declaración de un 'if'. ¡La indentación es importante en Python! # imprime "una_variable es menor que 10" if una_variable > 10: - print("una_variable es completamente mas grande que 10.") + print "una_variable es completamente mas grande que 10." elif una_variable < 10: # Este condición 'elif' es opcional. - print("una_variable es mas chica que 10.") + print "una_variable es mas chica que 10." else: # Esto también es opcional. - print("una_variable es de hecho 10.") + print "una_variable es de hecho 10." + """ -For itera sobre iterables (listas, cadenas, diccionarios, tuplas, generadores...) +For itera sobre listas imprime: perro es un mamifero gato es un mamifero raton es un mamifero """ for animal in ["perro", "gato", "raton"]: - print("{} es un mamifero".format(animal)) + # Puedes usar % para interpolar strings formateados + print "%s es un mamifero" % animal """ -`range(número)` retorna un generador de números +`range(número)` retorna una lista de números desde cero hasta el número dado imprime: 0 @@ -298,7 +318,7 @@ imprime: 3 """ for i in range(4): - print(i) + print i """ While itera hasta que una condición no se cumple. @@ -310,49 +330,18 @@ imprime: """ x = 0 while x < 4: - print(x) + print x x += 1 # versión corta de x = x + 1 # Maneja excepciones con un bloque try/except + +# Funciona desde Python 2.6 en adelante: try: # Usa raise para levantar un error raise IndexError("Este es un error de indice") except IndexError as e: pass # Pass no hace nada. Usualmente harias alguna recuperacion aqui. -# Python oferce una abstracción fundamental llamada Iterable. -# Un iterable es un objeto que puede ser tratado como una sequencia. -# El objeto es retornado por la función 'range' es un iterable. - -dicc_lleno = {"uno": 1, "dos": 2, "tres": 3} -nuestro_iterable = dicc_lleno.keys() -print(nuestro_iterable) #=> dict_keys(['uno', 'dos', 'tres']). Este es un objeto que implementa nuestra interfaz Iterable - -Podemos recorrerla. -for i in nuestro_iterable: - print(i) # Imprime uno, dos, tres - -# Aunque no podemos selecionar un elemento por su índice. -nuestro_iterable[1] # Genera un TypeError - -# Un iterable es un objeto que sabe como crear un iterador. -nuestro_iterator = iter(nuestro_iterable) - -# Nuestro iterador es un objeto que puede recordar el estado mientras lo recorremos. -# Obtenemos el siguiente objeto llamando la función __next__. -nuestro_iterator.__next__() #=> "uno" - -# Mantiene el estado mientras llamamos __next__. -nuestro_iterator.__next__() #=> "dos" -nuestro_iterator.__next__() #=> "tres" - -# Después que el iterador ha retornado todos sus datos, da una excepción StopIterator. -nuestro_iterator.__next__() # Genera StopIteration - -# Puedes obtener todos los elementos de un iterador llamando a list() en el. -list(dicc_lleno.keys()) #=> Retorna ["uno", "dos", "tres"] - - #################################################### ## 4. Funciones @@ -360,7 +349,7 @@ list(dicc_lleno.keys()) #=> Retorna ["uno", "dos", "tres"] # Usa 'def' para crear nuevas funciones def add(x, y): - print("x es {} y y es {}".format(x, y)) + print "x es %s y y es %s" % (x, y) return x + y # Retorna valores con una la declaración return # Llamando funciones con parámetros @@ -369,7 +358,6 @@ add(5, 6) #=> imprime "x es 5 y y es 6" y retorna 11 # Otra forma de llamar funciones es con argumentos de palabras claves add(y=6, x=5) # Argumentos de palabra clave pueden ir en cualquier orden. - # Puedes definir funciones que tomen un número variable de argumentos def varargs(*args): return args @@ -385,7 +373,6 @@ def keyword_args(**kwargs): # Llamémosla para ver que sucede keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"} - # Puedes hacer ambas a la vez si quieres def todos_los_argumentos(*args, **kwargs): print args @@ -423,28 +410,23 @@ filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7] # Podemos usar listas por comprensión para mapeos y filtros agradables [add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13] [x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7] -# también hay diccionarios -{k:k**2 for k in range(3)} #=> {0: 0, 1: 1, 2: 4} -# y conjuntos por comprensión -{c for c in "la cadena"} #=> {'d', 'l', 'a', 'n', ' ', 'c', 'e'} #################################################### -## 5. Classes +## 5. Clases #################################################### - # Heredamos de object para obtener una clase. class Humano(object): # Un atributo de clase es compartido por todas las instancias de esta clase especie = "H. sapiens" - # Constructor basico + # Constructor básico, se llama al instanciar la clase. def __init__(self, nombre): # Asigna el argumento al atributo nombre de la instancia self.nombre = nombre - # Un metodo de instancia. Todos los metodos toman self como primer argumento + # Un método de instancia. Todos los metodos toman self como primer argumento def decir(self, msg): return "%s: %s" % (self.nombre, msg) @@ -454,7 +436,7 @@ class Humano(object): def get_especie(cls): return cls.especie - # Un metodo estatico es llamado sin la clase o instancia como referencia + # Un metodo estático es llamado sin la clase o instancia como referencia @staticmethod def roncar(): return "*roncar*" @@ -485,12 +467,12 @@ Humano.roncar() #=> "*roncar*" # Puedes importar módulos import math -print(math.sqrt(16)) #=> 4.0 +print math.sqrt(16) #=> 4.0 # Puedes obtener funciones específicas desde un módulo from math import ceil, floor -print(ceil(3.7)) #=> 4.0 -print(floor(3.7))#=> 3.0 +print ceil(3.7) #=> 4.0 +print floor(3.7) #=> 3.0 # Puedes importar todas las funciones de un módulo # Precaución: Esto no es recomendable @@ -513,48 +495,52 @@ dir(math) ## 7. Avanzado #################################################### -# Los generadores te ayudan a hacer un código perezoso (lazy) +# Los generadores permiten evaluación perezosa def duplicar_numeros(iterable): for i in iterable: yield i + i -# Un generador crea valores sobre la marcha. -# En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración. -# Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'. -# Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse. -_rango = range(1, 900000000) -# Duplicará todos los números hasta que un resultado >= se encuentre. -for i in duplicar_numeros(_rango): - print(i) +# Un generador crea valores sobre la marcha +# En vez de generar y devolver todos los valores de una vez, crea un valor +# en cada iteración. En este ejemplo los valores mayores que 15 no serán +# procesados en duplicar_numeros. +# Nota: xrange es un generador que hace lo mismo que range. +# Crear una lista de 1 a 900000000 lleva mucho tiempo y ocupa mucho espacio. +# xrange crea un generador, mientras que range crea toda la lista. +# Añadimos un guión bajo a los nombres de variable que coinciden con palabras +# reservadas de python. +xrange_ = xrange(1, 900000000) + +# duplica todos los números hasta que encuentra un resultado >= 30 +for i in duplicar_numeros(xrange_): + print i if i >= 30: break - # Decoradores -# en este ejemplo 'pedir' envuelve a 'decir' -# Pedir llamará a 'decir'. Si decir_por_favor es True entonces cambiará el mensaje a retornar +# en este ejemplo pedir rodea a hablar +# Si por_favor es True se cambiará el mensaje. from functools import wraps -def pedir(_decir): - @wraps(_decir) +def pedir(target_function): + @wraps(target_function) def wrapper(*args, **kwargs): - mensaje, decir_por_favor = _decir(*args, **kwargs) - if decir_por_favor: - return "{} {}".format(mensaje, "¡Por favor! Soy pobre :(") - return mensaje + msg, por_favor = target_function(*args, **kwargs) + if por_favor: + return "{} {}".format(msg, "¡Por favor! Soy pobre :(") + return msg return wrapper @pedir -def say(decir_por_favor=False): - mensaje = "¿Puedes comprarme una cerveza?" - return mensaje, decir_por_favor - +def hablar(por_favor=False): + msg = "¿Me puedes comprar una cerveza?" + return msg, por_favor -print(decir()) # ¿Puedes comprarme una cerveza? -print(decir(decir_por_favor=True)) # ¿Puedes comprarme una cerveza? ¡Por favor! Soy pobre :() +print hablar() # ¿Me puedes comprar una cerveza? +print hablar(por_favor=True) # ¿Me puedes comprar una cerveza? ¡Por favor! Soy pobre :( ``` ## ¿Listo para más? @@ -563,10 +549,9 @@ print(decir(decir_por_favor=True)) # ¿Puedes comprarme una cerveza? ¡Por favo * [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) * [Dive Into Python](http://www.diveintopython.net/) -* [Ideas for Python Projects](http://pythonpracticeprojects.com) -* [The Official Docs](http://docs.python.org/3/) +* [The Official Docs](http://docs.python.org/2.6/) * [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) -* [Python Module of the Week](http://pymotw.com/3/) +* [Python Module of the Week](http://pymotw.com/2/) * [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) ### Encuadernados diff --git a/es-es/r-es.html.markdown b/es-es/r-es.html.markdown index 2b710b27..850952fa 100644 --- a/es-es/r-es.html.markdown +++ b/es-es/r-es.html.markdown @@ -16,7 +16,7 @@ LaTeX. ```r -# Los comentariso inician con símbolos numéricos. +# Los comentarios inician con símbolos numéricos. # No puedes hacer comentarios de múltiples líneas # pero puedes agrupar múltiples comentarios de esta manera. diff --git a/es-es/perl6-es.html.markdown b/es-es/raku-es.html.markdown index bf3ae65e..09341056 100644 --- a/es-es/perl6-es.html.markdown +++ b/es-es/raku-es.html.markdown @@ -1,8 +1,8 @@ --- -name: perl6 +name: Raku category: language -language: perl6 -filename: perl6-es.p6 +language: Raku +filename: learnraku-es.raku contributors: - ["vendethiel", "http://github.com/vendethiel"] - ["Samantha McVey", "https://cry.nu"] @@ -11,10 +11,10 @@ translators: lang: es-es --- -Perl 6 es un lenguaje de programación altamente capaz y con características +Raku es un lenguaje de programación altamente capaz y con características abundantes para hacerlo el lenguage ideal por los próximos 100 años. -El compilador primario de Perl 6 se llama [Rakudo](http://rakudo.org), el cual +El compilador primario de Raku se llama [Rakudo](http://rakudo.org), el cual se ejecuta en JVM y en [MoarVM](http://moarvm.com). Meta-nota: dos signos de números (##) son usados para indicar párrafos, @@ -26,7 +26,7 @@ mientras que un solo signo de número (#) indica notas. # Un comentario de una sola línea comienza con un signo de número #`( - Comentarios multilíneas usan #` y signos de encerradura tales + Comentarios multilíneas usan #` y signos de encerradura tales como (), [], {}, 「」, etc. ) ``` @@ -34,28 +34,28 @@ mientras que un solo signo de número (#) indica notas. ## Variables ```perl6 -## En Perl 6, se declara una variable lexical usando `my` +## En Raku, se declara una variable lexical usando `my` my $variable; -## Perl 6 tiene 3 tipos básicos de variables: escalares, arrays, y hashes. +## Raku tiene 3 tipos básicos de variables: escalares, arrays, y hashes. ``` ### Escalares ```perl6 -# Un escalar representa un solo valor. Variables escalares comienzan +# Un escalar representa un solo valor. Variables escalares comienzan # con un `$` my $str = 'Cadena'; -# Las comillas inglesas ("") permiten la intepolación (lo cual veremos +# Las comillas inglesas ("") permiten la intepolación (lo cual veremos # luego): my $str2 = "Cadena"; ## Los nombres de variables pueden contener pero no terminar con comillas -## simples y guiones. Sin embargo, pueden contener +## simples y guiones. Sin embargo, pueden contener ## (y terminar con) guiones bajos (_): my $nombre'de-variable_ = 5; # Esto funciona! -my $booleano = True; # `True` y `False` son valores booleanos en Perl 6. +my $booleano = True; # `True` y `False` son valores booleanos en Raku. my $inverso = !$booleano; # Puedes invertir un booleano con el operador prefijo `!` my $bool-forzado = so $str; # Y puedes usar el operador prefijo `so` que # convierte su operador en un Bool @@ -70,7 +70,7 @@ my $bool-forzado = so $str; # Y puedes usar el operador prefijo `so` que my @array = 'a', 'b', 'c'; # equivalente a: my @letras = <a b c>; # array de palabras, delimitado por espacios. - # Similar al qw de perl5, o el %w de Ruby. + # Similar al qw de perl, o el %w de Ruby. my @array = 1, 2, 3; say @array[2]; # Los índices de un array empiezan por el 0 -- Este es @@ -83,7 +83,7 @@ say "Interpola todos los elementos de un array usando [] : @array[]"; @array[0, 1] = 5, 6; # Asigna varios valores my @llaves = 0, 2; -@array[@llaves] = @letras; # Asignación usando un array que contiene valores +@array[@llaves] = @letras; # Asignación usando un array que contiene valores # índices say @array; #=> a 6 b ``` @@ -93,19 +93,19 @@ say @array; #=> a 6 b ```perl6 ## Un hash contiene parejas de llaves y valores. ## Puedes construir un objeto Pair usando la sintaxis `LLave => Valor`. -## Tablas de hashes son bien rápidas para búsqueda, y son almacenadas +## Tablas de hashes son bien rápidas para búsqueda, y son almacenadas ## sin ningún orden. ## Ten en cuenta que las llaves son "aplanadas" en contexto de hash, y ## cualquier llave duplicada es deduplicada. my %hash = 1 => 2, 3 => 4; -my %hash = foo => "bar", # las llaves reciben sus comillas +my %hash = foo => "bar", # las llaves reciben sus comillas # automáticamente. "some other" => "value", # las comas colgantes estań bien. ; ## Aunque los hashes son almacenados internamente de forma diferente a los -## arrays, Perl 6 te permite crear un hash usando un array +## arrays, Raku te permite crear un hash usando un array ## con un número par de elementos fácilmente. my %hash = <llave1 valor1 llave2 valor2>; @@ -122,7 +122,7 @@ my %hash = :w(1), # equivalente a `w => 1` say %hash{'llave1'}; # Puedes usar {} para obtener el valor de una llave say %hash<llave2>; # Si es una cadena de texto, puedes actualmente usar <> - # (`{llave1}` no funciona, debido a que Perl 6 no tiene + # (`{llave1}` no funciona, debido a que Raku no tiene # palabras desnudas (barewords en inglés)) ``` @@ -133,7 +133,7 @@ say %hash<llave2>; # Si es una cadena de texto, puedes actualmente usar <> ## creadas con la palabra clave `sub`. sub di-hola { say "¡Hola, mundo!" } -## Puedes proveer argumentos (tipados). Si especificado, +## Puedes proveer argumentos (tipados). Si especificado, ## el tipo será chequeado al tiempo de compilación si es posible. ## De lo contrario, al tiempo de ejecución. sub di-hola-a(Str $nombre) { @@ -165,7 +165,7 @@ say return-for; # imprime Nil ## Una subrutina puede tener argumentos opcionales: sub con-opcional($arg?) { # el signo "?" marca el argumento opcional - say "Podría returnar `(Any)` (valor de Perl parecido al 'null') si no me pasan + say "Podría returnar `(Any)` (valor de Perl parecido al 'null') si no me pasan un argumento, o returnaré mi argumento"; $arg; } @@ -173,7 +173,7 @@ con-opcional; # devuelve Any con-opcional(); # devuelve Any con-opcional(1); # devuelve 1 -## También puedes proveer un argumento por defecto para +## También puedes proveer un argumento por defecto para ## cuando los argumentos no son proveídos: sub hola-a($nombre = "Mundo") { say "¡Hola, $nombre!"; @@ -190,10 +190,10 @@ sub con-nombre($arg-normal, :$nombrado) { } con-nombre(1, nombrado => 6); #=> 7 ## Sin embargo, debes tener algo en cuenta aquí: -## Si pones comillas alrededor de tu llave, Perl 6 no será capaz de verla +## Si pones comillas alrededor de tu llave, Raku no será capaz de verla ## al tiempo de compilación, y entonces tendrás un solo objeto Pair como -## un argumento posicional, lo que significa que el siguiente ejemplo -## falla: +## un argumento posicional, lo que significa que el siguiente ejemplo +## falla: con-nombre(1, 'nombrado' => 6); con-nombre(2, :nombrado(5)); #=> 7 @@ -205,7 +205,7 @@ sub con-nombre-mandatorio(:$str!) { } con-nombre-mandatorio(str => "Mi texto"); #=> Mi texto! con-nombre-mandatorio; # error al tiempo de ejecución: - # "Required named parameter not passed" + # "Required named parameter not passed" # ("Parámetro nombrado requerido no proveído") con-nombre-mandatorio(3);# error al tiempo de ejecución: # "Too many positional parameters passed" @@ -226,7 +226,7 @@ sub nombrado-definido(:$def = 5) { nombrado-definido; #=> 5 nombrado-definido(def => 15); #=> 15 -## Dado que puedes omitir los paréntesis para invocar una función sin +## Dado que puedes omitir los paréntesis para invocar una función sin ## argumentos, necesitas usar "&" en el nombre para almacenar la función ## `di-hola` en una variable. my &s = &di-hola; @@ -240,8 +240,8 @@ sub muchos($principal, *@resto) { #`*@` (slurpy) consumirá lo restante say @resto.join(' / ') ~ "!"; } say muchos('Feliz', 'Cumpleaño', 'Cumpleaño'); #=> Feliz / Cumpleaño! - # Nota que el asterisco (*) no - # consumió el parámetro frontal. + # Nota que el asterisco (*) no + # consumió el parámetro frontal. ## Puedes invocar un función con un array usando el ## operador "aplanador de lista de argumento" `|` @@ -256,12 +256,12 @@ concat3(|@array); #=> a, b, c ## Contenedores ```perl6 -## En Perl 6, valores son actualmente almacenados en "contenedores". -## El operador de asignación le pregunta al contenedor en su izquierda +## En Raku, valores son actualmente almacenados en "contenedores". +## El operador de asignación le pregunta al contenedor en su izquierda ## almacenar el valor a su derecha. Cuando se pasan alrededor, contenedores ## son marcados como inmutables. Esto significa que, en una función, tu ## tendrás un error si tratas de mutar uno de tus argumentos. -## Si realmente necesitas hacerlo, puedes preguntar por un contenedor +## Si realmente necesitas hacerlo, puedes preguntar por un contenedor ## mutable usando `is rw`: sub mutar($n is rw) { $n++; @@ -276,7 +276,7 @@ mutar $m; # ¡$n es ahora 43! ## dado que no contenedor ha sido pasado y números enteros son inmutables ## por naturaleza: -mutar 42; # Parámetro '$n' esperaba un contenedor mutable, +mutar 42; # Parámetro '$n' esperaba un contenedor mutable, # pero recibió un valor Int ## Si en cambio quieres una copia, debes usar `is copy`. @@ -286,7 +286,7 @@ mutar 42; # Parámetro '$n' esperaba un contenedor mutable, my $x = 42; sub x-almacena() is rw { $x } x-almacena() = 52; # En este caso, los paréntesis son mandatorios - # (porque de otra forma, Perl 6 piensa que la función + # (porque de otra forma, Raku piensa que la función # `x-almacena` es un identificador). say $x; #=> 52 ``` @@ -297,9 +297,9 @@ say $x; #=> 52 ```perl6 ## - `if` ## Antes de hablar acerca de `if`, necesitamos saber cuales valores son -## "Truthy" (representa True (verdadero)), y cuales son "Falsey" -## (o "Falsy") -- representa False (falso). Solo estos valores son -## Falsey: 0, (), {}, "", Nil, un tipo (como `Str` o`Int`) y +## "Truthy" (representa True (verdadero)), y cuales son "Falsey" +## (o "Falsy") -- representa False (falso). Solo estos valores son +## Falsey: 0, (), {}, "", Nil, un tipo (como `Str` o`Int`) y ## por supuesto False. Todos los valores son Truthy. if True { say "¡Es verdadero!"; @@ -316,8 +316,8 @@ unless False { ## También puedes usar sus versiones sufijos seguidas por la palabra clave: say "Un poco verdadero" if True; -## - La condicional ternaria, "?? !!" (como `x ? y : z` en otros lenguajes) -## devuelve $valor-si-verdadera si la condición es verdadera y +## - La condicional ternaria, "?? !!" (como `x ? y : z` en otros lenguajes) +## devuelve $valor-si-verdadera si la condición es verdadera y ## $valor-si-falsa si es falsa. ## my $resultado = $valor condición ?? $valor-si-verdadera !! $valor-si-falsa; @@ -338,21 +338,21 @@ say $edad > 18 ?? "Eres un adulto" !! "Eres menor de 18"; ## ## `given` simplemente pone su argumento en `$_` (como un bloque lo haría), ## y `when` lo compara usando el operador de "coincidencia inteligente" (`~~`). -## -## Dado que otras construcciones de Perl 6 usan esta variable (por ejemplo, +## +## Dado que otras construcciones de Raku usan esta variable (por ejemplo, ## el bucle `for`, bloques, etc), esto se significa que el poderoso `when` no -## solo se aplica con un `given`, sino que se puede usar en cualquier +## solo se aplica con un `given`, sino que se puede usar en cualquier ## lugar donde exista una variable `$_`. given "foo bar" { say $_; #=> foo bar - when /foo/ { # No te preocupies acerca de la coincidencia inteligente – + when /foo/ { # No te preocupies acerca de la coincidencia inteligente – # solo ten presente que `when` la usa. # Esto es equivalente a `if $_ ~~ /foo/`. say "¡Yay!"; } when $_.chars > 50 { # coincidencia inteligente con cualquier cosa True es True, - # i.e. (`$a ~~ True`) + # i.e. (`$a ~~ True`) # por lo tanto puedes también poner condiciones "normales". # Este `when` es equivalente a este `if`: # if $_ ~~ ($_.chars > 50) {...} @@ -373,12 +373,12 @@ given "foo bar" { ## pero también puede ser un bucle for al estilo de C: loop { say "¡Este es un bucle infinito!"; - last; # last interrumpe el bucle, como la palabra clave `break` + last; # last interrumpe el bucle, como la palabra clave `break` # en otros lenguajes. } loop (my $i = 0; $i < 5; $i++) { - next if $i == 3; # `next` salta a la siguiente iteración, al igual + next if $i == 3; # `next` salta a la siguiente iteración, al igual # que `continue` en otros lenguajes. Ten en cuenta que # también puedes usar la condicionales postfix (sufijas) # bucles, etc. @@ -391,29 +391,29 @@ for @array -> $variable { } ## Como vimos con `given`, la variable de una "iteración actual" por defecto -## es `$_`. Esto significa que puedes usar `when` en un bucle `for` como +## es `$_`. Esto significa que puedes usar `when` en un bucle `for` como ## normalmente lo harías con `given`. for @array { say "he conseguido a $_"; .say; # Esto es también permitido. - # Una invocación con punto (dot call) sin "tópico" (recibidor) es - # enviada a `$_` por defecto. + # Una invocación con punto (dot call) sin "tópico" (recibidor) es + # enviada a `$_` por defecto. $_.say; # lo mismo de arriba, lo cual es equivalente. } for @array { # Puedes... - next if $_ == 3; # Saltar a la siguiente iteración (`continue` en + next if $_ == 3; # Saltar a la siguiente iteración (`continue` en # lenguages parecido a C) - redo if $_ == 4; # Re-hacer la iteración, manteniendo la + redo if $_ == 4; # Re-hacer la iteración, manteniendo la # misma variable tópica (`$_`) - last if $_ == 5; # Salir fuera del bucle (como `break` + last if $_ == 5; # Salir fuera del bucle (como `break` # en lenguages parecido a C) } -## La sintaxis de "bloque puntiagudo" no es específica al bucle for. -## Es solo una manera de expresar un bloque en Perl 6. +## La sintaxis de "bloque puntiagudo" no es específica al bucle for. +## Es solo una manera de expresar un bloque en Raku. if computación-larga() -> $resultado { say "El resultado es $resultado"; } @@ -423,7 +423,7 @@ if computación-larga() -> $resultado { ```perl6 ## Dados que los lenguajes de la familia Perl son lenguages basados -## mayormente en operadores, los operadores de Perl 6 son actualmente +## mayormente en operadores, los operadores de Raku son actualmente ## subrutinas un poco cómicas en las categorías sintácticas. Por ejemplo, ## infix:<+> (adición) o prefix:<!> (bool not). @@ -455,7 +455,7 @@ if computación-larga() -> $resultado { (1, 2) eqv (1, 3); ## - Operador de coincidencia inteligente (smart matching): `~~` -## Asocia (aliasing en inglés) el lado izquierda a la variable $_ +## Asocia (aliasing en inglés) el lado izquierda a la variable $_ ## y después evalúa el lado derecho. ## Aquí algunas comparaciones semánticas comunes: @@ -464,8 +464,8 @@ if computación-larga() -> $resultado { 'Foo' ~~ 'Foo'; # True si las cadenas de texto son iguales. 12.5 ~~ 12.50; # True si los números son iguales. -## Regex - Para la comparación de una expresión regular en contra -## del lado izquierdo. Devuelve un objeto (Match), el cual evalúa +## Regex - Para la comparación de una expresión regular en contra +## del lado izquierdo. Devuelve un objeto (Match), el cual evalúa ## como True si el regex coincide con el patrón. my $obj = 'abc' ~~ /a/; @@ -475,12 +475,12 @@ say $obj.WHAT; # (Match) ## Hashes 'llave' ~~ %hash; # True si la llave existe en el hash -## Tipo - Chequea si el lado izquierdo "tiene un tipo" (puede chequear +## Tipo - Chequea si el lado izquierdo "tiene un tipo" (puede chequear ## superclases y roles) 1 ~~ Int; # True (1 es un número entero) -## Coincidencia inteligente contra un booleano siempre devuelve ese +## Coincidencia inteligente contra un booleano siempre devuelve ese ## booleano (y lanzará una advertencia). 1 ~~ True; # True @@ -502,13 +502,13 @@ False ~~ True; # True ## Esto también funciona como un atajo para `0..^N`: ^10; # significa 0..^10 -## Esto también nos permite demostrar que Perl 6 tiene arrays +## Esto también nos permite demostrar que Raku tiene arrays ## ociosos/infinitos, usando la Whatever Star: my @array = 1..*; # 1 al Infinito! `1..Inf` es lo mismo. say @array[^10]; # puedes pasar arrays como subíndices y devolverá # un array de resultados. Esto imprimirá # "1 2 3 4 5 6 7 8 9 10" (y no se quedaré sin memoria!) -## Nota: Al leer una lista infinita, Perl 6 "cosificará" los elementos que +## Nota: Al leer una lista infinita, Raku "cosificará" los elementos que ## necesita y los mantendrá en la memoria. Ellos no serán calculados más de ## una vez. Tampoco calculará más elementos de los que necesita. @@ -517,14 +517,14 @@ say @array[^10]; # puedes pasar arrays como subíndices y devolverá say join(' ', @array[15..*]); #=> 15 16 17 18 19 ## lo que es equivalente a: say join(' ', @array[-> $n { 15..$n }]); -## Nota: Si tratas de hacer cualquiera de esos con un array infinito, +## Nota: Si tratas de hacer cualquiera de esos con un array infinito, ## provocará un array infinito (tu programa nunca terminará) ## Puedes usar eso en los lugares que esperaría, como durante la asignación ## a un array my @números = ^20; -## Aquí los números son incrementados por "6"; más acerca del +## Aquí los números son incrementados por "6"; más acerca del ## operador `...` adelante. my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99; @números[5..*] = 3, 9 ... *; # aunque la secuencia es infinita, @@ -546,7 +546,7 @@ $a && $b && $c; # Devuelve 0, el primer valor que es False $b || $a; # 1 ## Y porque tu lo querrás, también tienes operadores de asignación -## compuestos: +## compuestos: $a *= 2; # multiplica y asigna. Equivalente a $a = $a * 2; $b %%= 5; # divisible por y asignación. Equivalente $b = $b %% 5; @array .= sort; # invoca el método `sort` y asigna el resultado devuelto. @@ -555,8 +555,8 @@ $b %%= 5; # divisible por y asignación. Equivalente $b = $b %% 5; ## ¡Más sobre subrutinas! ```perl6 -## Como dijimos anteriormente, Perl 6 tiene subrutinas realmente poderosas. -## Veremos unos conceptos claves que la hacen mejores que en cualquier otro +## Como dijimos anteriormente, Raku tiene subrutinas realmente poderosas. +## Veremos unos conceptos claves que la hacen mejores que en cualquier otro ## lenguaje :-). ``` @@ -602,14 +602,14 @@ sub fst(*@ [$fst]) { # o simplemente: `sub fst($fst) { ... }` fst(1); #=> 1 fst(1, 2); # errores con "Too many positional parameters passed" -## También puedes desestructurar hashes (y clases, las cuales -## veremos adelante). La sintaxis es básicamente +## También puedes desestructurar hashes (y clases, las cuales +## veremos adelante). La sintaxis es básicamente ## `%nombre-del-hash (:llave($variable-para-almacenar))`. ## El hash puede permanecer anónimos si solo necesitas los valores extraídos. sub llave-de(% (:azul($val1), :red($val2))) { say "Valores: $val1, $val2."; } -## Después invócala con un hash: (necesitas mantener las llaves +## Después invócala con un hash: (necesitas mantener las llaves ## de los parejas de llave y valor para ser un hash) llave-de({azul => 'blue', rojo => "red"}); #llave-de(%hash); # lo mismo (para un `%hash` equivalente) @@ -621,11 +621,11 @@ sub siguiente-indice($n) { } my $nuevo-n= siguiente-indice(3); # $nuevo-n es ahora 4 -## Este es cierto para todo, excepto para las construcciones de bucles +## Este es cierto para todo, excepto para las construcciones de bucles ## (debido a razones de rendimiento): Hay una razón de construir una lista ## si la vamos a desechar todos los resultados. ## Si todavías quieres construir una, puedes usar la sentencia prefijo `do`: -## (o el prefijo `gather`, el cual veremos luego) +## (o el prefijo `gather`, el cual veremos luego) sub lista-de($n) { do for ^$n { # nota el uso del operador de rango `^` (`0..^N`) $_ # iteración de bucle actual @@ -639,19 +639,19 @@ my @list3 = lista-de(3); #=> (0, 1, 2) ```perl6 ## Puedes crear una lambda con `-> {}` ("bloque puntiagudo") o `{}` ("bloque") my &lambda = -> $argumento { "El argumento pasado a esta lambda es $argumento" } -## `-> {}` y `{}` son casi la misma cosa, excepto que la primerra puede +## `-> {}` y `{}` son casi la misma cosa, excepto que la primerra puede ## tomar argumentos, y la segunda puede ser malinterpretada como un hash ## por el parseador. ## Podemos, por ejemplo, agregar 3 a cada valor de un array usando map: my @arraymas3 = map({ $_ + 3 }, @array); # $_ es el argumento implícito -## Una subrutina (`sub {}`) tiene semánticas diferentes a un -## bloque (`{}` or `-> {}`): Un bloque no tiene "contexto funcional" +## Una subrutina (`sub {}`) tiene semánticas diferentes a un +## bloque (`{}` or `-> {}`): Un bloque no tiene "contexto funcional" ## (aunque puede tener argumentos), lo que significa que si quieres devolver ## algo desde un bloque, vas a returnar desde la función parental. Compara: sub is-in(@array, $elem) { - # esto `devolverá` desde la subrutina `is-in` + # esto `devolverá` desde la subrutina `is-in` # Una vez que la condición evalúa a True, el bucle terminará map({ return True if $_ == $elem }, @array); } @@ -685,7 +685,7 @@ map(sub ($a, $b) { $a + $b + 3 }, @array); # (aquí con `sub`) ### Acerca de tipos... ```perl6 -## Perl 6 es gradualmente tipado. Esto quiere decir que tu especifica el +## Raku es gradualmente tipado. Esto quiere decir que tu especifica el ## tipo de tus variables/argumentos/devoluciones (return), o puedes omitirlos ## y serán "Any" por defecto. ## Obviamente tienes acceso a algunas tipos básicos, como Int y Str. @@ -703,7 +703,7 @@ subset EnteroGrande of Int where * > 500; ### Despacho Múltiple (Multiple Dispatch) ```perl6 -## Perl 6 puede decidir que variante de una subrutina invocar basado en el +## Raku puede decidir que variante de una subrutina invocar basado en el ## tipo de los argumento, o precondiciones arbitrarias, como con un tipo o ## un `where`: @@ -740,9 +740,9 @@ multi sin_ti-o-contigo { } ## Esto es muy útil para muchos propósitos, como subrutinas `MAIN` (de las ## cuales hablaremos luego), y hasta el mismo lenguaje la está usando -## en muchos lugares. +## en muchos lugares. ## -## - `is`, por ejemplo, es actualmente un `multi sub` llamado +## - `is`, por ejemplo, es actualmente un `multi sub` llamado ## `trait_mod:<is>`. ## - `is rw`, es simplemente un despacho a una función con esta signatura: ## sub trait_mod:<is>(Routine $r, :$rw!) {} @@ -754,7 +754,7 @@ multi sin_ti-o-contigo { ## Ámbito (Scoping) ```perl6 -## En Perl 6, a diferencia de otros lenguajes de scripting, (tales como +## En Raku, a diferencia de otros lenguajes de scripting, (tales como ## (Python, Ruby, PHP), debes declarar tus variables antes de usarlas. El ## declarador `my`, del cual aprendiste anteriormente, usa "ámbito léxical". ## Hay otros declaradores (`our`, `state`, ..., ) los cuales veremos luego. @@ -770,7 +770,7 @@ sub externo { } outer()(); #=> 'Foo Bar' -## Como puedes ver, `$archivo-en-ámbito` y `$ámbito-externo` +## Como puedes ver, `$archivo-en-ámbito` y `$ámbito-externo` ## fueron capturados. Pero si intentaramos usar `$bar` fuera de `foo`, ## la variable estaría indefinida (y obtendrías un error al tiempo de ## compilación). @@ -779,12 +779,12 @@ outer()(); #=> 'Foo Bar' ## Twigils ```perl6 -## Hay muchos `twigils` especiales (sigilos compuestos) en Perl 6. -## Los twigils definen el ámbito de las variables. +## Hay muchos `twigils` especiales (sigilos compuestos) en Raku. +## Los twigils definen el ámbito de las variables. ## Los twigils * y ? funcionan con variables regulares: ## * Variable dinámica ## ? Variable al tiempo de compilación -## Los twigils ! y . son usados con los objetos de Perl 6: +## Los twigils ! y . son usados con los objetos de Raku: ## ! Atributo (miembro de la clase) ## . Método (no una variable realmente) @@ -820,20 +820,20 @@ di_ambito(); #=> 1 100 Cambiamos el valor de $*ambito_din_2 en invoca_a_di_ambit ```perl6 ## Para invocar a un método en un objeto, agrega un punto seguido por el -## nombre del objeto: +## nombre del objeto: ## => $object.method ## Las classes son declaradas usando la palabra clave `class`. Los atributos ## son declarados con la palabra clave `has`, y los métodos con `method`. ## Cada atributo que es privado usa el twigil `!`. Por ejemplo: `$!attr`. -## Atributos públicos inmutables usan el twigil `.` (los puedes hacer +## Atributos públicos inmutables usan el twigil `.` (los puedes hacer ## mutables con `is rw`). -## La manera más fácil de recordar el twigil `$.` is comparándolo +## La manera más fácil de recordar el twigil `$.` is comparándolo ## con como los métodos son llamados. -## El modelo de objeto de Perl 6 ("SixModel") es muy flexible, y te permite +## El modelo de objeto de Raku ("SixModel") es muy flexible, y te permite ## agregar métodos dinámicamente, cambiar la semántica, etc ... -## (no hablaremos de todo esto aquí. Por lo tanto, refiérete a: -## https://docs.perl6.org/language/objects.html). +## (no hablaremos de todo esto aquí. Por lo tanto, refiérete a: +## https://docs.raku.org/language/objects.html). class Clase-Atrib { has $.atrib; # `$.atrib` es inmutable. @@ -858,7 +858,7 @@ class Clase-Atrib { }; ## Crear una nueva instancia de Clase-Atrib con $.atrib asignado con 5: -## Nota: No puedes asignarle un valor a atrib-privado desde aquí (más de +## Nota: No puedes asignarle un valor a atrib-privado desde aquí (más de ## esto adelante). my $class-obj = Clase-Atrib.new(atrib => 5); say $class-obj.devolver-valor; #=> 5 @@ -870,12 +870,12 @@ $class-obj.otro-atrib = 10; # En cambio, esto funciona porque el atributo ### Herencia de Objeto ```perl6 -## Perl 6 también tiene herencia (junto a herencia múltiple) +## Raku también tiene herencia (junto a herencia múltiple) ## Mientras los métodos declarados con `method` son heredados, aquellos ## declarados con `submethod` no lo son. ## Submétodos son útiles para la construcción y destrucción de tareas, ## tales como BUILD, o métodos que deben ser anulados por subtipos. -## Aprenderemos acerca de BUILD más adelante. +## Aprenderemos acerca de BUILD más adelante. class Padre { has $.edad; @@ -890,7 +890,7 @@ class Padre { # Herencia usa la palabra clave `is` class Niño is Padre { method hablar { say "Goo goo ga ga" } - # Este método opaca el método `hablar` de Padre. + # Este método opaca el método `hablar` de Padre. # Este niño no ha aprendido a hablar todavía. } my Padre $Richard .= new(edad => 40, nombre => 'Richard'); @@ -899,19 +899,19 @@ $Richard.hablar; #=> "Hola, mi nombre es Richard" ## $Richard es capaz de acceder el submétodo; él sabe como decir su nombre. my Niño $Madison .= new(edad => 1, nombre => 'Madison'); -$Madison.hablar; # imprime "Goo goo ga ga" dado que el método fue cambiado +$Madison.hablar; # imprime "Goo goo ga ga" dado que el método fue cambiado # en la clase Niño. # $Madison.color-favorito # no funciona porque no es heredado ## Cuando se usa `my T $var` (donde `T` es el nombre de la clase), `$var` ## inicia con `T` en si misma, por lo tanto puedes invocar `new` en `$var`. -## (`.=` es sólo la invocación por punto y el operador de asignación: +## (`.=` es sólo la invocación por punto y el operador de asignación: ## `$a .= b` es lo mismo que `$a = $a.b`) ## Por ejemplo, la instancia $Richard pudo también haber sido declarada así: ## my $Richard = Padre.new(edad => 40, nombre => 'Richard'); -## También observa que `BUILD` (el método invocado dentro de `new`) -## asignará propiedades de la clase padre, por lo que puedes pasar +## También observa que `BUILD` (el método invocado dentro de `new`) +## asignará propiedades de la clase padre, por lo que puedes pasar ## `val => 5`. ``` @@ -932,7 +932,7 @@ class Item does PrintableVal { has $.val; ## Cuando se utiliza `does`, un `rol` se mezcla en al clase literalmente: - ## los métodos y atributos se ponen juntos, lo que significa que una clase + ## los métodos y atributos se ponen juntos, lo que significa que una clase ## puede acceder los métodos y atributos privados de su rol (pero no lo inverso!): method access { say $!counter++; @@ -945,17 +945,17 @@ class Item does PrintableVal { ## de su clase hijo/a, pero es un error sin un rol lo hace) ## NOTA: Puedes usar un rol como una clase (con `is ROLE`). En este caso, - ## métodos serán opacados, dado que el compilador considerará `ROLE` - ## como una clase. + ## métodos serán opacados, dado que el compilador considerará `ROLE` + ## como una clase. } ``` ## Excepciones ```perl6 -## Excepciones están construidas al tope de las clases, en el paquete +## Excepciones están construidas al tope de las clases, en el paquete ## `X` (como `X::IO`). -## En Perl 6, excepciones son lanzadas automáticamente. +## En Raku, excepciones son lanzadas automáticamente. open 'foo'; #=> Failed to open file foo: no such file or directory ## También imprimirá la línea donde el error fue lanzado y otra información ## concerniente al error. @@ -966,16 +966,16 @@ die 'Error!'; #=> Error! ## O más explícitamente: die X::AdHoc.new(payload => 'Error!'); -## En Perl 6, `orelse` es similar al operador `or`, excepto que solamente +## En Raku, `orelse` es similar al operador `or`, excepto que solamente ## coincide con variables indefinidas, en cambio de cualquier cosa ## que evalúa a falso. -## Valores indefinidos incluyen: `Nil`, `Mu` y `Failure`, también como +## Valores indefinidos incluyen: `Nil`, `Mu` y `Failure`, también como ## `Int`, `Str` y otros tipos que no han sido inicializados a ningún valor ## todavía. ## Puedes chequear si algo está definido o no usando el método defined: my $no-inicializada; say $no-inicializada.defined; #=> False -## Al usar `orelse`, se desarmará la excepción y creará un alias de dicho +## Al usar `orelse`, se desarmará la excepción y creará un alias de dicho ## fallo en $_ ## Esto evitará que sea automáticamente manejado e imprima una marejada de ## mensajes de errores en la pantalla. @@ -986,7 +986,7 @@ open 'foo' orelse say "Algo pasó {.exception}"; open 'foo' orelse say "Algo pasó $_"; #=> Algo pasó #=> Failed to open file foo: no such file or directory ## Ambos ejemplos anteriores funcionan pero en caso de que consigamos un -## objeto desde el lado izquierdo que no es un fallo, probablemente +## objeto desde el lado izquierdo que no es un fallo, probablemente ## obtendremos una advertencia. Más abajo vemos como usar `try` y `CATCH` ## para ser más expecíficos con las excepciones que capturamos. ``` @@ -994,8 +994,8 @@ open 'foo' orelse say "Algo pasó $_"; #=> Algo pasó ### Usando `try` y `CATCH` ```perl6 -## Al usar `try` y `CATCH`, puedes contener y manejar excepciones sin -## interrumpir el resto del programa. `try` asignará la última excepción +## Al usar `try` y `CATCH`, puedes contener y manejar excepciones sin +## interrumpir el resto del programa. `try` asignará la última excepción ## a la variable especial `$!`. ## Nota: Esto no tiene ninguna relación con las variables $!. @@ -1003,12 +1003,12 @@ try open 'foo'; say "Bueno, lo intenté! $!" if defined $!; #=> Bueno, lo intenté! Failed to open file #foo: no such file or directory ## Ahora, ¿qué debemos hacer si queremos más control sobre la excepción? -## A diferencia de otros lenguajes, en Perl 6 se pone el bloque `CATCH` +## A diferencia de otros lenguajes, en Raku se pone el bloque `CATCH` ## *dentro* del bloque a intentar (`try`). Similarmente como $_ fue asignada ## cuando 'disarmamos' la excepción con `orelse`, también usamos $_ en el ## bloque CATCH. ## Nota: ($! es solo asignada *después* del bloque `try`) -## Por defecto, un bloque `try` tiene un bloque `CATCH` que captura +## Por defecto, un bloque `try` tiene un bloque `CATCH` que captura ## cualquier excepción (`CATCH { default {} }`). try { my $a = (0 %% 0); CATCH { say "Algo pasó: $_" } } @@ -1022,9 +1022,9 @@ try { when X::AdHoc { say "Error: $_" } #=>Error: Failed to open file /dir/foo: no such file or directory - ## Cualquier otra excepción será levantada de nuevo, dado que no + ## Cualquier otra excepción será levantada de nuevo, dado que no ## tenemos un `default`. - ## Básicamente, si un `when` + ## Básicamente, si un `when` ## Basically, if a `when` matches (or there's a `default`) marks the ## exception as ## "handled" so that it doesn't get re-thrown from the `CATCH`. @@ -1032,14 +1032,14 @@ try { } } -## En Perl 6, excepciones poseen ciertas sutilezas. Algunas -## subrutinas en Perl 6 devuelven un `Failure`, el cual es un tipo de +## En Raku, excepciones poseen ciertas sutilezas. Algunas +## subrutinas en Raku devuelven un `Failure`, el cual es un tipo de ## "excepción no levantada". Ellas no son levantadas hasta que tu intentas -## mirar a sus contenidos, a menos que invoques `.Bool`/`.defined` sobre +## mirar a sus contenidos, a menos que invoques `.Bool`/`.defined` sobre ## ellas - entonces, son manejadas. ## (el método `.handled` es `rw`, por lo que puedes marcarlo como `False` ## por ti mismo) -## Puedes levantar un `Failure` usando `fail`. Nota que si el pragma +## Puedes levantar un `Failure` usando `fail`. Nota que si el pragma ## `use fatal` estás siendo utilizado, `fail` levantará una excepión (como ## `die`). fail "foo"; # No estamos intentando acceder el valor, por lo tanto no problema. @@ -1053,27 +1053,27 @@ try { ## También hay otro tipo de excepción: Excepciones de control. ## Esas son excepciones "buenas", las cuales suceden cuando cambias el flujo ## de tu programa, usando operadores como `return`, `next` or `last`. -## Puedes capturarlas con `CONTROL` (no lista un 100% en Rakudo todavía). +## Puedes capturarlas con `CONTROL` (no lista un 100% en Rakudo todavía). ``` ## Paquetes ```perl6 -## Paquetes son una manera de reusar código. Paquetes son como -## "espacio de nombres" (namespaces en inglés), y cualquier elemento del +## Paquetes son una manera de reusar código. Paquetes son como +## "espacio de nombres" (namespaces en inglés), y cualquier elemento del ## modelo seis (`module`, `role`, `class`, `grammar`, `subset` y `enum`) -## son paquetes por ellos mismos. (Los paquetes son como el mínimo común +## son paquetes por ellos mismos. (Los paquetes son como el mínimo común ## denominador) -## Los paquetes son importantes - especialmente dado que Perl es bien +## Los paquetes son importantes - especialmente dado que Perl es bien ## reconocido por CPAN, the Comprehensive Perl Archive Nertwork. ## Puedes usar un módulo (traer sus declaraciones al ámbito) con `use` use JSON::Tiny; # si intalaste Rakudo* o Panda, tendrás este módulo say from-json('[1]').perl; #=> [1] -## A diferencia de Perl 5, no deberías declarar paquetes usando +## A diferencia de Perl, no deberías declarar paquetes usando ## la palabra clave `package`. En vez, usa `class Nombre::Paquete::Aquí;` -## para declarar una clase, o si solamente quieres exportar +## para declarar una clase, o si solamente quieres exportar ## variables/subrutinas, puedes usar `module`. module Hello::World { # forma de llaves @@ -1083,11 +1083,11 @@ module Hello::World { # forma de llaves } unit module Parse::Text; # forma de ámbito de archivo -grammar Parse::Text::Grammar { # Una gramática (grammar en inglés) es un paquete, +grammar Parse::Text::Grammar { # Una gramática (grammar en inglés) es un paquete, # en el cual puedes usar `use` } # Aprenderás más acerca de gramáticas en la sección de regex -## Como se dijo anteriormente, cualquier parte del modelo seis es también un +## Como se dijo anteriormente, cualquier parte del modelo seis es también un ## paquete. Dado que `JSON::Tiny` usa su propia clase `JSON::Tiny::Actions`, ## tu puedes usarla de la manera siguiente: my $acciones = JSON::Tiny::Actions.new; @@ -1098,13 +1098,13 @@ my $acciones = JSON::Tiny::Actions.new; ## Declaradores ```perl6 -## En Perl 6, tu obtienes diferentes comportamientos basado en como declaras +## En Raku, tu obtienes diferentes comportamientos basado en como declaras ## una variable. ## Ya has visto `my` y `has`, ahora exploraremos el resto. ## * las declaraciones `our` ocurren al tiempo `INIT` (ve "Phasers" más abajo) ## Es como `my`, pero también crea una variable paquete. -## (Todas las cosas relacionadas con paquetes (`class`, `role`, etc) son +## (Todas las cosas relacionadas con paquetes (`class`, `role`, etc) son ## `our` por defecto) module Var::Incrementar { our $nuestra-var = 1; # Nota: No puedes colocar una restricción de tipo @@ -1132,7 +1132,7 @@ Var::Incrementar::Inc; #=> 3 # Nota como el valor de $nuestra-var fue Var::Incrementar::no-disponible; #=> Could not find symbol '&no-disponible' ## * `constant` (ocurre al tiempo `BEGIN`) -## Puedes usar la palabra clave `constant` para declarar una +## Puedes usar la palabra clave `constant` para declarar una ## variable/símbolo al tiempo de compilación: constant Pi = 3.14; constant $var = 1; @@ -1151,11 +1151,11 @@ sub aleatorio-fijo { aleatorio-fijo for ^10; # imprimirá el mismo número 10 veces ## Nota, sin embargo, que ellas existen separadamente en diferentes contextos. -## Si declaras una función con un `state` dentro de un bucle, recreará la +## Si declaras una función con un `state` dentro de un bucle, recreará la ## variable por cada iteración del bucle. Observa: for ^5 -> $a { sub foo { - state $valor = rand; # Esto imprimirá un valor diferente + state $valor = rand; # Esto imprimirá un valor diferente # por cada valor de `$a` } for ^5 -> $b { @@ -1165,11 +1165,11 @@ for ^5 -> $a { } ``` -## Phasers +## Phasers ```perl6 -## Un phaser en Perl 6 es un bloque que ocurre a determinados puntos de tiempo -## en tu programa. Se les llama phaser porque marca un cambio en la fase de +## Un phaser en Raku es un bloque que ocurre a determinados puntos de tiempo +## en tu programa. Se les llama phaser porque marca un cambio en la fase de ## de tu programa. Por ejemplo, cuando el programa es compilado, un bucle ## for se ejecuta, dejas un bloque, o una excepción se levanta. ## (¡`CATCH` es actualmente un phaser!) @@ -1191,13 +1191,13 @@ END { say "Se ejecuta al tiempo de ejecución, " ~ "tan tarde como sea posible, una sola vez" } ## * Phasers de bloques -ENTER { say "[*] Se ejecuta cada vez que entra en un bloque, " ~ +ENTER { say "[*] Se ejecuta cada vez que entra en un bloque, " ~ "se repite en bloques de bucle" } -LEAVE { say "Se ejecuta cada vez que abandona un bloque, incluyendo " ~ +LEAVE { say "Se ejecuta cada vez que abandona un bloque, incluyendo " ~ "cuando una excepción ocurre. Se repite en bloques de bucle"} PRE { - say "Impone una precondición a cada entrada de un bloque, " ~ + say "Impone una precondición a cada entrada de un bloque, " ~ "antes que ENTER (especialmente útil para bucles)"; say "Si este bloque no returna un valor truthy, " ~ "una excepción del tipo X::Phaser::PrePost será levantada."; @@ -1209,7 +1209,7 @@ for 0..2 { } POST { - say "Impone una postcondAsserts a poscondición a la salida de un bloque, " ~ + say "Impone una postcondAsserts a poscondición a la salida de un bloque, " ~ "después de LEAVE (especialmente útil para bucles)"; say "Si este bloque no returna un valor truthy, " ~ "una excepción del tipo X::Phaser::PrePost será levantada, como con PRE."; @@ -1250,14 +1250,14 @@ sub do-db-stuff { ## Prefijos de sentencias ```perl6 -## Los prefijos de sentencias actúan como los phasers: Ellos afectan el +## Los prefijos de sentencias actúan como los phasers: Ellos afectan el ## comportamiento del siguiente código. ## Debido a que son ejecutados en línea con el código ejecutable, ellos ## se escriben en letras minúsculas. (`try` and `start` están teoréticamente ## en esa lista, pero serán explicados en otra parte) ## Nota: Ningunos de estos (excepto `start`) necesitan las llaves `{` y `}`. -## - `do` (el cual ya viste) - ejecuta un bloque o una sentencia como un +## - `do` (el cual ya viste) - ejecuta un bloque o una sentencia como un ## término. ## Normalmente no puedes usar una sentencia como un valor (o término): ## @@ -1289,7 +1289,7 @@ say join ',', gather if False { ## - `eager` - Evalúa una sentencia ávidamente (forza contexto ávido) ## No intentes esto en casa: ## -## eager 1..*; # esto probablemente se colgará por un momento +## eager 1..*; # esto probablemente se colgará por un momento ## # (y podría fallar...). ## ## Pero considera lo siguiente: @@ -1302,13 +1302,13 @@ constant tres-veces = eager gather for ^3 { say take $_ }; #=> 0 1 2 ## Iterables ```perl6 -## En Perl 6, los iterables son objetos que pueden ser iterados similar -## a la construcción `for`. +## En Raku, los iterables son objetos que pueden ser iterados similar +## a la construcción `for`. ## `flat`, aplana iterables: say (1, 10, (20, 10) ); #=> (1 10 (20 10)) Nota como la agrupación se mantiene say (1, 10, (20, 10) ).flat; #=> (1 10 20 10) Ahora el iterable es plano -## - `lazy` - Aplaza la evaluación actual hasta que el valor sea requirido +## - `lazy` - Aplaza la evaluación actual hasta que el valor sea requirido ## (forza contexto perezoso) my @lazy-array = (1..100).lazy; say @lazy-array.is-lazy; #=> True # Chequea por "pereza" con el método `is-lazy`. @@ -1333,7 +1333,7 @@ quietly { warn 'Esto es una advertencia!' }; #=> No salida ## ¡Todo el mundo ama los operadores! Tengamos más de ellos. ## La lista de precedencia puede ser encontrada aquí: -## https://docs.perl6.org/language/operators#Operator_Precedence +## https://docs.raku.org/language/operators#Operator_Precedence ## Pero primero, necesitamos un poco de explicación acerca ## de la asociatividad: @@ -1356,7 +1356,7 @@ $a ! $b ! $c; # con asociatividad de lista `!`, esto es `infix:<>` ## Okay, has leído todo esto y me imagino que debería mostrarte ## algo interesante. ## Te mostraré un pequeño secreto (o algo no tan secreto): -## En Perl 6, todos los operadores son actualmente solo subrutinas. +## En Raku, todos los operadores son actualmente solo subrutinas. ## Puedes declarar un operador como declaras una subrutina: sub prefix:<ganar>($ganador) { # se refiere a las categorías de los operadores @@ -1374,14 +1374,14 @@ sub postfix:<!>(Int $n) { } say 5!; #=> 120 # Operadores sufijos (postfix) van *directamente* después del témino. - # No espacios en blanco. Puedes usar paréntesis para disambiguar, + # No espacios en blanco. Puedes usar paréntesis para disambiguar, # i.e. `(5!)!` sub infix:<veces>(Int $n, Block $r) { # infijo va en el medio for ^$n { $r(); # Necesitas los paréntesis explícitos para invocar la función - # almacenada en la variable `$r`. De lo contrario, te estaría + # almacenada en la variable `$r`. De lo contrario, te estaría # refiriendo a la variable (no a la función), como con `&r`. } } @@ -1399,33 +1399,33 @@ say [5]; #=> 3125 # un circunfijo va alrededor. De nuevo, no espacios en blanco. sub postcircumfix:<{ }>(Str $s, Int $idx) { - ## un pos-circunfijo es + ## un pos-circunfijo es ## "después de un término y alrededor de algo" $s.substr($idx, 1); } say "abc"{1}; #=> b # depués del término `"abc"`, y alrededor del índice (1) -## Esto es de gran valor -- porque todo en Perl 6 usa esto. +## Esto es de gran valor -- porque todo en Raku usa esto. ## Por ejemplo, para eliminar una llave de un hash, tu usas el adverbio ## `:delete` (un simple argumento con nombre debajo): %h{$llave}:delete; ## es equivalente a: -postcircumfix:<{ }>(%h, $llave, :delete); # (puedes invocar +postcircumfix:<{ }>(%h, $llave, :delete); # (puedes invocar # operadores de esta forma) -## ¡*Todos* usan los mismos bloques básicos! +## ¡*Todos* usan los mismos bloques básicos! ## Categorías sintácticas (prefix, infix, ...), argumentos nombrados ## (adverbios), ... - usados para construir el lenguaje - están al alcance ## de tus manos y disponibles para ti. -## (obviamente, no se te recomienda que hagas un operador de *cualquier +## (obviamente, no se te recomienda que hagas un operador de *cualquier ## cosa* -- Un gran poder conlleva una gran responsabilidad.) ``` ### Meta-operadores! ```perl6 -## ¡Prepárate! Prepárate porque nos estamos metiendo bien hondo -## en el agujero del conejo, y probablemente no querrás regresar a +## ¡Prepárate! Prepárate porque nos estamos metiendo bien hondo +## en el agujero del conejo, y probablemente no querrás regresar a ## otros lenguajes después de leer esto. ## (Me imagino que ya no quieres a este punto). ## Meta-operadores, como su nombre lo sugiere, son operadores *compuestos*. @@ -1434,14 +1434,14 @@ postcircumfix:<{ }>(%h, $llave, :delete); # (puedes invocar ## * El meta-operador reduce (reducir) ## Es un meta-operador prefijo que toman una función binaria y ## una o varias listas. Sino se pasa ningún argumento, -## returna un "valor por defecto" para este operador +## returna un "valor por defecto" para este operador ## (un valor sin significado) o `Any` si no hay ningún valor. ## -## De lo contrario, remueve un elemento de la(s) lista(s) uno a uno, y +## De lo contrario, remueve un elemento de la(s) lista(s) uno a uno, y ## aplica la función binaria al último resultado (o al primer elemento de ## la lista y el elemento que ha sido removido). ## -## Para sumar una lista, podrías usar el meta-operador "reduce" con `+`, +## Para sumar una lista, podrías usar el meta-operador "reduce" con `+`, ## i.e.: say [+] 1, 2, 3; #=> 6 ## es equivalente a `(1+2)+3` @@ -1461,20 +1461,20 @@ say [+] (); #=> 0 # valores sin significado, dado que N*1=N y N+0=N. say [//]; #=> (Any) # No hay valor por defecto para `//`. -## También puedes invocarlo con una función de tu creación usando +## También puedes invocarlo con una función de tu creación usando ## los dobles corchetes: sub add($a, $b) { $a + $b } say [[&add]] 1, 2, 3; #=> 6 ## * El meta-operador zip -## Este es un meta-operador infijo que también puede ser usado como un +## Este es un meta-operador infijo que también puede ser usado como un ## operador "normal". Toma una función binaria opcional (por defecto, solo -## crear un par), y remueve un valor de cada array e invoca su función +## crear un par), y remueve un valor de cada array e invoca su función ## binaria hasta que no tenga más elementos disponibles. Al final, returna ## un array con todos estos nuevos elementos. -(1, 2) Z (3, 4); # ((1, 3), (2, 4)), dado que por defecto, la función +(1, 2) Z (3, 4); # ((1, 3), (2, 4)), dado que por defecto, la función # crea un array. -1..3 Z+ 4..6; # (5, 7, 9), usando la función personalizada infix:<+> +1..3 Z+ 4..6; # (5, 7, 9), usando la función personalizada infix:<+> ## Dado que `Z` tiene asociatividad de lista (ve la lista más arriba), ## puedes usarlo en más de una lista @@ -1487,13 +1487,13 @@ say [[&add]] 1, 2, 3; #=> 6 ## Y para terminar la lista de operadores: ## * El operador secuencia -## El operador secuencia es uno de la más poderosas características de -## Perl 6: Está compuesto, en la izquierda, de la lista que quieres que -## Perl 6 use para deducir (y podría incluir una clausura), y en la derecha, -## un valor o el predicado que dice cuando parar (o Whatever para una +## El operador secuencia es uno de la más poderosas características de +## Raku: Está compuesto, en la izquierda, de la lista que quieres que +## Raku use para deducir (y podría incluir una clausura), y en la derecha, +## un valor o el predicado que dice cuando parar (o Whatever para una ## lista infinita perezosa). my @list = 1, 2, 3 ... 10; # deducción básica -#my @list = 1, 3, 6 ... 10; # esto muere porque Perl 6 no puede deducir el final +#my @list = 1, 3, 6 ... 10; # esto muere porque Raku no puede deducir el final my @list = 1, 2, 3 ...^ 10; # como con rangos, puedes excluir el último elemento # (la iteración cuando el predicado iguala). my @list = 1, 3, 9 ... * > 30; # puedes usar un predicado @@ -1505,8 +1505,8 @@ my @fib = 1, 1, *+* ... *; # lista infinita perezosa de la serie fibonacci, my @fib = 1, 1, -> $a, $b { $a + $b } ... *; # (equivalene a lo de arriba) my @fib = 1, 1, { $^a + $^b } ... *; #(... también equivalene a lo de arriba) ## $a and $b siempre tomarán el valor anterior, queriendo decir que -## ellos comenzarán con $a = 1 y $b = 1 (valores que hemos asignado -## de antemano). Por lo tanto, $a = 1 y $b = 2 (resultado del anterior $a+$b), +## ellos comenzarán con $a = 1 y $b = 1 (valores que hemos asignado +## de antemano). Por lo tanto, $a = 1 y $b = 2 (resultado del anterior $a+$b), ## etc. say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55 @@ -1519,29 +1519,29 @@ say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55 ## Expresiones Regulares ```perl6 -## Estoy seguro que has estado esperando por esta parte. Bien, ahora que -## sabes algo acerca de Perl 6, podemos comenzar. Primeramente, tendrás -## que olvidarte acerca de "PCRE regexps" (perl-compatible regexps) +## Estoy seguro que has estado esperando por esta parte. Bien, ahora que +## sabes algo acerca de Raku, podemos comenzar. Primeramente, tendrás +## que olvidarte acerca de "PCRE regexps" (perl-compatible regexps) ## (expresiones regulares compatible de perl). ## ## IMPORTANTE: No salte esto porque ya sabes acerca de PCRE. Son totalmente -## distintos. Algunas cosas son las mismas (como `?`, `+`, y `*`) pero +## distintos. Algunas cosas son las mismas (como `?`, `+`, y `*`) pero ## algunas veces la semántica cambia (`|`). Asegúrate de leer esto ## cuidadosamente porque podrías trospezarte sino lo haces. ## -## Perl 6 tiene muchas características relacionadas con RegExps. Después de +## Raku tiene muchas características relacionadas con RegExps. Después de ## todo, Rakudo se parsea a si mismo. Primero vamos a estudiar la sintaxis ## por si misma, después hablaremos acerca de gramáticas (parecido a PEG), -## las diferencias entre los declaradores `token`, `regex`, y `rule` y +## las diferencias entre los declaradores `token`, `regex`, y `rule` y ## mucho más. -## Nota aparte: Todavía tienes acceso a los regexes PCRE usando el +## Nota aparte: Todavía tienes acceso a los regexes PCRE usando el ## mofificador `:P5` (Sin embargo, no lo discutiremos en este tutorial). ## -## En esencia, Perl 6 implementa PEG ("Parsing Expression Grammars") +## En esencia, Raku implementa PEG ("Parsing Expression Grammars") ## ("Parseado de Expresiones de Gramáticas") nativamente. El orden jerárquico -## para los parseos ambiguos es determinado por un examen multi-nivel de +## para los parseos ambiguos es determinado por un examen multi-nivel de ## desempate: -## - La coincidencia de token más larga. `foo\s+` le gana a `foo` +## - La coincidencia de token más larga. `foo\s+` le gana a `foo` ## (por 2 o más posiciones) ## - El prefijo literal más largo. `food\w*` le gana a `foo\w*` (por 1) ## - Declaración desde la gramática más derivada a la menos derivada @@ -1550,48 +1550,48 @@ say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55 say so 'a' ~~ /a/; #=> True say so 'a' ~~ / a /; #=> True # ¡Más legible con los espacios! -## Nota al lector (del traductor): +## Nota al lector (del traductor): ## Como pudiste haber notado, he decidido traducir "match" y sus diferentes -## formas verbales como "coincidir" y sus diferentes formas. Cuando digo que +## formas verbales como "coincidir" y sus diferentes formas. Cuando digo que ## un regex (o regexp) coincide con cierto texto, me refiero a que el regex ## describe cierto patrón dentro del texto. Por ejemplo, el regex "cencia" -## coincide con el texto "reminiscencia", lo que significa que dentro del +## coincide con el texto "reminiscencia", lo que significa que dentro del ## texto aparece ese patrón de caracteres (una `c`, seguida de una `e`, -## (seguida de una `n`, etc.) +## (seguida de una `n`, etc.) -## En todos nuestros ejemplos, vamos a usar el operador de -## "coincidencia inteligente" contra una expresión regular ("regexp" or +## En todos nuestros ejemplos, vamos a usar el operador de +## "coincidencia inteligente" contra una expresión regular ("regexp" or ## "regex" de aquí en adelante). Estamos convirtiendo el resultado usando `so`, ## pero en efecto, está devolviendo un objeto Match. Ellos saben como responder -## a la indexación de lista, indexación de hash, y devolver la cadena de +## a la indexación de lista, indexación de hash, y devolver la cadena de ## texto coincidente. -## Los resultados de la coincidencia están disponible como `$/` (en +## Los resultados de la coincidencia están disponible como `$/` (en ## ámbito implícito lexical). También puedes usar las variables de captura ## las cuales comienzan con 0: ## `$0`, `$1', `$2`... ## -## Nota que `~~` no hace un chequeo de inicio/final (es decir, +## Nota que `~~` no hace un chequeo de inicio/final (es decir, ## el regexp puede coincider con solo un carácter de la cadena de texto). ## Explicaremos luego como hacerlo. -## En Perl 6, puedes tener un carácter alfanumérico como un literal, +## En Raku, puedes tener un carácter alfanumérico como un literal, ## todo lo demás debe escaparse usando una barra invertida o comillas. -say so 'a|b' ~~ / a '|' b /; # `True`. No sería lo mismo si no se escapara `|` +say so 'a|b' ~~ / a '|' b /; # `True`. No sería lo mismo si no se escapara `|` say so 'a|b' ~~ / a \| b /; # `True`. Otra forma de escaparlo -## El espacio en blanco actualmente no se significa nada en un regexp, +## El espacio en blanco actualmente no se significa nada en un regexp, ## a menos que uses el adverbio `:s` (`:sigspace`, espacio significante). say so 'a b c' ~~ / a b c /; #=> `False`. Espacio no significa nada aquí. say so 'a b c' ~~ /:s a b c /; #=> `True`. Agregamos el modificador `:s` aquí. -## Si usamos solo un espacio entre cadenas de texto en un regexp, Perl 6 +## Si usamos solo un espacio entre cadenas de texto en un regexp, Raku ## nos advertirá: say so 'a b c' ~~ / a b c /; #=> 'False' # Espacio no significa nada aquí. ## Por favor usa comillas o el modificador :s (:sigspace) para suprimir -## esta advertencia, omitir el espacio, o cambiar el espaciamiento. Para -## arreglar esto y hacer los espacios menos ambiguos, usa por lo menos +## esta advertencia, omitir el espacio, o cambiar el espaciamiento. Para +## arreglar esto y hacer los espacios menos ambiguos, usa por lo menos ## dos espacios entre las cadenas de texto o usa el adverbio `:s`. -## Como vimos anteriormente, podemos incorporar `:s` dentro de los +## Como vimos anteriormente, podemos incorporar `:s` dentro de los ## delimitadores de barras. También podemos ponerlos fuera de ellos si ## especificamos `m` for `match` (coincidencia): say so 'a b c' ~~ m:s/a b c/; #=> `True` @@ -1603,7 +1603,7 @@ say so 'abc' ~~ m[a b c]; #=> `True` ## minúsculas y mayúsculas: say so 'ABC' ~~ m:i{a b c}; #=> `True` -## Sin embargo, es importante para como los modificadores son aplicados +## Sin embargo, es importante para como los modificadores son aplicados ## (lo cual verás más abajo)... ## Cuantificando - `?`, `+`, `*` y `**`. @@ -1612,7 +1612,7 @@ so 'ac' ~~ / a b c /; # `False` so 'ac' ~~ / a b? c /; # `True`, la "b" coincidió (apareció) 0 veces. so 'abc' ~~ / a b? c /; # `True`, la "b" coincidió 1 vez. -## ... Como debes saber, espacio en blancos son importante porque +## ... Como debes saber, espacio en blancos son importante porque ## determinan en que parte del regexp es el objetivo del modificador: so 'def' ~~ / a b c? /; # `False`. Solamente la `c` es opcional so 'def' ~~ / a b? c /; # `False`. Espacio en blanco no es significante @@ -1642,7 +1642,7 @@ so 'abbbbbbc' ~~ / a b**3..* c /; # `True` (rangos infinitos no son un problem ## - `<[]>` - Clases de carácteres ## Las clases de carácteres son equivalentes a las clases `[]` de PCRE, -## pero usan una sintaxis de Perl 6: +## pero usan una sintaxis de Raku: say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa' ## Puedes usar rangos: @@ -1663,7 +1663,7 @@ so 'foo' ~~ / <-[ f o ]> + /; # False ## ... y componerlos: so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; # False (cualquier letra excepto f y o) so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; # True (no letra excepto f and o) -so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (el signo + no reemplaza la +so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (el signo + no reemplaza la # parte de la izquierda) ``` @@ -1671,7 +1671,7 @@ so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (el signo + no reemplaza la ```perl6 ## Grupo: Puedes agrupar partes de tu regexp con `[]`. -## Estos grupos *no son* capturados (como con `(?:)` en PCRE). +## Estos grupos *no son* capturados (como con `(?:)` en PCRE). so 'abc' ~~ / a [ b ] c /; # `True`. El agrupamiento no hace casi nada so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /; ## La línea anterior returna `True`. @@ -1680,15 +1680,15 @@ so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /; ## Pero esto no va demasiado lejos, porque no podemos actualmente obtener ## devuelta el patrón que coincidió. -## Captura: Podemos actualmente *capturar* los resultados del regexp, +## Captura: Podemos actualmente *capturar* los resultados del regexp, ## usando paréntesis. so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # `True`. (usando `so` # aquí, `$/` más abajo) -## Ok. Comenzando con las explicaciones de grupos. Como dijimos, +## Ok. Comenzando con las explicaciones de grupos. Como dijimos, ### nuestra objeto `Match` está disponible en la variable `$/`: -say $/; # Imprimirá algo extraño (explicaremos luego) o - # "Nil" si nada coincidió +say $/; # Imprimirá algo extraño (explicaremos luego) o + # "Nil" si nada coincidió ## Como dijimos anteriormente, un objeto Match tiene indexación de array: say $/[0]; #=> 「ABC」 「ABC」 @@ -1696,15 +1696,15 @@ say $/[0]; #=> 「ABC」 「ABC」 # Aquí, tenemos un array de ellos. say $0; # Lo mismo que lo anterior. -## Nuestra captura es `$0` porque es la primera y única captura en el -## regexp. Podrías estarte preguntando porque un array y la respuesta es +## Nuestra captura es `$0` porque es la primera y única captura en el +## regexp. Podrías estarte preguntando porque un array y la respuesta es ## simple: Algunas capturas (indezadas usando `$0`, `$/[0]` o una nombrada) ## será un array si y solo si puedes tener más de un elemento. ## (Así que, con `*`, `+` y `**` (cualquiera los operandos), pero no con `?`). ## Usemos algunos ejemplos para ver como funciona: ## Nota: Pusimos A B C entre comillas para demostrar que el espacio en blanco -## entre ellos no es significante. Si queremos que el espacio en blanco +## entre ellos no es significante. Si queremos que el espacio en blanco ## *sea* significante, podemos utilizar el modificador `:sigspace`. so 'fooABCbar' ~~ / foo ( "A" "B" "C" )? bar /; # `True` say $/[0]; #=> 「ABC」 @@ -1718,22 +1718,22 @@ say $0.WHAT; #=> (Array) # Un cuantificador específico siempre capturará un Array, # puede ser un rango o un valor específico (hasta 1). -## Las capturas son indezadas por anidación. Esto quiere decir que un grupo -## dentro de un grup estará anidado dentro de su grupo padre: `$/[0][0]`, +## Las capturas son indezadas por anidación. Esto quiere decir que un grupo +## dentro de un grup estará anidado dentro de su grupo padre: `$/[0][0]`, ## para este código: 'hello-~-world' ~~ / ( 'hello' ( <[ \- \~ ]> + ) ) 'world' /; say $/[0].Str; #=> hello~ say $/[0][0].Str; #=> ~ -## Esto se origina de un hecho bien simple: `$/` no contiene cadenas de -## texto, números enteros o arrays sino que solo contiene objetos Match. -## Estos objetos contienen los métodos `.list`, `.hash` y `.Str`. (Pero -## también puedes usar `match<llave>` para accesar un hash y `match[indice]` +## Esto se origina de un hecho bien simple: `$/` no contiene cadenas de +## texto, números enteros o arrays sino que solo contiene objetos Match. +## Estos objetos contienen los métodos `.list`, `.hash` y `.Str`. (Pero +## también puedes usar `match<llave>` para accesar un hash y `match[indice]` ## para accesar un array. say $/[0].list.perl; #=> (Match.new(...),).list # Podemos ver que es una lista de objetos Match. - # Estos contienen un montón de información: dónde la - # coincidencia comenzó o terminó, el "ast" + # Estos contienen un montón de información: dónde la + # coincidencia comenzó o terminó, el "ast" # (chequea las acciones más abajo), etc. # Verás capturas nombradas más abajo con las gramáticas. @@ -1743,9 +1743,9 @@ so 'abc' ~~ / a [ b | y ] c /; # `True`. o "b" o "y". so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviamente suficiente... ## La diferencia entre este `|` y el otro al que estás acustombrado es LTM. -## LTM significa "Longest Token Matching", traducido libremente como +## LTM significa "Longest Token Matching", traducido libremente como ## "Coincidencia de Token Más Larga". Esto significa que el motor ("engine") -## siempre intentará coindidir tanto como sea posible en la cadena de texto. +## siempre intentará coindidir tanto como sea posible en la cadena de texto. ## Básicamente, intentará el patrón más largo que concuerde con el regexp. 'foo' ~~ / fo | foo /; # `foo` porque es más largo. ## Para decidir cual parte es la "más larga", primero separa el regex en @@ -1759,19 +1759,19 @@ so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviamente suficiente... ## anteriores, aserciones de código, y otras cosas que tradicionalmente no pueden ## ser representadas por regexes normales. ## -## Entonces, todas las alternativas se intentan al mismo tiempo, y la +## Entonces, todas las alternativas se intentan al mismo tiempo, y la ## más larga gana. ## Ejemplos: ## DECLARATIVO | PROCEDIMENTAL / 'foo' \d+ [ <subrule1> || <subrule2> ] /; ## DECLARATIVO (grupos anidados no son un problema) / \s* [ \w & b ] [ c | d ] /; -## Sin embargo, las clausuras y la recursión (de regexes nombrados) +## Sin embargo, las clausuras y la recursión (de regexes nombrados) ## son procedimentales. ## ... Hay más reglas complicadas, como la especifidad (los literales ganan ## son las clases de caracteres) + -## Nota: la primera coincidencia `or` todavía existen, pero ahora se +## Nota: la primera coincidencia `or` todavía existen, pero ahora se ## deletrea `||` 'foo' ~~ / fo || foo /; # `fo` ahora. ``` @@ -1779,19 +1779,19 @@ so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviamente suficiente... ## Extra: la subrutina MAIN ```perl6 -## La subrutina `MAIN` se invoca cuando tu ejecuta un archivo de Perl 6 -## directamente. Es realmente poderosa porque Perl 6 actualmente parsea -## los argumentos y los pasas a la subrutina. También maneja argumentos +## La subrutina `MAIN` se invoca cuando tu ejecuta un archivo de Raku +## directamente. Es realmente poderosa porque Raku actualmente parsea +## los argumentos y los pasas a la subrutina. También maneja argumentos ## nombrados (`--foo`) y hasta autogenerará un `--help`. sub MAIN($nombre) { say "¡Hola, $nombre!" } ## Esto produce: -## $ perl6 cli.pl +## $ raku cli.pl ## Uso: ## t.pl <nombre> -## Y dado que una subrutina regular en Perl 6, puedes tener múltiples +## Y dado que una subrutina regular en Raku, puedes tener múltiples ## despachos: -## (usando un "Bool" por un argumento nombrado para que podamos hacer +## (usando un "Bool" por un argumento nombrado para que podamos hacer ## `--replace` a cambio de `--replace=1`) subset File of Str where *.IO.d; # convierte a un objeto IO para chequear si # un archivo existe @@ -1800,7 +1800,7 @@ multi MAIN('add', $key, $value, Bool :$replace) { ... } multi MAIN('remove', $key) { ... } multi MAIN('import', File, Str :$as) { ... } # omitiendo parámetros nombrados ## Esto produce: -## $ perl6 cli.pl +## $ raku cli.pl ## Uso: ## t.pl [--replace] add <key> <value> ## t.pl remove <key> @@ -1814,7 +1814,7 @@ multi MAIN('import', File, Str :$as) { ... } # omitiendo parámetros nombrados ### Lista de cosas ```perl6 -## Consideramos que por ahora ya sabes lo básico de Perl 6. +## Consideramos que por ahora ya sabes lo básico de Raku. ## Esta sección es solo para listar algunas operaciones comunes ## las cuales no están en la "parte principal" del tutorial. @@ -1825,13 +1825,13 @@ multi MAIN('import', File, Str :$as) { ... } # omitiendo parámetros nombrados ## (los cuales representan los números -1, 0 o +1). 1 <=> 4; # comparación de orden para caracteres numéricos 'a' leg 'b'; # comparación de orden para cadenas de texto -$obj eqv $obj2; # comparación de orden usando la semántica eqv +$obj eqv $obj2; # comparación de orden usando la semántica eqv ## * Ordenación genérica 3 before 4; # True 'b' after 'a'; # True -## * Operador (por defecto) de circuito corto +## * Operador (por defecto) de circuito corto ## Al igual que `or` y `||`, pero devuelve el primer valor *defined* ## (definido): say Any // Nil // 0 // 5; #=> 0 @@ -1843,9 +1843,9 @@ say True ^^ False; #=> True ## * Flip Flop ## Los operadores flip flop (`ff` y `fff`, equivalente a `..`/`...` en P5) ## son operadores que toman dos predicados para evalualarlos: -## Ellos son `False` hasta que su lado izquierdo devuelve `True`, entonces +## Ellos son `False` hasta que su lado izquierdo devuelve `True`, entonces ## son `True` hasta que su lado derecho devuelve `True`. -## Como los rangos, tu puedes excluir la iteración cuando se convierte en +## Como los rangos, tu puedes excluir la iteración cuando se convierte en ## `True`/`False` usando `^` en cualquier lado. ## Comencemos con un ejemplo: for <well met young hero we shall meet later> { @@ -1861,25 +1861,25 @@ for <well met young hero we shall meet later> { } ## Esto imprimirá "young hero we shall meet" (exluyendo "met"): ## el flip-flop comenzará devolviendo `True` cuando primero encuentra "met" -## (pero no returnará `False` por "met" dabido al `^` al frente de `ff`), +## (pero no returnará `False` por "met" dabido al `^` al frente de `ff`), ## hasta que ve "meet", lo cual es cuando comenzará devolviendo `False`. ## La diferencia entre `ff` (al estilo de awk) y `fff` (al estilo de sed) -## es que `ff` probará su lado derecho cuando su lado izquierdo cambia +## es que `ff` probará su lado derecho cuando su lado izquierdo cambia ## a `True`, y puede returnar a `False` inmediamente (*excepto* que será -## `True` por la iteración con la cual coincidió). Por lo contrario, -## `fff` esperará por la próxima iteración para intentar su lado +## `True` por la iteración con la cual coincidió). Por lo contrario, +## `fff` esperará por la próxima iteración para intentar su lado ## derecho, una vez que su lado izquierdo ha cambiado: .say if 'B' ff 'B' for <A B C B A>; #=> B B # porque el lado derecho se puso a prueba # directamente (y returnó `True`). # Las "B"s se imprimen dadó que coincidió - # en ese momento (returnó a `False` + # en ese momento (returnó a `False` # inmediatamente). .say if 'B' fff 'B' for <A B C B A>; #=> B C B # El lado derecho no se puso a prueba # hasta que `$_` se convirtió en "C" - # (y por lo tanto no coincidió + # (y por lo tanto no coincidió # inmediamente). ## Un flip-flop puede cambiar estado cuantas veces se necesite: @@ -1901,35 +1901,35 @@ for (1, 3, 60, 3, 40, 60) { # Nota: los paréntesis son superfluos aquí ## que no pasará la primera vez: for <a b c> { .say if * ^ff *; # el flip-flop es `True` y nunca returna a `False`, - # pero el `^` lo hace *que no se ejecute* en la + # pero el `^` lo hace *que no se ejecute* en la # primera iteración #=> b c } -## - `===` es la identidad de valor y usa `.WHICH` +## - `===` es la identidad de valor y usa `.WHICH` ## en los objetos para compararlos. -## - `=:=` es la identidad de contenedor y usa `VAR()` +## - `=:=` es la identidad de contenedor y usa `VAR()` ## en los objetos para compararlos. ``` Si quieres ir más allá de lo que se muestra aquí, puedes: - - Leer la [documentación de Perl 6](https://docs.perl6.org/). Esto es un recurso - grandioso acerca de Perl 6. Si estás buscando por algo en particular, usa la + - Leer la [documentación de Raku](https://docs.raku.org/). Esto es un recurso + grandioso acerca de Raku. Si estás buscando por algo en particular, usa la barra de búsquedas. Esto te dará un menú de todas las páginas concernientes a tu término de búsqueda (¡Es mucho mejor que usar Google para encontrar - documentos acerca de Perl 6!) - - Leer el [Perl 6 Advent Calendar](http://perl6advent.wordpress.com/). Este es - un gran recurso de fragmentos de código de Perl 6 y explicaciones. Si la documentación + documentos acerca de Raku!) + - Leer el [Raku Advent Calendar](https://rakuadventcalendar.wordpress.com/). Este es + un gran recurso de fragmentos de código de Raku y explicaciones. Si la documentación no describe algo lo suficientemente bien, puedes encontrar información más detallada aquí. Esta información puede ser un poquito más antigua pero hay muchos ejemplos y - explicaciones. Las publicaciones fueron suspendidas al final del 2015 cuando - el lenguaje fue declarado estable y Perl 6.c fue lanzado. - - Unirte a `#perl6` en `irc.freenode.net`. Las personas aquí son siempre serviciales. - - Chequear la [fuente de las funciones y clases de Perl 6 - ](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo está principalmente - escrito en Perl 6 (con mucho de NQP, "Not Quite Perl" ("No Perl Todavía"), un - subconjunto de Perl 6 que es más fácil de implementar y optimizar). - - Leer [documentos acerca del diseño del lenguaje](http://design.perl6.org). + explicaciones. Las publicaciones fueron suspendidas al final del 2015 cuando + el lenguaje fue declarado estable y Raku.c fue lanzado. + - Unirte a `#raku` en `irc.freenode.net`. Las personas aquí son siempre serviciales. + - Chequear la [fuente de las funciones y clases de Raku + ](https://github.com/rakudo/rakudo/tree/master/src/core.c). Rakudo está principalmente + escrito en Raku (con mucho de NQP, "Not Quite Perl" ("No Perl Todavía"), un + subconjunto de Raku que es más fácil de implementar y optimizar). + - Leer [documentos acerca del diseño del lenguaje](http://design.raku.org). Estos explican P6 desde la perspectiva de un implementador, lo cual es bastante interesante. diff --git a/es-es/ruby-es.html.markdown b/es-es/ruby-es.html.markdown index e3e43c18..8b703df1 100644 --- a/es-es/ruby-es.html.markdown +++ b/es-es/ruby-es.html.markdown @@ -89,10 +89,10 @@ true || false #=> true # Estos son usados como constructores controladores de flujo que encadenan # sentencias hasta que una de ellas retorne verdadero o falso -# `has_otra_cosa` solo se llama si `has_algo` retorna verdadero. -has_algo() and has_otra_cosa() -# `registra_error` solo se llama si `has_algo` falla -has_algo() or registra_error() +# `haz_otra_cosa` solo se llama si `haz_algo` retorna verdadero. +haz_algo() and haz_otra_cosa() +# `registra_error` solo se llama si `haz_algo` falla +haz_algo() or registra_error() # Los strings son objetos @@ -139,7 +139,7 @@ status == :pendiente #=> true status == 'pendiente' #=> false -status == :aprovado #=> false +status == :aprobado #=> false # Arreglos diff --git a/es-es/rust-es.html.markdown b/es-es/rust-es.html.markdown index b43cb815..b0a3873c 100644 --- a/es-es/rust-es.html.markdown +++ b/es-es/rust-es.html.markdown @@ -1,5 +1,5 @@ --- -language: rust +language: Rust contributors: - ["P1start", "http://p1start.github.io/"] translators: @@ -225,7 +225,7 @@ fn main() { // bucles `for` let array = [1, 2, 3]; - for i in array.iter() { + for i in array { println!("{}", i); } diff --git a/es-es/self-es.html.markdown b/es-es/self-es.html.markdown index 11972214..1f985215 100644 --- a/es-es/self-es.html.markdown +++ b/es-es/self-es.html.markdown @@ -116,6 +116,7 @@ Las expresiones múltiples son separadas por un punto. ^ retorna inmediatamente. ``` Los bloques son ejecutados al enviales el mensaje 'value' y son inherentes (delegados a) sus contextos: + ``` "returns 0" [|x| diff --git a/es-es/sql-es.html.markdown b/es-es/sql-es.html.markdown new file mode 100644 index 00000000..1ee0d454 --- /dev/null +++ b/es-es/sql-es.html.markdown @@ -0,0 +1,115 @@ +--- +language: SQL +filename: learnsql-es.sql +contributors: + - ["Bob DuCharme", "http://bobdc.com/"] +translators: + - ["FedeHC", "https://github.com/FedeHC"] +lang: es-es +--- + +El lenguaje de consulta estructurada (SQL en inglés) es un lenguaje estándar ISO para crear y trabajar con bases de datos almacenados en un conjunto de tablas. Las implementaciones generalmente añaden sus propias extensiones al lenguaje; [Comparación entre diferentes implementaciones de SQL](http://troels.arvin.dk/db/rdbms/) es una buena referencia sobre las diferencias entre distintos productos. + +Las implementaciones típicamente proveen de una línea de comandos donde uno puede introducir los comandos que se muestran aquí en forma interactiva, y también ofrecen una forma de ejecutar una serie de estos comandos almacenados en un archivo de script (mostrar que uno ha terminado con el prompt interactivo es un buen ejemplo de algo que no está estandarizado - la mayoría de las implementaciones de SQL soportan las palabras clave QUIT, EXIT, o ambas). + +Varios de estos comandos que sirven de ejemplo asumen que la [base de datos de empleados de muestra de MySQL](https://dev.mysql.com/doc/employee/en/) disponible en [github](https://github.com/datacharmer/test_db) ya ha sido cargada. Los archivos github son scripts de comandos, similares a los comandos que aparecen a continuación, que crean y cargan tablas de datos sobre los empleados de una empresa ficticia. La sintaxis para ejecutar estos scripts dependerá de la implementación de SQL que esté utilizando. Una aplicación que se ejecuta desde el prompt del sistema operativo suele ser lo habitual. + + +```sql +-- Los comentarios empiezan con dos guiones. Se termina cada comando con punto +-- y coma. + +-- SQL no distingue entre mayúsculas y minúsculas en palabras clave. Los +-- comandos de ejemplo que aquí se muestran siguen la convención de ser escritos +-- en mayúsculas porque hace más fácil distinguirlos de los nombres de las bases +-- de datos, de las tablas y de las columnas. + +-- A cont. se crea y se elimina una base de datos. Los nombres de la base de +-- datos y de la tabla son sensibles a mayúsculas y minúsculas. +CREATE DATABASE someDatabase; +DROP DATABASE someDatabase; + +-- Lista todas las bases de datos disponibles. +SHOW DATABASES; + +-- Usa una base de datos existente en particular. +USE employees; + +-- Selecciona todas las filas y las columnas de la tabla departments en la base +-- de datos actual. La actividad predeterminada es que el intérprete desplace +-- los resultados por la pantalla. +SELECT * FROM departments; + +-- Recupera todas las filas de la tabla departments, pero sólo las columnas +-- dept_no y dept_name. +-- Separar los comandos en varias líneas está permitido. +SELECT dept_no, + dept_name FROM departments; + +-- Obtiene todas las columnas de departments, pero se limita a 5 filas. +SELECT * FROM departments LIMIT 5; + +-- Obtiene los valores de la columna dept_name desde la tabla departments cuando +-- dept_name tiene como valor la subcadena 'en'. +SELECT dept_name FROM departments WHERE dept_name LIKE '%en%'; + +-- Recuperar todas las columnas de la tabla departments donde la columna +-- dept_name comienza con una 'S' y tiene exactamente 4 caracteres después +-- de ella. +SELECT * FROM departments WHERE dept_name LIKE 'S____'; + +-- Selecciona los valores de los títulos de la tabla titles, pero no muestra +-- duplicados. +SELECT DISTINCT title FROM titles; + +-- Igual que el anterior, pero ordenado por los valores de title (se distingue +-- entre mayúsculas y minúsculas). +SELECT DISTINCT title FROM titles ORDER BY title; + +-- Muestra el número de filas de la tabla departments. +SELECT COUNT(*) FROM departments; + +-- Muestra el número de filas en la tabla departments que contiene 'en' como +-- subcadena en la columna dept_name. +SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%'; + +-- Una unión (JOIN) de información desde varias tablas: la tabla titles muestra +-- quién tiene qué títulos de trabajo, según sus números de empleados, y desde +-- qué fecha hasta qué fecha. Se obtiene esta información, pero en lugar del +-- número de empleado se utiliza el mismo como una referencia cruzada a la +-- tabla employee para obtener el nombre y apellido de cada empleado (y se +-- limita los resultados a 10 filas). +SELECT employees.first_name, employees.last_name, + titles.title, titles.from_date, titles.to_date +FROM titles INNER JOIN employees ON + employees.emp_no = titles.emp_no LIMIT 10; + +-- Se enumera todas las tablas de todas las bases de datos. Las implementaciones +-- típicamente proveen sus propios comandos para hacer esto con la base de datos +-- actualmente en uso. +SELECT * FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_TYPE='BASE TABLE'; + +-- Crear una tabla llamada tablename1, con las dos columnas mostradas, a partir +-- de la base de datos en uso. Hay muchas otras opciones disponibles para la +-- forma en que se especifican las columnas, como por ej. sus tipos de datos. +CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20)); + +-- Insertar una fila de datos en la tabla tablename1. Se asume que la tabla ha +-- sido definida para aceptar estos valores como aptos. +INSERT INTO tablename1 VALUES('Richard','Mutt'); + +-- En tablename1, se cambia el valor de fname a 'John' para todas las filas que +-- tengan un valor en lname igual a 'Mutt'. +UPDATE tablename1 SET fname='John' WHERE lname='Mutt'; + +-- Se borra las filas de la tabla tablename1 donde el valor de lname comience +-- con 'M'. +DELETE FROM tablename1 WHERE lname like 'M%'; + +-- Se borra todas las filas de la tabla tablename1, dejando la tabla vacía. +DELETE FROM tablename1; + +-- Se elimina toda la tabla tablename1 por completo. +DROP TABLE tablename1; +``` diff --git a/es-es/swift-es.html.markdown b/es-es/swift-es.html.markdown index 22e3c532..60af1913 100644 --- a/es-es/swift-es.html.markdown +++ b/es-es/swift-es.html.markdown @@ -11,7 +11,7 @@ lang: es-es filename: learnswift-es.swift --- -Swift es un lenguaje de programación para el desarrollo en iOS y OS X creado +Swift es un lenguaje de programación para el desarrollo en iOS y macOS creado por Apple. Diseñado para coexistir con Objective-C y ser más resistente contra el código erroneo, Swift fue introducido en el 2014 en el WWDC, la conferencia de desarrolladores de Apple. diff --git a/es-es/typescript-es.html.markdown b/es-es/typescript-es.html.markdown index c42da4a4..fbe1290b 100644 --- a/es-es/typescript-es.html.markdown +++ b/es-es/typescript-es.html.markdown @@ -12,7 +12,7 @@ TypeScript es un lenguaje cuyo objetivo es facilitar el desarrollo de aplicacion TypeScript añade conceptos comunes como clases, módulos, interfaces, genéricos y (opcionalmente) tipeo estático a JavaScript. Es un superset de JavaScript: todo el código JavaScript es código válido en TypeScript de manera que se puede integrar fácilmente a cualquier proyecto . El compilador TypeScript emite JavaScript. -Este artículo se enfocará solo en la sintáxis extra de TypeScript, y no en [JavaScript] (../javascript/). +Este artículo se enfocará solo en la sintáxis extra de TypeScript, y no en [JavaScript] (../javascript-es/). Para probar el compilador de TypeScript, diríjase al [Área de Pruebas] (http://www.typescriptlang.org/Playground) donde podrá tipear código, y ver como se auto-completa al tiempo que ve el código emitido JavaScript. diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown index c677c20f..fb0b1d27 100644 --- a/es-es/visualbasic-es.html.markdown +++ b/es-es/visualbasic-es.html.markdown @@ -8,7 +8,7 @@ filename: learnvisualbasic-es.vb lang: es-es --- -``` +```visualbasic Module Module1 Sub Main() diff --git a/es-es/wolfram-es.html.markdown b/es-es/wolfram-es.html.markdown index 44ec9e09..6858c286 100644 --- a/es-es/wolfram-es.html.markdown +++ b/es-es/wolfram-es.html.markdown @@ -15,7 +15,7 @@ El lenguaje de Wolfram tiene varias interfaces: El código de este ejemplo se puede escribir en cualquier interfaz y editarlo con Wolfram Workbench. Cargar directamente en Matematica puede resultar incómodo porque el archivo no contiene información de formato de celda (lo que haría que el archivo sea un desastre enorme para ser leído como texto) - puede ser visto / editado pero tal vez requerira algún ajuste. -``` +```mathematica (* Esto es un comentario *) (* En Mathematica en lugar de utilizar estos comentarios, puede crear una celda de texto diff --git a/es-es/yaml-es.html.markdown b/es-es/yaml-es.html.markdown index cd3143fb..582fa60e 100644 --- a/es-es/yaml-es.html.markdown +++ b/es-es/yaml-es.html.markdown @@ -3,7 +3,7 @@ language: yaml lang: es-es filename: learnyaml-es.yaml contributors: - - ["Adam Brenecki", "https://github.com/adambrenecki"] + - ["Leigh Brenecki", "https://github.com/adambrenecki"] - ["Everardo Medina","https://github.com/everblut"] translators: - ["Daniel Zendejas","https://github.com/DanielZendejas"] |