diff options
Diffstat (limited to 'es-es')
-rw-r--r-- | es-es/amd-es.html.markdown | 214 | ||||
-rw-r--r-- | es-es/bf-es.html.markdown (renamed from es-es/brainfuck-es.html.markdown) | 20 | ||||
-rw-r--r-- | es-es/forth-es.html.markdown | 226 | ||||
-rw-r--r-- | es-es/git-es.html.markdown | 14 | ||||
-rw-r--r-- | es-es/hack-es.html.markdown | 307 | ||||
-rw-r--r-- | es-es/javascript-es.html.markdown | 20 | ||||
-rw-r--r-- | es-es/json-es.html.markdown | 16 | ||||
-rw-r--r-- | es-es/latex-es.html.markdown | 213 | ||||
-rw-r--r-- | es-es/markdown-es.html.markdown | 16 | ||||
-rw-r--r-- | es-es/objective-c-es.html.markdown | 851 | ||||
-rw-r--r-- | es-es/php-es.html.markdown | 825 | ||||
-rw-r--r-- | es-es/python3-es.html.markdown | 8 | ||||
-rw-r--r-- | es-es/r-es.html.markdown | 717 | ||||
-rw-r--r-- | es-es/ruby-es.html.markdown | 253 | ||||
-rw-r--r-- | es-es/rust-es.html.markdown | 324 | ||||
-rw-r--r-- | es-es/swift-es.html.markdown | 596 | ||||
-rw-r--r-- | es-es/tmux-es.html.markdown | 253 | ||||
-rw-r--r-- | es-es/yaml-es.html.markdown | 189 |
18 files changed, 4931 insertions, 131 deletions
diff --git a/es-es/amd-es.html.markdown b/es-es/amd-es.html.markdown new file mode 100644 index 00000000..7a59ddd6 --- /dev/null +++ b/es-es/amd-es.html.markdown @@ -0,0 +1,214 @@ +--- + +category: tool +tool: amd +contributors: + - ["Frederik Ring", "https://github.com/m90"] + +translators: + - ["Damaso Sanoja", "https://github.com/damasosanoja"] +filename: learnamd-es.js +lang: es-es +--- + +## Iniciando con AMD + +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: +// `define(id?, dependencias?, fábrica)` define un módulo +// `require(dependencias, callback)` importa un conjunto de dependencias y +// las consume al invocar el callback + +// Comencemos usando define para definir un nuevo módulo +// que no posee dependencias. Lo haremos enviando un nombre +// y una función fábrica para definirla: +define('awesomeAMD', function(){ + var isAMDAwesome = function(){ + return true; + }; + // El valor que regresa la función fábrica del módulo será + // lo que los otros módulos o llamados require recibirán cuando + // soliciten nuestro módulo `awesomeAMD`. + // El valor exportado puede ser cualquier cosa, funciones (constructores), + // objetos, primitivos, incluso indefinidos (aunque eso no ayuda mucho). + return isAMDAwesome; +}); + +// Ahora definamos otro módulo que dependa de nuestro módulo `awesomeAMD`. +// Observe que ahora hay un argumento adicional que define +// las dependencias de nuestro módulo: +define('loudmouth', ['awesomeAMD'], function(awesomeAMD){ + // las dependencias serán enviadas a los argumentos de la fábrica + // en el orden que sean especificadas + var tellEveryone = function(){ + if (awesomeAMD()){ + alert('This is sOoOo rad!'); + } else { + alert('Pretty dull, isn\'t it?'); + } + }; + return tellEveryone; +}); + +// Como ya sabemos utilizar define usemos ahora `require` para poner en marcha +// nuestro programa. La firma de `require` es `(arrayOfDependencies, callback)`. +require(['loudmouth'], function(loudmouth){ + loudmouth(); +}); + +// Para hacer que este tutorial corra código, vamos a implementar una +// versión muy básica (no-asíncrona) de AMD justo aquí: +function define(name, deps, factory){ + // observa como son manejados los módulos sin dependencias + define[name] = require(factory ? deps : [], factory || deps); +} + +function require(deps, callback){ + var args = []; + // primero recuperemos todas las dependencias que necesita + // el llamado require + for (var i = 0; i < deps.length; i++){ + args[i] = define[deps[i]]; + } + // satisfacer todas las dependencias del callback + return callback.apply(null, args); +} +// puedes ver este código en acción aquí: http://jsfiddle.net/qap949pd/ +``` + +### Uso en el mundo real con require.js + +En contraste con el ejemplo introductorio, `require.js` (la librería AMD más popular) implementa la **A** de **AMD**, permitiéndote cargar los módulos y sus dependencias asincrónicamente via XHR: + +```javascript +/* file: app/main.js */ +require(['modules/someClass'], function(SomeClass){ + // el callback es diferido hasta que la dependencia sea cargada + var thing = new SomeClass(); +}); +console.log('So here we are, waiting!'); // esto correrá primero +``` + +Por convención, usualmente guardas un módulo en un fichero. `require.js` puede resolver los nombres de los módulos basados en rutas de archivo, de forma que no tienes que nombrar tus módulos, simplemente referenciarlos usando su ubicación. En el ejemplo `someClass` asumimos que se ubica en la carpeta `modules`, relativa a tu `baseUrl` configurada: + +* app/ + * main.js + * modules/ + * someClass.js + * someHelpers.js + * ... + * daos/ + * things.js + * ... + +Esto significa que podemos definir `someClass` sin especificar su id de módulo: + +```javascript +/* file: app/modules/someClass.js */ +define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){ + // definición de módulo, por supuesto, ocurrirá también asincrónicamente + function SomeClass(){ + this.method = function(){/**/}; + // ... + } + return SomeClass; +}); +``` + +Para alterar el comportamiento del mapeo de ruta usa `requirejs.config(configObj)` en tu `main.js`: + +```javascript +/* file: main.js */ +requirejs.config({ + baseUrl : 'app', + paths : { + // también puedes cargar módulos desde otras ubicaciones + jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min', + coolLibFromBower : '../bower_components/cool-lib/coollib' + } +}); +require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){ + // un fichero `main` necesita llamar a require al menos una vez, + // de otra forma jamás correrá el código + 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 +<!DOCTYPE html> +<html> +<head> + <title>Cien etiquetas de script? Nunca más!</title> +</head> +<body> + <script src="require.js" data-main="app/main"></script> +</body> +</html> +``` + +### Optimizar todo un proyecto usando r.js + +Muchas personas prefieren usar AMD para la organización del código durante el desarrollo, pero quieren enviar para producción un solo fichero en vez de ejecutar cientos de XHRs en las cargas de página. + +`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 */ +({ + name : 'main', // nombre del punto de entrada + out : 'main-built.js', // nombre del fichero donde se escribirá la salida + baseUrl : 'app', + paths : { + // `empty:` le dice a r.js que esto aún debe ser cargado desde el CDN, usando + // la ubicación especificada en `main.js` + jquery : 'empty:', + coolLibFromBower : '../bower_components/cool-lib/coollib' + } +}) +``` + +Para usar el fichero creado en producción, simplemente intercambia `data-main`: +```html +<script src="require.js" data-main="app/main-built"></script> +``` + +Un increíblemente detallado [resumen de opciones de generación](https://github.com/jrburke/r.js/blob/master/build/example.build.js) está disponible en el repositorio de GitHub. + +### Tópicos no cubiertos en este tutorial +* [Cargador de plugins / transformaciones](http://requirejs.org/docs/plugins.html) +* [Cargando y exportando estilos CommonJS](http://requirejs.org/docs/commonjs.html) +* [Configuración avanzada](http://requirejs.org/docs/api.html#config) +* [Configuración de Shim (cargando módulos no-AMD)](http://requirejs.org/docs/api.html#config-shim) +* [Cargando y optimizando CSS con require.js](http://requirejs.org/docs/optimization.html#onecss) +* [Usando almond.js para construcciones](https://github.com/jrburke/almond) + +### Otras lecturas: + +* [Especificaciones oficiales](https://github.com/amdjs/amdjs-api/wiki/AMD) +* [¿Por qué AMD?](http://requirejs.org/docs/whyamd.html) +* [Definición Universal de Módulos](https://github.com/umdjs/umd) + +### Implementaciones: + +* [require.js](http://requirejs.org) +* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/) +* [cujo.js](http://cujojs.com/) +* [curl.js](https://github.com/cujojs/curl) +* [lsjs](https://github.com/zazl/lsjs) +* [mmd](https://github.com/alexlawrence/mmd) diff --git a/es-es/brainfuck-es.html.markdown b/es-es/bf-es.html.markdown index e33d672d..c93b8c3a 100644 --- a/es-es/brainfuck-es.html.markdown +++ b/es-es/bf-es.html.markdown @@ -1,5 +1,5 @@ --- -language: brainfuck +language: bf contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] - ["Mathias Bynens", "http://mathiasbynens.be/"] @@ -9,8 +9,10 @@ lang: es-es --- Brainfuck (con mayúscula sólo al inicio de una oración) es un -lenguaje de programación mínimo, computacionalmente universal -en tamaño con sólo 8 comandos. +lenguaje de programación extremadamente pequeño, Turing completo con sólo 8 comandos. + +Puedes probar brainfuck en tu navegador con [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/). + ``` @@ -18,7 +20,7 @@ Cualquier caracter que no sea "><+-.,[]" (sin incluir las comillas) será ignorado. Brainfuck es representado por un arreglo de 30,000 celdas inicializadas -en cero y un apuntador en la celda actual. +en cero y un puntero apuntando la celda actual. Existen ocho comandos: @@ -26,7 +28,7 @@ Existen ocho comandos: - : Decrementa 1 al valor de la celda actual. > : Mueve el apuntador a la siguiente celda. (a la derecha) < : Mueve el apuntador a la celda anterior. (a la izquierda) -. : Imprime el valor en ASCII de la celda actual (i.e. 65 = 'A') +. : Imprime el valor en ASCII de la celda actual (p.e. 65 = 'A') , : Lee un caracter como input y lo escribe en la celda actual. [ : Si el valor en la celda actual es cero mueve el apuntador hasta el primer ']' que encuentre. Si no es cero sigue a la @@ -37,7 +39,7 @@ Existen ocho comandos: [ y ] forman un while. Obviamente, deben estar balanceados. -Ahora unos ejemplos de programas escritos con brainfuck. +Estos son algunos ejemplos de programas escritos con brainfuck. ++++++ [ > ++++++++++ < - ] > +++++ . @@ -63,7 +65,7 @@ Esto continúa hasta que la celda #1 contenga un cero. Cuando #1 contenga un cero la celda #2 tendrá el valor inicial de #1. Como este ciclo siempre terminara en la celda #1 nos movemos a la celda #2 e imprimimos (.). -Ten en mente que los espacios son sólo para fines de legibilidad. +Ten en cuenta que los espacios son sólo para fines de legibilidad. Es lo mismo escribir el ejemplo de arriba que esto: ,[>+<-]>. @@ -81,7 +83,7 @@ hasta la próxima vez. Para resolver este problema también incrementamos la celda #4 y luego copiamos la celda #4 a la celda #2. La celda #3 contiene el resultado. ``` -Y eso es brainfuck. ¿No tan difícil o sí? Como diversión, puedes escribir +Y eso es brainfuck. No es tan difícil, ¿verdad? Como diversión, puedes escribir tu propio intérprete de brainfuck o tu propio programa en brainfuck. El intérprete es relativamente sencillo de hacer, pero si eres masoquista, -intenta construir tu proprio intérprete de brainfuck... en brainfuck. +puedes intentar construir tu propio intérprete de brainfuck... en brainfuck. diff --git a/es-es/forth-es.html.markdown b/es-es/forth-es.html.markdown new file mode 100644 index 00000000..05dc0cc5 --- /dev/null +++ b/es-es/forth-es.html.markdown @@ -0,0 +1,226 @@ +--- +language: forth +contributors: + - ["Horse M.D.", "http://github.com/HorseMD/"] +translators: + - ["Zach Larsen", "http://zachariahlarsen.com/"] +lang: es-es +filename: learnforth-es.fs +--- + +Forth fue criado por Charles H. Moore en los 70s. Forth es un lenguaje imperativo, basado en pila y entorno de programación, siendo usado en proyectos como Open Firmware. También esta usado por NASA. + +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. + +``` +\ Este es un comentario +( Este es un comentario también pero solo esta usado cuando definiendo palabras. ) + +\ --------------------------------- Precursor ---------------------------------- + +\ Todo programación en Forth se hace manipulando el parámetro pila (mas +\ común se refiere como "el pila"). +5 2 3 56 76 23 65 \ ok + +\ estos números se añadieron al pila desde izquierda a derecho. +.s \ <7> 5 2 3 56 76 23 65 ok + +\ En Forth, todo es o una palabra o un numero. + +\ ------------------------------ Básico Aritmética ------------------------------ + +\ Aritmética (de hecho casi todas palabras que requieren datos) funciona manipulando datos +\ en el pila. +5 4 + \ ok + +\ `.` saca lo alto resulto desde el pila: +. \ 9 ok + +\ Mas ejemplos de aritmética: +6 7 * . \ 42 ok +1360 23 - . \ 1337 ok +12 12 / . \ 1 ok +13 2 mod . \ 1 ok + +99 negate . \ -99 ok +-99 abs . \ 99 ok +52 23 max . \ 52 ok +52 23 min . \ 23 ok + +\ ----------------------------- Pila Manipulación ----------------------------- + +\ Naturalmente, cuando trabajaremos con el pila, querremos algunos metidos útiles: + +3 dup - \ duplicar el primero articulo (1ra ahora igual a 2da): 3 - 3 +2 5 swap / \ intercambiar la primera con la segunda elemento: 5 / 2 +6 4 5 rot .s \ rotar los tres primero elementos: 4 5 6 +4 0 drop 2 / \ sacar el primero articulo (no imprima a la pantalla): 4 / 2 +1 2 3 nip .s \ sacar el segundo articulo (similar a drop): 1 3 + +\ ---------------------- Mas Avanzado Pila Manipulación ---------------------- + +1 2 3 4 tuck \ duplicar el primero articulo en el segundo hueco: 1 2 4 3 4 ok +1 2 3 4 over \ duplicar el segundo articulo a la primera del pila: 1 2 3 4 3 ok +1 2 3 4 2 roll \ *mover* el articulo en este posición a la primera del pila: 1 3 4 2 ok +1 2 3 4 2 pick \ *duplicar* el articulo en este posición a la primera del pila: 1 2 3 4 2 ok + +\ Cuando refiere a pila indices, ellos son basado en cero. + +\ ------------------------------ Creando Palabras -------------------------------- + +\ La `:` palabra hace que Forth entra modo de compilar hasta que se ve la `;` palabra. +: cuadrado ( n -- n ) dup * ; \ ok +5 cuadrado . \ 25 ok + +\ Podemos ver lo que hace una palabra también.: +see cuadrado \ : cuadrado dup * ; ok + +\ -------------------------------- Condicionales -------------------------------- + +\ -1 == cierto, 0 == falso. No obstante, valores que no son cero es usualmente tratado como +\ siendo cierto: +42 42 = \ -1 ok +12 53 = \ 0 ok + +\ `if` es una palabra que solamente compila. `if` <cosas para hacer> `then` <los de mas del programa>. +: ?>64 ( n -- n ) dup 64 > if ." Mas que 64!" then ; \ ok +100 ?>64 \ Mas que 64! ok + +\ Else: +: ?>64 ( n -- n ) dup 64 > if ." Mas que 64!" else ." Menos que 64!" then ; +100 ?>64 \ Mas que 64! ok +20 ?>64 \ Menos que 64! ok + +\ ------------------------------------ Loops ----------------------------------- + +\ `do` también es una palabra que solamente compila. +: miloop ( -- ) 5 0 do cr ." Hola!" loop ; \ ok +miloop +\ Hola! +\ Hola! +\ Hola! +\ Hola! +\ Hola! ok + +\ `do` espera dos números en el pila: el último numero y el primero numero. + +\ Podemos recibir el valor del indice mientras damos vuelta con `i`: +: uno-a-12 ( -- ) 12 0 do i . loop ; \ ok +uno-a-12 \ 0 1 2 3 4 5 6 7 8 9 10 11 12 ok + +\ `?do` funciona similarmente, pero salta el loop si el último y primero +\ números son iguales. +: cuadrados ( n -- ) 0 ?do i cuadrado . loop ; \ ok +10 cuadrado \ 0 1 4 9 16 25 36 49 64 81 ok + +\ cambiar el "paso" con `+loop`: +: treces ( n n -- ) ?do i . 3 +loop ; \ ok +15 0 treces \ 0 3 6 9 12 ok + +\ Indefinido loops empiezan `begin` <cosas para hacer> <bandera> `until`: +: death ( -- ) begin ." Ya hemos llegado?" 0 until ; \ ok + +\ ---------------------------- Variables y Memoria ---------------------------- + +\ Use `variable` declarar `edad` ser un variable. +variable edad \ ok + +\ Ahora escribimos 21 a edad con la palabra `!`. +21 edad ! \ ok + +\ Por fin podemos imprimir nuestro variable usando la "leer" palabra `@`, que agregue el +\ valor a la pila, or usa `?` que lee y imprime todo juntos. +edad @ . \ 21 ok +edad ? \ 21 ok + +\ Constantes son muy similar, pero no nos importa los direcciones de memoria: +100 constant PUNTA-QUE-AQUA-HIERVA \ ok +PUNTA-QUE-AQUA-HIERVA . \ 100 ok + +\ ----------------------------------- Arrays ----------------------------------- + +\ Creando arrays es similar a variables, pero necesitamos alocar mas +\ memoria a ellos. + +\ Puede usar `2 cells allot` para crear un array que es sea 3 cédulas de tamaño: +variable minumeros 2 cells allot \ ok + +\ Inicializar todos los valores a 0 +minumeros 3 cells erase \ ok + +\ Alternativamente podemos usar `fill`: +minumeros 3 cells 0 fill + +\ o podemos saltar todo arriba y inicializar con valores específicos: +create minumeros 64 , 9001 , 1337 , \ ok (el último `,` es importante!) + +\ ...que es equivalente a: + +\ Manualmente escribiendo valores a cada indice: +64 minumeros 0 cells + ! \ ok +9001 minumeros 1 cells + ! \ ok +1337 minumeros 2 cells + ! \ ok + +\ Leyendo valores en particular array indices: +0 cells minumeros + ? \ 64 ok +1 cells minumeros + ? \ 9001 ok + +\ Podemos simplificar un poco cuando hacemos una palabra que ayuda cuando manipulando arrays: +: de-arr ( n n -- n ) cells + ; \ ok +minumeros 2 de-arr ? \ 1337 ok + +\ Que podemos usar cuando escribimos también: +20 minumeros 1 de-arr ! \ ok +minumeros 1 de-arr ? \ 20 ok + +\ ------------------------------ El Pila de Regreso ------------------------------ + +\ El pila de regreso se usa para retener punteros a cosas cuando palabras están +\ ejecutando otras palabras como loops. + +\ Ya hemos visto un uso de esto: `i`, que duplica el primero del pila +\ de regreso. `i` es equivalente a `r@`. +: miloop ( -- ) 5 0 do r@ . loop ; \ ok + +\ También como leyendo, podemos agregar al pila de regreso y sacarlo: +5 6 4 >r swap r> .s \ 6 5 4 ok + +\ NOTA: Porque Forth usa el pila de regreso por punteros de palabras, `>r` debe +\ siempre ser seguido por un `r>`. + +\ ------------------------- Flotante Punto Operaciones -------------------------- + +\ La mayoría Forths evitan el uso de flotante punto operaciones. +8.3e 0.8e f+ f. \ 9.1 ok + +\ Usualmente agregamos al frente palabras con 'f' cuando usando flotantes: +variable miflotantevar \ ok +4.4e miflotantevar f! \ ok +miflotantevar f@ f. \ 4.4 ok + +\ --------------------------------- Notas al Final -------------------------------- + +\ Usando una palabra que no existe vaciara el pila. No obstante, también hay una palabra +\ específicamente por esto: +clearstack + +\ vaciar la pantalla: +page + +\ Cargando Forth archivos: +\ s" archivodeforth.fs" included + +\ Puede listar cada palabra en el diccionario de Forth (pero es una lista gigante!): +\ words + +\ Terminando Gforth: +\ bye + +``` + +##Listo Para Mas? + +* [Starting Forth](http://www.forth.com/starting-forth/) +* [Simple Forth](http://www.murphywong.net/hello/simple.htm) +* [Thinking Forth](http://thinking-forth.sourceforge.net/) diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown index 18b544b4..4e1e68ba 100644 --- a/es-es/git-es.html.markdown +++ b/es-es/git-es.html.markdown @@ -18,11 +18,11 @@ versionar y administrar nuestro código fuente. ## Versionamiento, conceptos. -### Qué es el control de versiones? +### ¿Qué es el control de versiones? El control de versiones es un sistema que guarda todos los cambios realizados en uno o varios archivos, a lo largo del tiempo. -### Versionamiento centralizado vs Versionamiento Distribuido. +### Versionamiento centralizado vs versionamiento distribuido. + El versionamiento centralizado se enfoca en sincronizar, rastrear, y respaldar archivos. @@ -33,9 +33,9 @@ uno o varios archivos, a lo largo del tiempo. [Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones) -### Por qué usar Git? +### ¿Por qué usar Git? -* Se puede trabajar sin conexion. +* Se puede trabajar sin conexión. * ¡Colaborar con otros es sencillo!. * Derivar, crear ramas del proyecto (aka: Branching) es fácil. * Combinar (aka: Merging) @@ -47,7 +47,7 @@ uno o varios archivos, a lo largo del tiempo. ### Repositorio Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka: -comits), y encabezados (aka: heads). Imagina que un repositorio es una clase, +commits), y encabezados (aka: heads). Imagina que un repositorio es una clase, y que sus atributos otorgan acceso al historial del elemento, además de otras cosas. @@ -62,12 +62,12 @@ y mas. ### Directorio de trabajo (componentes del repositorio) -Es basicamente los directorios y archivos dentro del repositorio. La mayoría de +Es básicamente los directorios y archivos dentro del repositorio. La mayoría de las veces se le llama "directorio de trabajo". ### Índice (componentes del directorio .git) -El índice es el área de inicio en git. Es basicamente la capa que separa el +El índice es el área de inicio en git. Es básicamente la capa que separa el directorio de trabajo del repositorio en git. Esto otorga a los desarrolladores más poder sobre lo que se envía y se recibe del repositorio. diff --git a/es-es/hack-es.html.markdown b/es-es/hack-es.html.markdown new file mode 100644 index 00000000..1059117a --- /dev/null +++ b/es-es/hack-es.html.markdown @@ -0,0 +1,307 @@ +--- +language: Hack +contributors: + - ["Stephen Holdaway", "https://github.com/stecman"] + - ["David Lima", "https://github.com/davelima"] +translators: + - ["César Suárez", "https://github.com/csuarez"] +lang: es-es +filename: learnhack-es.hh +--- + +Hack es un superconjunto de PHP que se ejecuta en una máquina virtual llamada HHVM. Hack es casi totalmente compatible con código PHP ya existente y añade varias características típicas de los lenguajes de programación estáticamente tipados. + +En este artículo sólo se cubren las características específicas de Hack. Los detalles sobre la sintaxis de PHP están en el [artículo sobre PHP](http://learnxinyminutes.com/docs/php/) de esta misma web. + +```php +<?hh + +// La sintaxis de Hack sólo se habilita para los ficheros que comienzan con +// un marcador <?hh. Estos marcadores no pueden intercalarse con código HTML, +// tal como se puede hacer con <?php. Al usar el marcador "<?hh //strict" el +// comprobador de tipado en modo estricto se pone en modo estricto. + +// Indicando el tipo de parámetros escalares +function repeat(string $word, int $count) +{ + $word = trim($word); + return str_repeat($word . ' ', $count); +} + +// Indicando el tipo que devuelve una función +function add(...$numbers) : int +{ + return array_sum($numbers); +} + +// Las funciones que no devuelven nada usan el tipo "void" +function truncate(resource $handle) : void +{ + // ... +} + +// Al determinar un tipo, hay que indicar explícitamente si permite el valor +// NULL +function identity(?string $stringOrNull) : ?string +{ + return $stringOrNull; +} + +// Se puede especificar el tipo de las propiedades de una clase +class TypeHintedProperties +{ + public ?string $name; + + protected int $id; + + private float $score = 100.0; + + // El comprobador de tipos de Hack fuerza que las propiedades tipadas + // tengan un valor por defecto o que estén asignadas en el constructor + public function __construct(int $id) + { + $this->id = $id; + } +} + + +// Funciones anónimas concisas (lambdas) +$multiplier = 5; +array_map($y ==> $y * $multiplier, [1, 2, 3]); + + +// Genéricos +class Box<T> +{ + protected T $data; + + public function __construct(T $data) { + $this->data = $data; + } + + public function getData(): T { + return $this->data; + } +} + +function openBox(Box<int> $box) : int +{ + return $box->getData(); +} + + +// Shapes +// +// Hack añade el concepto de shape para definir estructuras similares a +// vectores, pero con un conjunto de claves garantizado y tipado +type Point2D = shape('x' => int, 'y' => int); + +function distance(Point2D $a, Point2D $b) : float +{ + return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2)); +} + +distance( + shape('x' => -1, 'y' => 5), + shape('x' => 2, 'y' => 50) +); + + +// Alias de tipos +// +// Hack permite crear alias para hacer que los tipos complejos sean más legibles +newtype VectorArray = array<int, Vector<int>>; + +// Una tupla que contiene dos enteros +newtype Point = (int, int); + +function addPoints(Point $p1, Point $p2) : Point +{ + return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]); +} + +addPoints( + tuple(1, 2), + tuple(5, 6) +); + + +// Enumerados de primera clase +enum RoadType : int +{ + Road = 0; + Street = 1; + Avenue = 2; + Boulevard = 3; +} + +function getRoadType() : RoadType +{ + return RoadType::Avenue; +} + + +// Promoción de argumentos en constructores +// +// Para evitar repetir una y otra vez la definición de constructores que +// sólo asignan propiedades, Hack añade una sintaxis concisa para definir +// propiedades junto al constructor. +class ArgumentPromotion +{ + public function __construct(public string $name, + protected int $age, + private bool $isAwesome) {} +} + +class WithoutArgumentPromotion +{ + public string $name; + + protected int $age; + + private bool $isAwesome; + + public function __construct(string $name, int $age, bool $isAwesome) + { + $this->name = $name; + $this->age = $age; + $this->isAwesome = $isAwesome; + } +} + + +// Multitarea cooperativa +// +// "async" y "await" son dos palabras claves nuevas para realizar multi-tarea. +// Esto no implica que se usen hilos, sólo permiten transferir el control de la +// ejecución. +{ + for ($i = $start; $i <= $end; $i++) { + echo "$i "; + + // Da a otras tareas la oportunidad de hacer algo + await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0); + } +} + +// Esto imprime "1 4 7 2 5 8 3 6 9" +AwaitAllWaitHandle::fromArray([ + cooperativePrint(1, 3), + cooperativePrint(4, 6), + cooperativePrint(7, 9) +])->getWaitHandle()->join(); + + +// Atributos +// +// Los atributos son una especie de metadatos para funciones. Hack implementa +// algunos atributos especiales para introducir esta característica. + +// El atributo especial __Memoize hace que el resultado de la función se cacheé. +<<__Memoize>> +function doExpensiveTask() : ?string +{ + return file_get_contents('http://example.com'); +} + +// Esta función se va a ejecutar sólo una vez: +doExpensiveTask(); +doExpensiveTask(); + + +// El atributo __ConsistentConstruct indica al comprobador de tipos de Hack que +// asegure que la signatura de __construct sea la misma para todas las +// subclases. +<<__ConsistentConstruct>> +class ConsistentFoo +{ + public function __construct(int $x, float $y) + { + // ... + } + + public function someMethod() + { + // ... + } +} + +class ConsistentBar extends ConsistentFoo +{ + public function __construct(int $x, float $y) + { + // El comprobador de tipos de Hack fuerza que los constructores de + // los padres sean llamados. + parent::__construct($x, $y); + + // ... + } + + // La anotación __Override es un atributo opcional para que el comprobador + // de tipos fuerce que ese método esté sobrecargando un método de un padre + // o de un trait. Sino, fallará. + <<__Override>> + public function someMethod() + { + // ... + } +} + +class InvalidFooSubclass extends ConsistentFoo +{ + // Este constructor no coincide con el padre y causará el siguiente error: + // + // "This object is of type ConsistentBaz. It is incompatible with this + // object of type ConsistentFoo because some of their methods are + // incompatible" + public function __construct(float $x) + { + // ... + } + + // Usando la anotación __Override en un método que no sobrecarga nada se + // producirá el siguiente error: + // + // "InvalidFooSubclass::otherMethod() is marked as override; no non-private + // parent definition found or overridden parent is defined in non-<?hh + // code" + <<__Override>> + public function otherMethod() + { + // ... + } +} + + +// Los traits pueden implementar interfaces (PHP no soporta esto). +interface KittenInterface +{ + public function play() : void; +} + +trait CatTrait implements KittenInterface +{ + public function play() : void + { + // ... + } +} + +class Samuel +{ + use CatTrait; +} + + +$cat = new Samuel(); +$cat instanceof KittenInterface === true; // True + +``` + +## Más información + +Para obtener una explicación más detallada de las características que añade Hack a PHP visita la página de [referencia de Hack](http://docs.hhvm.com/manual/en/hacklangref.php) o la [página oficial de Hack](http://hacklang.org/) para información de caracter más general. + +Visita la [página oficial de HHVM](http://hhvm.com/) para ver las instrucciones de su instalación. + +También puedes visitar la [sección de características de PHP no soportadas por Hack](http://docs.hhvm.com/manual/en/hack.unsupported.php) para más detalles sobre la retrocompatibilidad entre Hack y PHP. diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown index d475cf42..9ef0c63e 100644 --- a/es-es/javascript-es.html.markdown +++ b/es-es/javascript-es.html.markdown @@ -30,7 +30,7 @@ Aunque JavaScript no sólo se limita a los navegadores web: Node.js, Un proyecto // Cada sentencia puede ser terminada con punto y coma ; hazAlgo(); -// ... aunque no es necesario, ya que el punto y coma se agrega automaticamente +// ... aunque no es necesario, ya que el punto y coma se agrega automáticamente // cada que se detecta una nueva línea, a excepción de algunos casos. hazAlgo() @@ -109,7 +109,7 @@ null == undefined; // = true null === undefined; // false // Los Strings funcionan como arreglos de caracteres -// Puedes accesar a cada caracter con la función charAt() +// Puedes acceder a cada caracter con la función charAt() "Este es un String".charAt(0); // = 'E' // ...o puedes usar la función substring() para acceder a pedazos más grandes @@ -186,7 +186,7 @@ miObjeto.miLlave; // = "miValor" // agregar nuevas llaves. miObjeto.miTerceraLlave = true; -// Si intentas accesar con una llave que aún no está asignada tendrás undefined. +// Si intentas acceder con una llave que aún no está asignada tendrás undefined. miObjeto.miCuartaLlave; // = undefined /////////////////////////////////// @@ -301,7 +301,7 @@ i; // = 5 - en un lenguaje que da ámbitos por bloque esto sería undefined, per //inmediatamente", que preveé variables temporales de fugarse al ámbito global (function(){ var temporal = 5; - // Podemos accesar al ámbito global asignando al 'objeto global', el cual + // Podemos acceder al ámbito global asignando al 'objeto global', el cual // en un navegador siempre es 'window'. El objeto global puede tener // un nombre diferente en ambientes distintos, por ejemplo Node.js . window.permanente = 10; @@ -321,7 +321,7 @@ function decirHolaCadaCincoSegundos(nombre){ alert(texto); } setTimeout(interna, 5000); - // setTimeout es asíncrono, así que la funcion decirHolaCadaCincoSegundos + // setTimeout es asíncrono, así que la función decirHolaCadaCincoSegundos // terminará inmediatamente, y setTimeout llamará a interna() a los cinco segundos // Como interna está "cerrada dentro de" decirHolaCadaCindoSegundos, interna todavía tiene // acceso a la variable 'texto' cuando es llamada. @@ -339,7 +339,7 @@ var miObjeto = { }; miObjeto.miFuncion(); // = "¡Hola Mundo!" -// Cuando las funciones de un objeto son llamadas, pueden accesar a las variables +// Cuando las funciones de un objeto son llamadas, pueden acceder a las variables // del objeto con la palabra clave 'this'. miObjeto = { miString: "¡Hola Mundo!", @@ -401,11 +401,11 @@ var MiConstructor = function(){ miNuevoObjeto = new MiConstructor(); // = {miNumero: 5} miNuevoObjeto.miNumero; // = 5 -// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a accesar a una +// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a acceder a una // propiedad en un objeto que no existe en el objeto el intérprete buscará en // el prototipo. -// Algunas implementaciones de JavaScript te permiten accesar al prototipo de +// Algunas implementaciones de JavaScript te permiten acceder al prototipo de // un objeto con la propiedad __proto__. Mientras que esto es útil para explicar // prototipos, no es parte del estándar; veremos formas estándar de usar prototipos // más adelante. @@ -440,7 +440,7 @@ miPrototipo.sentidoDeLaVida = 43; miObjeto.sentidoDeLaVida; // = 43 // Mencionabamos anteriormente que __proto__ no está estandarizado, y que no -// existe una forma estándar de accesar al prototipo de un objeto. De todas formas. +// existe una forma estándar de acceder al prototipo de un objeto. De todas formas. // hay dos formas de crear un nuevo objeto con un prototipo dado. // El primer método es Object.create, el cual es una adición reciente a JavaScript, @@ -476,7 +476,7 @@ typeof miNumero; // = 'number' typeof miNumeroObjeto; // = 'object' miNumero === miNumeroObjeyo; // = false if (0){ - // Este código no se ejecutara porque 0 es false. + // Este código no se ejecutará porque 0 es false. } // Aún así, los objetos que envuelven y los prototipos por defecto comparten diff --git a/es-es/json-es.html.markdown b/es-es/json-es.html.markdown index fff678eb..c98049f9 100644 --- a/es-es/json-es.html.markdown +++ b/es-es/json-es.html.markdown @@ -21,22 +21,22 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead "llaves": "siempre debe estar entre comillas (ya sean dobles o simples)", "numeros": 0, "strings": "Høla, múndo. Todo el unicode está permitido, así como \"escapar\".", - "soporta booleanos?": true, - "vacios": null, + "¿soporta booleanos?": true, + "vacíos": null, "numero grande": 1.2e+100, "objetos": { - "comentario": "La mayoria de tu estructura vendra de objetos.", + "comentario": "La mayoría de tu estructura vendrá de objetos.", "arreglo": [0, 1, 2, 3, "Los arreglos pueden contener cualquier cosa.", 5], "otro objeto": { - "comentario": "Estas cosas pueden estar anidadas, muy util." + "comentario": "Estas cosas pueden estar anidadas, muy útil." } }, - "tonteria": [ + "tontería": [ { "fuentes de potasio": ["bananas"] }, @@ -50,10 +50,10 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead "estilo alternativo": { "comentario": "Mira esto!" - , "posicion de la coma": "no importa - mientras este antes del valor, entonces sera valido" - , "otro comentario": "que lindo" + , "posición de la coma": "no importa - mientras este antes del valor, entonces sera válido" + , "otro comentario": "qué lindo" }, - "eso fue rapido": "Y, estas listo. Ahora sabes todo lo que JSON tiene para ofrecer." + "eso fue rapido": "Y, estás listo. Ahora sabes todo lo que JSON tiene para ofrecer." } ``` diff --git a/es-es/latex-es.html.markdown b/es-es/latex-es.html.markdown new file mode 100644 index 00000000..aff3c603 --- /dev/null +++ b/es-es/latex-es.html.markdown @@ -0,0 +1,213 @@ +--- +language: latex +lang: es-es +contributors: + - ["Chaitanya Krishna Ande", "http://icymist.github.io"] + - ["Colton Kohnke", "http://github.com/voltnor"] + - ["Sricharan Chiruvolu", "http://sricharan.xyz"] +translators: + - ["Mario Pérez", "https://github.com/MarioPerezEsteso"] +filename: learn-latex-es.tex +--- + +```tex +% Todas las líneas comentadas comienzan con % +% No existen los comentarios multilínea + +% LaTeX NO es un software de procesamiento de texto que cumple con +% "Lo que ves es lo que tienes" como MS Word u OpenOffice + +% Todos los comandos de LaTeX comienzan con una contrabarra (\) + +% Los documentos LaTeX comienzan definiendo el tipo de documento que se va a +% compilar. Algunos tipos de documentos son libros, informes, presentaciones, +% etc. Las opciones para el documento comienzan en los corchetes []. En este +% caso, se especifica que queremos utilizar una fuente de tamaño 12pt. +\documentclass[12pt]{article} + +% A continuación, definimos los paquetes que utilizará el documento. +% Si quieres incluir gráficos, texto coloreado o código fuente de otro lenguaje, +% debes extender las funciones de LaTeX. Esto se consigue añadiendo paquetes. +% A continuación se incluirán los paquetes float y caption para figuras. +\usepackage{caption} +\usepackage{float} + +% También podemos definir otras propiedades en el documento +\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu} +\date{\today} +\title{Learn LaTeX in Y Minutes!} + +% Ahora estamos preparados para comenzar el documento +% Todo lo que se encuentre antes de esta línea se llama "El Preámbulo" +\begin{document} +% Si especificamos el autor, fecha y título, LaTeX creará una página como título +% por nosotros +\maketitle + +% La mayoría de los artículos de investigación tienen un abstract. Es posible +% utilizar comandos predefinidos para ello. +% Esto debería aparecer en su orden lógico. Tras el título pero antes de las +% secciones principales del cuerpo. +% Este comando está disponible en los tipos de documentos article y report. +\begin{abstract} + Documentación de LaTex escrita en LaTex. +\end{abstract} + +% Los comandos de sección son intuitivos. +% Todos los títulos de secciones son añadidos automáticamente a la tabla de contenidos. +\section{Introducción} +Hola, mi nombre es Mario Pérez y estoy traduciendo este documento para aprender LaTex. + +\section{Otra sección} +Este es el texto de otra sección. Creo que necesitará una subsección. + +\subsection{Esto es una subsección} % Las subsecciones también son fáciles. +Creo que necesitamos otra más. + +\subsubsection{Pitágoras} +Mejor ahora. +\label{subsec:pitagoras} + +% Utilizando el asterisco podemos decirle a LaTeX que no ponga los números de secciones y subsecciones. +% Esto también funciona con otros comandos de LaTeX. +\section*{Esto es una sección no numerada} +¡No todas las secciones tienen que estar numeradas! + +\section{Algunas notas} +LaTeX es generalmente bastante bueno situando el texto donde debe ir. Si una lína \\ necesita \\ ser \\ rota \\ puedes poner \textbackslash\textbackslash en el código fuente. \\ + +\section{Listas} +Las listas son de las cosas más fáciles de crear en LaTeX. Necesito ir a comprar mañana, así que vamos a crear una lista de la compra. +\begin{enumerate} % Esto crea una lista numerada. + % \item crea un elemento + \item Ensalada. + \item 27 sandías. + \item Pescado. + % podemos incluso sobreescribir el número del ítem usando [] + \item[cuántos?] Plátanos. + + No es un ítem de la lista, pero sigue siendo parte de la enumeración. + +\end{enumerate} % Todos los contextos deben tener un final. + +\section{Matemáticas} + +Uno de los usos principales de LaTeX es la producción de artículos académicos o técnicos. Normalmente relacionados con la ciencia y las matemáticas. Debido a esto, necesitamos poder añadir símbolos especiales a nuestro artículo.\\ + +En matemáticas hay muchos símbolos. Más de los que podemos encontrar en un teclado. Flechas o letras por nombrar un par.\\ + +Algunos símbolos juegan un papel fundamental en muchos artículos de investigación matemática. Así es como se establece que todo Y pertenece a X: $\forall$ x $\in$ X. \\ +He necesitado añadir el signo $ antes de los símbolos. Esto se debe a que cuando escribimos, estamos en modo texto. Sin embargo, los símbolos solo pueden utilizarse en modo matemático, al cual se entra con el signo $. +% Lo opuesto también se cumple. Una variable también puede ser mostrada en modo matemático, al que también se puede entrar con \[\] + +\[a^2 + b^2 = c^2 \] + +Mi letra griega favorita es $\xi$. También me gustan $\beta$, $\gamma$ y $\sigma$. +Todavía no he encontrado una letra griega que LaTeX no conozca. + +Los operadores son también una parte esencial de un documento matemático: +funciones trigonométricas ($\sin$, $\cos$, $\tan$), logaritmos y exponenciales ($\log$, $\exp$), límites ($\lim$), etc. tienen comandos predefinidos en LaTeX. + +Vamos a escribir una ecuación para ver cómo se hace: \\ + +$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$ + +Las fracciones (numeradores-denominadores) pueden escribirse de la siguiente forma: + +% 10 / 7 +$^{10}/_{7}$ + +% Las fracciones relativamente complejas pueden escribirse como +% \frac{numerador}{denominador} +$\frac{n!}{k!(n - k)!}$ \\ + +También podemos insertar ecuaciones en un contexto de ecuación. + +% Mostrar matemáticas en el contexto de ecuaciones +\begin{equation} % entra en modo matemático + c^2 = a^2 + b^2. + \label{eq:pitagoras} % para referencias +\end{equation} % Todos los contextos deben tener un final. + +Podemos referenciar nuestra nueva ecuación. +Ecuación ~\ref{eq:pythagoras} también se conoce como el Teorema de Pitágoras, el cual también se encuentra en la sección ~\ref{subsec:pythagoras}. Muchas cosas pueden ser etiquetadas: figures, equations, sections, etc. + +Los sumatorios e integrales son escritor son los comandos sum e int: + +% Algunos compiladores de LaTeX se quejarán si hay líneas en blanco +% En un contexto de ecuación. +\begin{equation} + \sum_{i=0}^{5} f_{i} +\end{equation} +\begin{equation} + \int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x +\end{equation} + +\section{Figuras} + +Vamos a insertar una figura. Situarla puede ser algo complicado. + +\begin{figure}[H] % H aquí establece la situación de la figura. + \centering % centra la figura en la página + % Inserta una figura escalada por 0.8 el ancho de la página. + %\includegraphics[width=0.8\linewidth]{right-triangle.png} + % La línea anterior ha sido comentada para poder compilar este archivo. Por favor, usa tu imaginación. + \caption{Triángulo con lados $a$, $b$, $c$} + \label{fig:right-triangle} +\end{figure} + +\subsection{Tablas} +También podemos insertar tablas de la misma manera que las figuras. + +\begin{table}[H] + \caption{Título para la tabla.} + % los argumentos en {} describen cómo cada fila va a ser representada. + \begin{tabular}{c|cc} + Número & Nombre & Apellido \\ + \hline % una línea horizontal + 1 & Biggus & Dickus \\ + 2 & Monty & Python + \end{tabular} +\end{table} + +% \section{Hyperlinks} % En construcción + +\section{Haciendo que LaTeX no compile algo (por ejemplo, código fuente)} +Digamos que queremos incluir código fuente dentro de nuestro documento LaTex. En ese caso, debemos indicarle a LaTeX que no trate de compilarlo y simplemente lo muestre en el documento. Esto lo realizamos en el contexto verbatim. + +% Hay otros paquetes para esta misma tarea, pero verbatim es el más básico. +\begin{verbatim} + print("Hola Mundo!") + a%b; % Podemos usar los signos % en verbatim. + aleatorio = 4; # Número aleatorio +\end{verbatim} + +\section{Compilación} + +Ahora mismo te estarás preguntando cómo compilar este fabuloso documento y obtener un documento PDF.\\ +Para obtener el documento final utilizando LaTeX hay que seguir los siguientes pasos: + \begin{enumerate} + \item Escribe el documento en texto plano. + \item Compila el código para producir un PDF. + Los pasos de compilación serán algo parecido a esto (en Linux): \\ + \begin{verbatim} + $pdflatex learn-latex.tex learn-latex.pdf + \end{verbatim} + \end{enumerate} + +Un gran número de editores LaTeX combinan ambos pasos para que sea más sencillo obtener el documento. + +Escribe toda la información de formato en el paso 1 y con el paso 2 obtendrás el documento que has definido en el paso anterior. + +\section{End} + +Esto es todo por ahora. + +% fin del documento +\end{document} +``` + +## Más información sobre LaTeX + +* El wikilibro LaTeX: [https://es.wikibooks.org/wiki/Manual_de_LaTeX](https://es.wikibooks.org/wiki/Manual_de_LaTeX) +* Un tutorial real: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/) diff --git a/es-es/markdown-es.html.markdown b/es-es/markdown-es.html.markdown index d90e3eb5..0505b4cb 100644 --- a/es-es/markdown-es.html.markdown +++ b/es-es/markdown-es.html.markdown @@ -11,7 +11,7 @@ lang: es-es Markdown fue creado por John Gruber en 2004. Su propósito es ser una sintaxis fácil de leer y escribir que se convierta fácilmente a HTML (y, actualmente, otros formatos también). -¡Denme todo la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests! +¡Denme toda la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests! ```markdown @@ -44,7 +44,7 @@ Esto es un h2 ------------- <!-- Estilos para texto plano --> -<!-- El texto puede ser fácilmente estilizaedo con italicas, negritas o tachado +<!-- El texto puede ser fácilmente estilizado con italicas, negritas o tachado usando markdown --> *Este texto está en itálicas.* @@ -57,12 +57,12 @@ __Al igual que este texto.__ **_Al igual que este!_** *__¡Y este!__* -<!-- En Github Flavored Markdown, el cual es usado para mostrar archivos -Markdown en Github, también tenemos: --> +<!-- En GitHub Flavored Markdown, el cual es usado para mostrar archivos +Markdown en GitHub, también tenemos: --> ~~Este texto está tachado.~~ -<!-- Los párrafos son una o múltuples líneas de texto adyacentes separadas por +<!-- Los párrafos son una o múltiples líneas de texto adyacentes separadas por una o múltiples líneas en blanco--> Este es un párrafo. Estoy escribiendo un párrafo, ¿No es divertido? @@ -150,7 +150,7 @@ para indentar dentro del código --> ¡John no sabía lo que la función `go_to()` hacía! -<!-- Con Github Flavored Markdown, puedes usar una sintaxis especial para código --> +<!-- Con GitHub Flavored Markdown, puedes usar una sintaxis especial para código --> \`\`\`ruby <!-- quita esas comillas cuando lo hagas, deja sólo ```ruby ! --> def foobar @@ -158,7 +158,7 @@ def foobar end \`\`\` <!-- aquí también, sin comillas, sólo ``` --> -<!-- El texto de arriba no necesita indentación, aparte Github usará +<!-- El texto de arriba no necesita indentación, aparte GitHub usará resaltará la sintaxis del lenguaje que especifiques después de ``` --> <!-- Regla horizontal (<hr />) --> @@ -231,7 +231,7 @@ Quiero escribir *este texto rodeado por asteriscos* pero no quiero que esté en así que hago esto: \*Este texto está rodeado de asteriscos\*. <!-- Tablas --> -<!-- Las tablas sólo están disponibles en Github Flavored Markdown y son un poco pesadas, +<!-- Las tablas sólo están disponibles en GitHub Flavored Markdown y son un poco pesadas, pero si de verdad las quieres: --> | Col1 | Col2 | Col3 | diff --git a/es-es/objective-c-es.html.markdown b/es-es/objective-c-es.html.markdown new file mode 100644 index 00000000..bdbce524 --- /dev/null +++ b/es-es/objective-c-es.html.markdown @@ -0,0 +1,851 @@ +--- +language: Objective-C +contributors: + - ["Eugene Yagrushkin", "www.about.me/yagrushkin"] + - ["Yannick Loriot", "https://github.com/YannickL"] + - ["Levi Bostian", "https://github.com/levibostian"] +translators: + - ["David Hsieh", "http://github.com/deivuh"] +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. +Es un lenguaje de programación para propósito general que le agrega al lenguaje de programación C una mensajería estilo "Smalltalk". + + +```objective_c +// Los comentarios de una sola línea inician con // + +/* +Los comentarios de múltiples líneas se ven así. +*/ + +// Importa los encabezados de Foundation con #import +// Utiliza <> para importar archivos globales (generalmente frameworks) +// Utiliza "" para importar archivos locales (del proyecto) +#import <Foundation/Foundation.h> +#import "MyClass.h" + +// Si habilitas módulos para proyectos de iOS >= 7.0 u OS X >= 10.9 en +// Xcode 5, puedes importarlos de la siguiente manera: +@import Foundation; + +// El punto de entrada de tu programa es una función llamada +// main con un tipo de retorno entero. +int main (int argc, const char * argv[]) +{ + // Crear un autorelease pool para manejar la memoria al programa + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + // Si se utiliza el conteo automático de referencias (ARC), + // utiliza @autoreleasepool: + @autoreleasepool { + + // Utiliza NSLog para imprimir líneas a la consola + NSLog(@"Hello World!"); // Imprimir el string "Hello World!" + + /////////////////////////////////////// + // Tipos y variables + /////////////////////////////////////// + + // Declaraciones de primitivos + int myPrimitive1 = 1; + long myPrimitive2 = 234554664565; + + // Declaraciones de objetos + // Pon el * como prefijo de los nombre de las variables para declaraciones + // de objetos de tipos fuertes + MyClass *myObject1 = nil; // Tipo fuerte + id myObject2 = nil; // Tipo débil + // %@ es un objeto + // 'description' es una convención para mostrar el valor de los objetos + NSLog(@"%@ and %@", myObject1, [myObject2 description]); + // imprime => "(null) and (null)" + + // String + NSString *worldString = @"World"; + NSLog(@"Hello %@!", worldString); // imprime => "Hello World!" + // NSMutableString es una versión mutable del objeto NSString + NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"]; + [mutableString appendString:@" World!"]; + NSLog(@"%@", mutableString); // imprime => "Hello World!" + + // Literales de caracteres + NSNumber *theLetterZNumber = @'Z'; + char theLetterZ = [theLetterZNumber charValue]; // o 'Z' + NSLog(@"%c", theLetterZ); + + // Literales de enteros + NSNumber *fortyTwoNumber = @42; + int fortyTwo = [fortyTwoNumber intValue]; // o 42 + NSLog(@"%i", fortyTwo); + + NSNumber *fortyTwoUnsignedNumber = @42U; + unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue]; // o 42 + NSLog(@"%u", fortyTwoUnsigned); + + NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42]; + short fortyTwoShort = [fortyTwoShortNumber shortValue]; // o 42 + NSLog(@"%hi", fortyTwoShort); + + NSNumber *fortyOneShortNumber = [NSNumber numberWithShort:41]; + unsigned short fortyOneUnsigned = [fortyOneShortNumber unsignedShortValue]; // o 41 + NSLog(@"%u", fortyOneUnsigned); + + NSNumber *fortyTwoLongNumber = @42L; + long fortyTwoLong = [fortyTwoLongNumber longValue]; // o 42 + NSLog(@"%li", fortyTwoLong); + + NSNumber *fiftyThreeLongNumber = @53L; + unsigned long fiftyThreeUnsigned = [fiftyThreeLongNumber unsignedLongValue]; // o 53 + NSLog(@"%lu", fiftyThreeUnsigned); + + // Literales de punto flotante + NSNumber *piFloatNumber = @3.141592654F; + float piFloat = [piFloatNumber floatValue]; // o 3.141592654f + NSLog(@"%f", piFloat); // imprime => 3.141592654 + NSLog(@"%5.2f", piFloat); // imprime => " 3.14" + + NSNumber *piDoubleNumber = @3.1415926535; + double piDouble = [piDoubleNumber doubleValue]; // o 3.1415926535 + NSLog(@"%f", piDouble); + NSLog(@"%4.2f", piDouble); // imprime => "3.14" + + // NSDecimalNumber es una clase de punto-fijo que es más preciso que float o double + NSDecimalNumber *oneDecNum = [NSDecimalNumber decimalNumberWithString:@"10.99"]; + NSDecimalNumber *twoDecNum = [NSDecimalNumber decimalNumberWithString:@"5.002"]; + // NSDecimalNumber no tiene la capacidad de utilizar los operadores estándares + // +, -, * , /, por lo que cuenta con sus propios operadores: + [oneDecNum decimalNumberByAdding:twoDecNum]; + [oneDecNum decimalNumberBySubtracting:twoDecNum]; + [oneDecNum decimalNumberByMultiplyingBy:twoDecNum]; + [oneDecNum decimalNumberByDividingBy:twoDecNum]; + NSLog(@"%@", oneDecNum); // imprime => 10.99 como NSDecimalNumber es inmutable + + // Literales BOOL + NSNumber *yesNumber = @YES; + NSNumber *noNumber = @NO; + // o + BOOL yesBool = YES; + BOOL noBool = NO; + NSLog(@"%i", yesBool); // prints => 1 + + // Objecto arreglo + // Puede contener diferentes tipos de datos, pero deben de ser un objeto de + // Objective-C + NSArray *anArray = @[@1, @2, @3, @4]; + NSNumber *thirdNumber = anArray[2]; + NSLog(@"Third number = %@", thirdNumber); // imprime => "Third number = 3" + // NSMutableArray es una versión mutable de NSArray, permitiendo el cambio + // de los elementos del arreglo y el agrandado o encojimiento del objeto arreglo. + // Conveniente, pero no tan eficiente como NSArray en cuanto a rendimiento. + NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2]; + [mutableArray addObject:@"Hello"]; + [mutableArray addObject:@"World"]; + [mutableArray removeObjectAtIndex:0]; + NSLog(@"%@", [mutableArray objectAtIndex:0]); // imprime => "World" + + // Objecto Diccionario + NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" }; + NSObject *valueObject = aDictionary[@"A Key"]; + NSLog(@"Object = %@", valueObject); // imprime => "Object = (null)" + // NSMutableDictionary también está disponible como un objeto mutable + NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [mutableDictionary setObject:@"value1" forKey:@"key1"]; + [mutableDictionary setObject:@"value2" forKey:@"key2"]; + [mutableDictionary removeObjectForKey:@"key1"]; + + // Objeto de Set + NSSet *set = [NSSet setWithObjects:@"Hello", @"Hello", @"World", nil]; + NSLog(@"%@", set); // imprime => {(Hello, World)} (el orden puede variar) + // NSMutableSet también está disponible como un objeto mutable + NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2]; + [mutableSet addObject:@"Hello"]; + [mutableSet addObject:@"Hello"]; + NSLog(@"%@", mutableSet); // prints => {(Hello)} + + /////////////////////////////////////// + // Operadores + /////////////////////////////////////// + + // Los operadores funcionan como en el lenguaje C + // Por ejemplo: + 2 + 5; // => 7 + 4.2f + 5.1f; // => 9.3f + 3 == 2; // => 0 (NO) + 3 != 2; // => 1 (YES) + 1 && 1; // => 1 (and lógico) + 0 || 1; // => 1 (or lógico) + ~0x0F; // => 0xF0 (negación bitwise) + 0x0F & 0xF0; // => 0x00 (AND bitwise) + 0x01 << 1; // => 0x02 (acarreamiento a la izquierda bitwise (por 1)) + + /////////////////////////////////////// + // Estructuras de control + /////////////////////////////////////// + + // Declaraciones If-Else + if (NO) + { + NSLog(@"I am never run"); + } else if (0) + { + NSLog(@"I am also never run"); + } else + { + NSLog(@"I print"); + } + + // Declaración Switch + switch (2) + { + case 0: + { + NSLog(@"I am never run"); + } break; + case 1: + { + NSLog(@"I am also never run"); + } break; + default: + { + NSLog(@"I print"); + } break; + } + + // Declaración de ciclos While + int ii = 0; + while (ii < 4) + { + NSLog(@"%d,", ii++); // ii++ incrementa ii en la misma línea, luego de + // utilizar su valor + } // imprime => "0," + // "1," + // "2," + // "3," + + // Declaración de ciclos For + int jj; + for (jj=0; jj < 4; jj++) + { + NSLog(@"%d,", jj); + } // imprime => "0," + // "1," + // "2," + // "3," + + // Declaraciones foreach + NSArray *values = @[@0, @1, @2, @3]; + for (NSNumber *value in values) + { + NSLog(@"%@,", value); + } // imprime => "0," + // "1," + // "2," + // "3," + + // Objeto de ciclos For. Puede ser utilizado con cualquier tipo de objecto de + // Objective-C + for (id item in values) { + NSLog(@"%@,", item); + } // imprime => "0," + // "1," + // "2," + // "3," + + // Declaraciones Try-Catch-Finally + @try + { + // Tus declaraciones aquí + @throw [NSException exceptionWithName:@"FileNotFoundException" + reason:@"File Not Found on System" userInfo:nil]; + } @catch (NSException * e) // utiliza: @catch (id exceptionName) para atrapar + // todos los objetos + { + NSLog(@"Exception: %@", e); + } @finally + { + NSLog(@"Finally. Time to clean up."); + } // imprime => "Exception: File Not Found on System" + // "Finally. Time to clean up." + + // Los objetos NSError son útiles para argumentos de función para los + // errores de usuario. + NSError *error = [NSError errorWithDomain:@"Invalid email." code:4 userInfo:nil]; + + /////////////////////////////////////// + // Objetos + /////////////////////////////////////// + + // Crea una instancia de objeto alocando memoria e inicializándola + // Un objeto no es completamente funcional hasta que ambos pasos hayan sido + // completados + MyClass *myObject = [[MyClass alloc] init]; + + // El modelo de programación orientada a objetos de Objective-C es basada en + // el envío de mensajes a instancias de objetos + // En Objective-C no se llama a un método; se envía un mensaje + [myObject instanceMethodWithParameter:@"Steve Jobs"]; + + // Limpiar la memoria que se utilizó en el programa + [pool drain]; + + // Fin de @autoreleasepool + } + + // Fin del programa + return 0; +} + +/////////////////////////////////////// +// Clases y funciones +/////////////////////////////////////// + +// Declara tu clase en archivo de encabezado (MyClass.h) +// Sintaxis de declaración de clase: +// @interface NombreDeClase : NombreDeClasePadre <ProtocolosImplementados> +// { +// type nombre; <= declaraciones de variables; +// } +// @property tipo nombre; <= declaración de propiedades +// -/+ (tipo) Declaración de método; <= Declaración de método +// @end +@interface MyClass : NSObject <MyProtocol> // NSObject es la clase de objeto + // base de Objective-C. +{ + // Declaraciones de variables de instancia (puede existir en el archivo de + // interfaz o de implementación) + int count; // Acceso protegido por defecto. + @private id data; // Acceso privado (Más conveniente de declarar en el + // archivo de implementación) + NSString *name; +} +// Notación conveneinte para acceso público de las variables para generar un +// método setter +// Por defecto, el nombre del método setter 'set' seguido del nombre de +// variable @property +@property int propInt; // Nombre del método 'setter' = 'setPropInt' +@property (copy) id copyId; // (copy) => Copia el objeto durante la asignación +// (readonly) => No se le puede asignar un valor fuera de @interface +@property (readonly) NSString *roString; // utiliza @synthesize en + // @implementation para crear un accesor +// Puedes personalizar el nombre del getter y del setter en lugar de utilizar +// el nombre por defecto "set". +@property (getter=lengthGet, setter=lengthSet:) int length; + +// Métodos ++/- (return type)methodSignature:(Parameter Type *)parameterName; + +// + Para métodos de clase: ++ (NSString *)classMethod; ++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight; + +// - Para métodos de instancia: +- (NSString *)instanceMethodWithParameter:(NSString *)string; +- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number; + +// Métodos de constructor con argumentos +- (id)initWithDistance:(int)defaultDistance; +// Los nombres de los métodos de Objective-C son muy descriptivos. +// Siempre nombra los métodos de acuerdo con sus argumentos + +@end // Define el final de la interfaz + + +// Para acceder a las variables públicas desde el archivo de implementación, +// @property genera un método setter automáticamente. El nombre del método +// es 'set' seguido de un nombre de variable @property: +MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia del objeto MyClass +[myClass setCount:10]; +NSLog(@"%d", [myClass count]); // imprime => 10 +// O utilizando los métodos getter y setter personalizados en @interface: +[myClass lengthSet:32]; +NSLog(@"%i", [myClass lengthGet]); // imprime => 32 +// Por conveniencia, puedes utilizar la notación de punto para asignar y +// acceder a las variables de una instancia de objeto. +myClass.count = 45; +NSLog(@"%i", myClass.count); // imprime => 45 + +// Llama a métodos de clase: +NSString *classMethodString = [MyClass classMethod]; +MyClass *classFromName = [MyClass myClassFromName:@"Hello"]; + +// Llama a métodos de instancia: +MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia de objeto Myclass +NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Hello"]; + +// Selectors +// Una forma dinámica de representar métodos. Utilizados para llamar métodos +// de una clase, pasar métodos a través de funciones para avisar a otras clases +// para que lo llamen, y para guardar métodos como una variable. +// SEL es el tipo de dato. @selector() devuelve un selector del nombre de +// método proveído methodAparameterAsString:andAParameterAsNumber: es un nombre +// para un método en MyClass +SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:); +if ([myClass respondsToSelector:selectorVar]) { // Revisa si la clase contiene el método + // Debe de poner todos los argumentos de método en un solo objeto para mandar una + // función performSelector. + NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil]; + [myClass performSelector:selectorVar withObject:arguments]; // Calls the method +} else { + // NSStringFromSelector() devuelve un NSString del nombre de método de un selector dado + NSLog(@"MyClass does not have method: %@", NSStringFromSelector(selectedVar)); +} + +// Implementa los métodos de un archivo de implementación (MyClass.m): +@implementation MyClass { + long distance; // Variable de instancia de acceso privado + NSNumber height; +} + +// Para acceder a una variable pública del archivo de interfaz, utiliza '_' seguido del +// nombre de la variable: +_count = 5; // Hace referencia a "int count" de la interfaz de MyClass +// Accede variables definidas en el archivo de implementación: +distance = 18; // Hace referencia a "long distance" de la implementación de MyClass +// Para utilizar una variable @property en el archivo de implementación, utiliza +// @synthesize para crear una variable de acceso: +@synthesize roString = _roString; // _roString ahora está disponible en @implementation + +// Lamado antes de llamar algún método o instanciar cualquier objeto ++ (void)initialize +{ + if (self == [MyClass class]) { + distance = 0; + } +} + +// Contraparte para inicializar un método. Llamado cuando el contador de referencias +// del objeto es cero +- (void)dealloc +{ + [height release]; // Si no utilizas ARC, asegúrate de liberar las variables de + // objeto de las clases + [super dealloc]; // y llama el método dealloc de la clase padre +} + +// Los constructores son una manera de crear instancias de una clase +// Este es el constructor por defecto que es llamado cuando el objeto es inicializado. +- (id)init +{ + if ((self = [super init])) // 'super' es utilizado para acceder a los + // métodos de la clase padre. + { + self.count = 1; // 'self' es utilizado para que el objeto se llame a sí mismo. + } + return self; +} +// Se pueden crear constructores que contiene argumentos +- (id)initWithDistance:(int)defaultDistance +{ + distance = defaultDistance; + return self; +} + ++ (NSString *)classMethod +{ + return @"Some string"; +} + ++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight +{ + height = defaultHeight; + return [[self alloc] init]; +} + +- (NSString *)instanceMethodWithParameter:(NSString *)string +{ + return @"New string"; +} + +- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number +{ + return @42; +} + +// Objective-C no tiene declaraciones de métodos privados, pero pueden ser simulados. +// Para simular un método privado, crea un método en @implementation pero no en @interface. +- (NSNumber *)secretPrivateMethod { + return @72; +} +[self secretPrivateMethod]; // Calls private method + +// Métodos declarados dentro de MyProtocol +- (void)myProtocolMethod +{ + // statements +} + +@end // Declara el final de la implementación + +/////////////////////////////////////// +// Categorías +/////////////////////////////////////// +// Una categoría es un grupo de métodos diseñados para extender una clase. +// Te permiten agregar nuevos métodos a una clase existente por propósitos +// de organización. Éstos no deben de serconfundidos con subclases. +// Las subclases existen para CAMBIAR la funcionalidad de un objeto mientras +// que las categoríasle AGREGAN funcionalidad de un objeto. +// Las categorías te permiten: +// -- Agregar métodos a una clase existente por propósitos de oganización. +// -- Extender clases de objetos de Objective-C (ejemplo: NSString) para +// agregar tus propios métodos. +// -- Agregar la habilidad de crear métodos protegidos y privados para las clases. +// NOTA: No sobreescribas los métodos de las clases base en una categoría +// aunque tengas la habilidad de poder hacerlo. Sobreescribir métodos puede +// causar errores en la compilación después entre diferentes categorías y +// puede arruinar el propósito de las categorías de solo AGREGAR funcionalidad. +// Utiliza subclass para sobreescribir métodos. + +// Aquí una clase base simple, Car. +@interface Car : NSObject + +@property NSString *make; +@property NSString *color; + +- (void)turnOn; +- (void)accelerate; + +@end + +// Y la implementación de la clase simple, Car +#import "Car.h" + +@implementation Car + +@synthesize make = _make; +@synthesize color = _color; + +- (void)turnOn { + NSLog(@"Car is on."); +} +- (void)accelerate { + NSLog(@"Accelerating."); +} + +@end + +// Ahora, si quisieramos crear un objeto Truck (Camión), crearíamos una +// subclase de Car (Carro) como si le cambiaramos de funcionalidad de Car +// para que se comporte como un camión. Pero digamos que únicamente queremos +// agregar funcionalidad al Car (Carro) existente. Un buen ejemplo sería +// limpiar el carro. Así que crearíamos una cateog®iea para agregar los +// métodos de limpieza: +// Archivo @interface: Car+Clean.h (NombreBaseDeClase+NombreDeCategoria.h) +#import "Car.h" // Asegúrate de improtar la clase que deseas extener. + +@interface Car (Clean) // El nombre de la categoría está dentro de (), + // seguido del nombre de la clase base + +- (void)washWindows; // Nombres de los nuevos métodos que le agregamos + // a nuestro objeto Car +- (void)wax; + +@end + +// Archivo @implementation: Car+Clean.m (NombreBaseDeClase+NombreDeCategoria.m) +#import "Car+Clean.h" // Importa el archivo de @interface de la categoría Clean + +@implementation Car (Clean) + +- (void)washWindows { + NSLog(@"Windows washed."); +} +- (void)wax { + NSLog(@"Waxed."); +} + +@end + +// Cualquier instancia del objeto Car tiene la habilidad de utilizar una +// categoría. Todo lo que necesitan es importarlo: +#import "Car+Clean.h" // Importa todas las diferentes categorías que + // necesites utilizar +#import "Car.h" // También debes de importar la clase base para su + // funcionalidad original + +int main (int argc, const char * argv[]) { + @autoreleasepool { + Car *mustang = [[Car alloc] init]; + mustang.color = @"Red"; + mustang.make = @"Ford"; + + [mustang turnOn]; // Utiliza métodos de la clase base Car. + [mustang washWindows]; // Utiliza métodos de la categoría Clean de Car. + } + return 0; +} + +// Objective-C no tiene declaraciones para métodos protegidos, pero los puedes +// simular. Crea una categoría conteniendo todos los métodos protegidos, +// luego importa ÚNICAMENTE al archivo @implementation de una clase que +// pertenece a la clase Car. +@interface Car (Protected) // Nombrando la categoría 'Protected' para + // recordar que los métodos están protegidos + +- (void)lockCar; // Los métodos enlistados aquí solo puedens ser creados + // por objetos Car + +@end +// Para utilizar los métodos protegidos, importa la categoría, +// luego implementa sus métodos: +#import "Car+Protected.h" // Recuerda, importa únicamente el archivo + // de @implementation + +@implementation Car + +- (void)lockCar { + NSLog(@"Car locked."); // Las instancias de Car no puede utilizar + // lockCar porque no se encuentra en @interface +} + +@end + +/////////////////////////////////////// +// Extensiones +/////////////////////////////////////// +// Las Extensions te permiten sobreescribir atributos de propiedades de +// acceso público y métodos de un @interface +// Archivo @interface: Shape.h +@interface Shape : NSObject + +@property (readonly) NSNumber *numOfSides; + +- (int)getNumOfSides; + +@end +// Puedes sobreescribir la variable numOfSides o el métodos getNumOfSlides +// para modificarlos con una extensión: +// Archivo @implementation: Shape.m +#import "Shape.h" +// Las extensiones se encuentran en el mismo archivo que el archivo +// de @implementation +@interface Shape () // () después del nombre de la clase base declara + // una extensión + +@property (copy) NSNumber *numOfSides; // Hacer numOfSlides copy en lugar + // de readonly. +-(NSNumber)getNumOfSides; // Hacer que getNumOfSides devuelva un NSNumber + // en lugar de un int. +-(void)privateMethod; // También puedes crear una nuevos métodos privados + // dentro de las extensiones + +@end +// @implementation principal: +@implementation Shape + +@synthesize numOfSides = _numOfSides; + +-(NSNumber)getNumOfSides { // Todas las declaraciones dentro de extensions + // deben de ser dentro de @implementation + return _numOfSides; +} +-(void)privateMethod { + NSLog(@"Private method created by extension. Shape instances cannot call me."); +} + +@end + +/////////////////////////////////////// +// Protocolos +/////////////////////////////////////// +// Un protocolo declara métodos que pueden ser implementados por cualquier otra +// clase. Los protocolos no son clases. Simplementen define una interfaz que +// otros objetos deben de implementar. +// Archivo @protocol: "CarUtilities.h" +@protocol CarUtilities <NSObject> // <NSObject> => Nombre de otro protocolo + // que se incluye en éste + @property BOOL engineOn; // La clase que lo adopta debe de utilizar + // @synthesize para todas las @properties definidas + - (void)turnOnEngine; // y todos los métodos definidos +@end +// A continuación una clase ejemplo que implementa el protcolo +#import "CarUtilities.h" // Importar el archivo @protocol. + +@interface Car : NSObject <CarUtilities> // El nombre del protocolo dentro de <> + // No necesitas los nombres de @property o métodos aquí para CarUtilities. + // Estos solo es requerido por @implementation. +- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // También Puedes + // utilizar protocolos + // como datos. +@end +// El @implementation necesita que se implementen @properties y métodos +// del protocolo. +@implementation Car : NSObject <CarUtilities> + +@synthesize engineOn = _engineOn; // Crear una declaración @synthesize para el + // @property engineOn. + +- (void)turnOnEngine { // Implementa turnOnEngine como quieras. Los + // protocolos no definen + _engineOn = YES; // cómo implementas un método, con tal de que lo implementes. +} +// Puedes utilizar un protocolo como data mientras sepas quee métodos y variables +// tiene implementado. +- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind { + [objectOfSomeKind engineOn]; // Tienes acceso a las variables + [objectOfSomeKind turnOnEngine]; // y los métodos del objeto + [objectOfSomeKind engineOn]; // Puede o no puede ser YES. La clase lo + // implementa como se quiera. +} + +@end +// Las instancias de Car ahora tienen acceso al protocolo. +Car *carInstance = [[Car alloc] init]; +[carInstance setEngineOn:NO]; +[carInstance turnOnEngine]; +if ([carInstance engineOn]) { + NSLog(@"Car engine is on."); // imprime => "Car engine is on." +} +// Asegúrate de revisar si un objeto de tipo 'id' implementa un protocolo antes +// de llamar a sus métodos: +if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { + NSLog(@"This does not run as the MyClass class does not implement the CarUtilities protocol."); +} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) { + NSLog(@"This does run as the Car class implements the CarUtilities protocol."); +} +// Las categorías también pueden implementar protcolos: @interface Car +// (CarCategory) <CarUtilities> +// Puedes implementar varios protocolos: +// @interface Car : NSObject <CarUtilities, CarCleaning> +// NOTA: Si dos o más protocolos dependen entre sí, asegúrate de declararlos +// de manera adelantada: +#import "Brother.h" + +@protocol Brother; // Declaración adelantada. Sin ésto, el compilador + // tira un error. + +@protocol Sister <NSObject> + +- (void)beNiceToBrother:(id <Brother>)brother; + +@end + +// Ver si el problema es que Sister depende de Brother, +// y Brother dependa de Sister. +#import "Sister.h" + +@protocol Sister; // Estas líneas detienen la recursión, resolviendo el problema. + +@protocol Brother <NSObject> + +- (void)beNiceToSister:(id <Sister>)sister; + +@end + + +/////////////////////////////////////// +// Bloques +/////////////////////////////////////// +// Los bloques son declaraciones de código, tal como una función, pueden +// ser utilizados como data. +// A continuación un bloque simple con un argumento entero que devuelve +// un el argumento más 4. +int (^addUp)(int n); // Declarar una variable para almacenar el bloque. +void (^noParameterBlockVar)(void); // Ejemplo de una declaración de variable + // de bloque sin argumentos. +// Los bloques tienen acceso a variables del mismo ámbito. Pero las variables +// son solo readonly y el valor pasado al bloque es el valor de la variable +// cuando el bloque es creado. +int outsideVar = 17; // Si modificamos outsideVar después de declarar addUp, + // outsideVar AÚN es 17. +__block long mutableVar = 3; // __block hace que las variables se puedan + // escribir en bloques. +addUp = ^(int n) { // Remueve (int n) para tener un bloque que no recibe + // ningún parámetro + NSLog(@"You may have as many lines in a block as you would like."); + NSSet *blockSet; // También puedes declarar variables locales. + mutableVar = 32; // Asignar un nuevo valor a la variable __block. + return n + outsideVar; // Declaraciones de retorno son opcionales. +} +int addUp = add(10 + 16); // Llama al bloque de código con argumentos. +// Los bloques son usualmente utilizados como argumentos a funciones que +// son llamados más adelante o para callbacks. +@implementation BlockExample : NSObject + + - (void)runBlock:(void (^)(NSString))block { + NSLog(@"Block argument returns nothing and takes in a NSString object."); + block(@"Argument given to block to execute."); // Calling block. + } + + @end + + +/////////////////////////////////////// +// Manejo de memoria +/////////////////////////////////////// +/* +Para cada objeto utilizado en una aplicación, la memoria debe de ser alocada +para ese objeto. Cuando la aplicación termina de utilizar ese objeto, la +memoria debe de ser desalocada para asegurar la eficiencia de la aplicación. +Objetive-C no utiliza garbage collection, y en lugar de eso utiliza conteos +de referencias. Mientras haya al menos una referencia del objeto (también +conocido como tener un objeto de adueñado), entonces el objeto estará +disponible para su uso. + +Cuando una instancia es dueña un objeto, su contador de referencia incrementa +por uno. Cuando el objeto es liberado, el contador de referencia decrementa uno. +Cuando el conteo de referencia es cero, el objeto es removido de la memoria. + +Con todas las interacciones de los objetos, sigue el patrón de: +(1) Crear e lobjeto, (2) utiliza el objeto, (3) libera el objeto de la memoria. +*/ + +MyClass *classVar = [MyClass alloc]; // 'alloc' asigna uno al conteo de + // referencias de classVar. Devuelve un + // puntero al objeto +[classVar release]; // Decrementa el conteo de referencias de classVar's +// 'retain' +// 'retain' adueña la instancia de objeto existente e incrementa el conteo de +// referencia por uno. Devuelve un puntero al objeto. +MyClass *newVar = [classVar retain]; // Si classVar es liberado, el objeto + // aún se queda en memoria porque newVar + // es el dueño. +[classVar autorelease]; // Remueve el adueñamiento de un objeto al final del + // bloque @autoreleasepool. Devuelve un puntero al objeto. + +// @property puede utilizar 'retain' y 'assign' también para pequeñas +// definiciones convenientes +@property (retain) MyClass *instance; // Libera el valor viejo y retiene + // uno nuevo (referencia fuerte) +@property (assign) NSSet *set; // Apunta a un nuevo valor sin retener/liberar + // una referencia vieja (débil) + +// Conteo Automático de Referencias (ARC) +// Debido a que el manejo de memoria puede ser un dolor, en Xcode 4.2 y iOS 4 +// se introdujo el Conteo Automático de Referencias (ARC). +// ARC es una funcionalidad del compilador que agrega retain, release y +// autorealase automáticamente, así que al +// utilizar ARC, no se debe de utilizar retain, release o autorelease. +MyClass *arcMyClass = [[MyClass alloc] init]; +// ... código utilizando arcMyClass +// Sin ARC, necesitarás llamar: [arcMyClass release] luego de terminar de +// utilizar arcMyClass. Pero con ARC, no hay necesidad. Insertará +// automáticamente la declaración de liberación. + +// Mientras que para los atributos de @property 'assign' y 'retain', con ARC +// utilizarás 'weak' y 'strong' +@property (weak) MyClass *weakVar; // 'weak' no adueña el objeto. El conteo de + // referencias de la instancia original +// es fijado a ceor, weakVar automáticamente recibe el valor de nil para +// evitar cualquier 'crashing'. +@property (strong) MyClass *strongVar; // 'strong' se adueña del objeto. + // Asegura que el objeto se quede en memoria. + +// Para variables regulares (no variables de @property), utiliza lo siguiente: +__strong NSString *strongString; // Por defecto. La variables de retenida en + // memoria hasta que se salga del ámbito. +__weak NSSet *weakSet; // Referencia débil a un objeto existente. Cuando el + // objeto existente es liberado, weakSet le es asginado + // un valor nil +__unsafe_unretained NSArray *unsafeArray; // Como __weak, pero unsafeArray no + // es asginado a nil cuando el objeto + // existente es liberado. + +``` +## Lecturas sugeridas + +[Wikipedia Objective-C](http://es.wikipedia.org/wiki/Objective-C) + +[Programming with Objective-C. Libro PDF de Apple](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/ProgrammingWithObjectiveC.pdf) + +[iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started) diff --git a/es-es/php-es.html.markdown b/es-es/php-es.html.markdown new file mode 100644 index 00000000..fa52353c --- /dev/null +++ b/es-es/php-es.html.markdown @@ -0,0 +1,825 @@ +--- +language: PHP +contributors: + - ["Malcolm Fell", "http://emarref.net/"] + - ["Trismegiste", "https://github.com/Trismegiste"] +translators: + - ["Mario Pérez", "https://github.com/MarioPerezEsteso"] +lang: es-es +filename: learnphp-es.php +--- + +Este documento explica el funcionamiento de PHP 5+. + +```php +<?php // El código PHP debe estar dentro de etiquetas <?php + +// Si tu fichero php solo contiene código php, es una buena práctica +// omitir la etiqueta de cierre php para prevenir salidas acidentales. + +// Dos barras comienzan un comentario de una línea. + +# También lo hará una almohadilla, pero // es más común + +/* + Escribir texto entre una barra-asterisco y asterisco-barra + crea un comentario multilínea. +*/ + +// Utiliza "echo" o "print" para imprimir por pantalla +print('Hola '); // Imprime "Hola " sin salto de línea + +// () son opcionales para print y echo +echo "Mundo\n"; // Imprime "Mundo" con un salto de línea +// (todas las sentencias deben finalizar con un punto y coma) + +// Cualquier cosa fuera de las etiquetas <?php se imprime automáticamente +?> +¡Hola Mundo de nuevo! +<?php + + +/************************************ + * Tipos y variables + */ + +// Las variables comienzan con el símbolo $. +// Una variable válida comienza con una letra o guión bajo, +// seguida de cualquier cantidad de letras, números o guiones bajos. + +// Las variables booleanas no distinguen entre mayúsculas o minúsculas +$boolean = true; // o TRUE o True +$boolean = false; // o FALSE o False + +// Enteros +$int1 = 12; // => 12 +$int2 = -12; // => -12 +$int3 = 012; // => 10 (un 0 al comienzo declara un número octal) +$int4 = 0x0F; // => 15 (un 0x al comienzo declara un hexadecimal) + +// Floats (también conocidos como doubles) +$float = 1.234; +$float = 1.2e3; +$float = 7E-10; + +// Eliminar variable +unset($int1); + +// Operaciones aritméticas +$suma = 1 + 1; // 2 +$diferencia = 2 - 1; // 1 +$producto = 2 * 2; // 4 +$cociente = 2 / 1; // 2 + +// Operaciones aritméticas de escritura rápida +$numero = 0; +$numero += 1; // Incrementa $numero en 1 +echo $numero++; // Imprime 1 (incremento después la evaluación) +echo ++$numero; // Imprime 3 (incremento antes de la evaluación) +$numero /= $float; // Divide y asigna el cociente a $numero + +// Las cadenas de caracteres deben declararse entre comillas simples +$sgl_quotes = '$String'; // => '$String' + +// Evita utilizar comillas dobles excepto para embeber otras variables +$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.' + +// Los caracteres especiales solo son válidos entre comillas dobles +$escaped = "Esto contiene \t un caracter tabulador."; +$unescaped = 'Esto solo contiene una barra y una t: \t'; + +// Rodea una variable entre corchetes si es necesario +$dinero = "Tengo $${numero} en el banco."; + +// Desde PHP 5.3, los nowdocs pueden ser utilizados para multilíneas no interpoladas +$nowdoc = <<<'END' +Multi line +string +END; + +// Heredocs interpola cadenas de caracteres +$heredoc = <<<END +Multi line +$sgl_quotes +END; + +// La concatenación de cadenas de caracteres se realiza con . +echo 'Esta cadena de caracteres ' . 'está concatenada'; + +// Las cadenas de caracteres pueden ser pasadas como parámetros en un echo +echo 'Multiples', 'Parametros', 'Validos'; // Devuelve 'MultiplesParametrosValidos' + + +/******************************** + * Constantes + */ + +// Una constante se define utilizando define() +// y nunca puede ser cambiada en tiempo de ejecución + +// un nombre válido para una constante debe comenzar con una letra o guión bajo, +// seguido por cualquier número de letras, números o guiones bajos. +define("FOO", "algo"); + +// el acceso a una constante se puede realizar llamando a la variable elegida sin un símbolo de $ +echo FOO; // Devuelve 'algo' +echo 'Esto imprime '.FOO; // Devuelve 'Esto imprime algo' + + + +/******************************** + * Arrays + */ + +// Todos los arrays en PHP son asociativos (hashmaps), + +// Los arrays asociativos son conocidos como hashmaps en algunos lenguajes. + +// Funciona con todas las versiones de php +$asociativo = array('Uno' => 1, 'Dos' => 2, 'Tres' => 3); + +// PHP 5.4 introdujo una nueva sintaxis +$asociativo = ['Uno' => 1, 'Dos' => 2, 'Tres' => 3]; + +echo $asociativo['Uno']; // imprime 1 + +// Lista literales implícitamente asignados con claves enteras +$array = ['Uno', 'Dos', 'Tres']; +echo $array[0]; // => "Uno" + +// Añadir un elemento al final de un array +$array[] = 'Cuatro'; +// o +array_push($array, 'Cinco'); + +// Eliminar un elemento de un array +unset($array[3]); + +/******************************** + * Salidas por pantalla + */ + +echo('¡Hola Mundo!'); +// Imprime ¡Hola Mundo! en stdout. +// Stdout es la página web si se está ejecutando en un navegador. + +print('!Hola Mundo!'); // Es lo mismo que echo + +// No es necesario el paréntesis en echo y print +echo '¡Hola Mundo!'; +print '¡Hola Mundo!'; + +$parrafo = 'parrafo'; + +echo 100; // Haz echo de escalares directamente +echo $parrafo; // o de variables + +// Si las etiquetas cortas estás configuradas y tu versión de PHP es +// la 5.4.0 o superior, puede utilizar la sintaxis abreviada de echo +?> +<p><?= $parrafo?></p> +<?php + +$x = 1; +$y = 2; +$x = $y; // $x ahora contiene el mismo valor que $y +$z = &$y; +// $z contiene ahora una referencia a $y. Un cambio en el valor de +// $z cambiará también el valor de $y, y viceversa. +// $x sin embargo, tendrá el valor original de $y + +echo $x; // => 2 +echo $z; // => 2 +$y = 0; +echo $x; // => 2 +echo $z; // => 0 + +// Dump muestra el tipo y valor de una variable en stdout +var_dump($z); // imprime int(0) + +// Para mostrar el valor de una variable en un formato legible para humanos +print_r($array); // imprime: Array ( [0] => Uno [1] => Dos [2] => Tres ) + +/******************************** + * Lógica + */ +$a = 0; +$b = '0'; +$c = '1'; +$d = '1'; + +// assert lanza una advertencia si su argumento no es verdadero + +// Estas comparaciones siempre serán verdaderas, incluso si los tipos no son los mismos. +assert($a == $b); // igualdad +assert($c != $a); // desigualdad +assert($c <> $a); // desigualdad alternativa +assert($a < $c); +assert($c > $b); +assert($a <= $b); +assert($c >= $d); + +// Los siguiente solo será verdadero si los valores coinciden y son del mismo tipo. +assert($c === $d); +assert($a !== $d); +assert(1 === '1'); +assert(1 !== '1'); + +// Operador 'Spaceship' (desde PHP 7) +// Devuelve 0 si ambos valores son iguales +// Devuelve 1 si el valor de la izquierda es mayor +// Devuelve -1 si el valor de la derecha es mayor + +$a = 100; +$b = 1000; + +echo $a <=> $a; // 0 porque son iguales +echo $a <=> $b; // -1 porque $a < $b +echo $b <=> $a; // 1 porque $b > $a + +// Las variables pueden ser convertidas entre tipos, dependiendo de su uso. + +$entero = 1; +echo $entero + $entero; // => 2 + +$string = '1'; +echo $string + $string; // => 2 (los strings son convertidos a enteros) + +$string = 'uno'; +echo $string + $string; // => 0 +// Muestra un 0 porque el operador + no puede convertir la cadena de caracteres 'uno' a un número + +// La conversión de tipos puede ser utilizada para tratar a una variable como otro tipo + +$boolean = (boolean) 1; // => true + +$cero = 0; +$boolean = (boolean) $cero; // => false + +// También hay funciones dedicadas a la conversión de tipos +$entero = 5; +$string = strval($entero); + +$var = null; // Valor nulo + + +/******************************** + * Estructuras de control + */ + +if (true) { + print 'He sido imprimido'; +} + +if (false) { + print 'Yo no'; +} else { + print 'He sido imprimido'; +} + +if (false) { + print 'No se imprime'; +} elseif(true) { + print 'Sí se imprime'; +} + +// operador ternario +print (false ? 'No se imprime' : 'Sí se imprime'); + +// atajo para el operador ternario desde PHP 5.3 +// equivalente de "$x ? $x : 'Sí'"" +$x = false; +print($x ?: 'Sí'); + +// operador 'no definido' desde php 7 +$a = null; +$b = 'Imprime'; +echo $a ?? 'a no está definido'; // imprime 'a no está definido' +echo $b ?? 'b no está definido'; // imprime 'Imprime' + + +$x = 0; +if ($x === '0') { + print 'No imprime'; +} elseif($x == '1') { + print 'No imprime'; +} else { + print 'Imprime'; +} + + + +// Esta sintaxis alternativa se utiliza para plantillas: +?> + +<?php if ($x): ?> +Esto se muestra si la evaluación es verdadera. +<?php else: ?> +En otro caso, se muestra esto. +<?php endif; ?> + +<?php + +// Utiliza el switch para tener algo más de lógica. +switch ($x) { + case '0': + print 'Switch does type coercion'; + break; // Debes incluir un break para no seguir con los casos 'Dos' y 'Tres' + case 'Dos': + case 'Tres': + // Hacer algo si la variables es 'Dos' o 'Tres' + break; + default: + // Hacer algo por defecto +} + +// Los bucles While, do...while y for te serán familiares +$i = 0; +while ($i < 5) { + echo $i++; +}; // Imprime "01234" + +echo "\n"; + +$i = 0; +do { + echo $i++; +} while ($i < 5); // Imprime "01234" + +echo "\n"; + +for ($x = 0; $x < 10; $x++) { + echo $x; +} // Imprime "0123456789" + +echo "\n"; + +$ruedas = ['bicicleta' => 2, 'coche' => 4]; + +// Los bucles foreach pueden iterar por arrays +foreach ($ruedas as $numero_ruedas) { + echo $numero_ruedas; +} // Imprime "24" + +echo "\n"; + +// También se puede iterar sobre las claves, así como sobre los valores +foreach ($ruedas as $vehiculo => $numero_ruedas) { + echo "Un $vehiculo tiene $numero_ruedas ruedas"; +} + +echo "\n"; + +$i = 0; +while ($i < 5) { + if ($i === 3) { + break; // Sale fuera del bucle while + } + echo $i++; +} // Imprime "012" + +for ($i = 0; $i < 5; $i++) { + if ($i === 3) { + continue; // Se salta esta iteración del bucle + } + echo $i; +} // Imprime "0124" + + +/******************************** + * Funciones + */ + +// Define una función con "function": +function mi_funcion () { + return 'Hola'; +} + +echo mi_funcion(); // => "Hola" + +// Un nombre válido de función comienza con una letra o guión bajo, seguido de cualquier +// número de letras, números o guiones bajos. + +function anadir ($x, $y = 1) { // $y es opcional y por defecto es 1 + $resultado = $x + $y; + return $resultado; +} + +echo anadir(4); // => 5 +echo anadir(4, 2); // => 6 + +// $resultado no es accesible fuera de la función +// print $resultado; // Devuelve una advertencia. + +// Desde PHP 5.3 se pueden declarar funciones anónimas +$inc = function ($x) { + return $x + 1; +}; + +echo $inc(2); // => 3 + +function foo ($x, $y, $z) { + echo "$x - $y - $z"; +} + +// Las funciones pueden devolver funciones +function bar ($x, $y) { + // Utiliza 'use' para meter variables de fuera de la función + return function ($z) use ($x, $y) { + foo($x, $y, $z); + }; +} + +$bar = bar('A', 'B'); +$bar('C'); // Imprime "A - B - C" + +// Puedes llamar a funciones utilizando cadenas de caracteres +$nombre_funcion = 'add'; +echo $nombre_funcion(1, 2); // => 3 +// Es útil para determinarl qué función ejecutar. +// O, utiliza call_user_func(callable $callback [, $parameter [, ... ]]); + + +// Puedes obtener todos los parámetros pasados a una función +function parametros() { + $numero_argumentos = func_num_args(); + if ($numero_argumentos > 0) { + echo func_get_arg(0) . ' | '; + } + $args_array = func_get_args(); + foreach ($args_array as $key => $arg) { + echo $key . ' - ' . $arg . ' | '; + } +} + +parametros('Hola', 'Mundo'); // Hola | 0 - Hola | 1 - Mundo | + +// Desde PHP 5.6 se puede obtener un número variable de argumentos +function variable($palabra, ...$lista) { + echo $palabra . " || "; + foreach ($lista as $item) { + echo $item . ' | '; + } +} + +variable("Separa", "Hola", "Mundo") // Separa || Hola | Mundo | + +/******************************** + * Includes + */ + +<?php +// Los ficheros PHP incluidos deben comenzar también con la etiqueta de <?php + +include 'mi-fichero.php'; +// El código de mi-fichero.php ya está disponible en el entorno actual. +// Si el fichero no puede ser incluido (por ejemplo porque no se ha encontrado), +// se muestra una advertencia. + +include_once 'mi-fichero.php'; +// Si el código del fichero mi-fichero.php ya ha sido incluido, ya no se +// incluirá de nuevo. Este previene errores por múltiples declaraciones. + +require 'mi-fichero.php'; +require_once 'mi-fichero.php'; +// Es lo mismo que el include(), pero require() causará un error fatal si el archivo +// no ha podido ser incluido. + +// Contenido de mi-include.php: +<?php + +return 'Cualquier cosa.'; +// acabar archivo + +// Los include y require también pueden devolver un valor. +$valor = include 'mi-include.php'; + +// Los archivos son incluidos en función de la ruta data o, si ninguna ruta es +// especificada se utilizará la directiva de configuración de include_path. Si el +// fichero no se encuentra en el include_path, include comprobará la ruta del código +// que lo llama antes de fallar. +/* */ + +/******************************** + * Clases + */ + +// Las clases son definidas con la palabra clave class + +class MiClase +{ + const MI_CONSTANTE = 'valor'; // Una constante + + static $staticVar = 'static'; + + // Las variables estáticas y su visibilidad + public static $publicStaticVar = 'publicStatic'; + // Accesible solo dentro de su clase + private static $privateStaticVar = 'privateStatic'; + // Accesible desde la clase y las subclases + protected static $protectedStaticVar = 'protectedStatic'; + + // Las propiedades deben declarar su visibilidad + public $propiedad = 'public'; + public $instanceProp; + protected $prot = 'protected'; // Accesible desde la clase y las subclases + private $priv = 'private'; // Accesible solo desde la clase + + // Crear un constructor con __construct + public function __construct($instanceProp) { + // Accede a las variables de la instancia con $this + $this->instanceProp = $instanceProp; + } + + // Los métodos son declarados como funciones dentro de una clase + public function miMetodo() + { + print 'MiClase'; + } + + // la palabra clave final hará una función no sobreescribible + final function noMePuedesSobreEscribir() + { + } + +/* + * Declarar propiedades de clase o métodos como estáticos los hace accesibles sin + * necesidad de instanciar la clase. Una propiedad declarada como estática no + * puede ser accedida mediante una instancia de la clase, pero sí mediante un + * método estático. + */ + + public static function miMetodoEstatico() + { + print 'Soy estático'; + } +} + +// Las constantes de una clase siempre pueden ser accedidas estáticamente +echo MiClase::MI_CONSTANTE; // Muestra 'valor'; + +echo MiClase::$staticVar; // Muestra 'static'; +MiClase::miMetodoEstatico(); // Muestra 'Soy estático'; + +// Instancia una clase usando new +$mi_clase = new MiClase('Una instancia'); +// Los paréntesis son opcionales si no se pasa ningún argumento. + +// Accede a los miembros de una clase utilizando -> +echo $mi_clase->propiedad; // => "public" +echo $mi_clase->instanceProp; // => "Una instancia" +$mi_clase->miMetodo(); // => "MiClase" + + +// Extender clases utilizando "extends" +class MiOtraClase extends MiClase +{ + function imprimePropiedadProtegida() + { + echo $this->prot; + } + + // Sobreescribe un método + function miMetodo() + { + parent::miMetodo(); + print ' > MiOtraClase'; + } +} + +$mi_otra_clase = new MiOtraClase('Propiedad de instancia'); +$mi_otra_clase->imprimePropiedadProtegida(); // => Imprime "protected" +$mi_otra_clase->miMetodo(); // Imprime "MiClase > MiOtraClase" + +final class NoMePuedesExtender +{ +} + +// Puedes utilizar "métodos mágicos" para crear los getters y setters +class MiClaseMapeada +{ + private $propiedad; + + public function __get($key) + { + return $this->$key; + } + + public function __set($key, $value) + { + $this->$key = $value; + } +} + +$x = new MiClaseMapeada(); +echo $x->propiedad; // Utilizará el método __get() +$x->propiedad = 'Algo'; // Utilizará el método __set() + +// Las clases pueden ser abstractas (utilizando la palabra clave abstract) o +// implementando interfaces (utilizando la palabra clave implements). +// Una interfaz puede ser declarada con la palabra clave interface. + +interface InterfazUno +{ + public function hazAlgo(); +} + +interface InterfazDos +{ + public function hazOtraCosa(); +} + +// las interfaces pueden ser extendidas +interface InterfazTres extends InterfazDos +{ + public function hazCualquierOtraCosa(); +} + +abstract class MiClaseAbstracta implements InterfazUno +{ + public $x = 'hazAlgo'; +} + +class MiOtraClase extends MiClaseAbstracta implements InterfazDos +{ + public function hazAlgo() + { + echo $x; + } + + public function hazOtraCosa() + { + echo 'hazOtraCosa'; + } +} + + +// Las clases pueden implementar más de una interfaz +class CualquierOtraClase implements InterfazUno, InterfazDos +{ + public function hazAlgo() + { + echo 'hazAlgo'; + } + + public function hazOtraCosa() + { + echo 'hazOtraCosa'; + } +} + + +/******************************** + * Traits + */ + +// Los traits están disponibles desde PHP 5.4.0 y son declarados utilizando "trait" + +trait MiTrait +{ + public function miMetodoTrait() + { + print 'Tengo trait'; + } +} + +class MiClaseTrait +{ + use MiTrait; +} + +$cls = new MiClaseTrait(); +$cls->miMetodoTrait(); // Imprime "Tengo trait" + + +/******************************** + * Namespaces + */ + +// Esta sección está separada porque una declaración de namespace debe +// ser la primera sentencia en un archivo. Vamos a suponer que no es el caso + +<?php + +// Por defecto, las clases existen en el namespace global y pueden ser llamadas +// explícitamente con una contrabarra. + +$cls = new \MiClase(); + + + +// Estableder el namespace para un archivo +namespace Mi\Namespace; + +class MiClase +{ +} + +// (de otro archivo) +$cls = new Mi\Namespace\MiClase; + +// O de otro namespace. +namespace Mi\Otro\Namespace; + +use Mi\Namespace\MiClase; + +$cls = new MiClase(); + +// O se puede asignar un ales al namespace + +namespace Mi\Otro\Namespace; + +use Mi\Namespace as OtroNamespace; + +$cls = new OtroNamespace\MiClase(); + + +/********************** +* Late Static Binding +* +*/ + +class ClasePadre { + public static function quien() { + echo "Soy una " . __CLASS__ . "\n"; + } + public static function test() { + // Auto referencia a la clase en la que el método está definido + self::quien(); + // Referencia estáticamente a la clase donde el método ha sido llamado + static::quien(); + } +} + +ClasePadre::test(); +/* +Soy una ClasePadre +Soy una ClasePadre +*/ + +class ClaseHija extends ClasePadre { + public static function quien() { + echo "Pero soy una " . __CLASS__ . "\n"; + } +} + +ClaseHija::test(); +/* +Soy una ClasePadre +Pero soy una ClaseHija +*/ + + +/********************** +* Manejo de errores +* +*/ + +// Una simple gestión de errores puede ser realizada con un bloque try catch + +try { + // Haz algo +} catch (Exception $e) { + // Maneja la excepción +} + +// Cuando se utilicen bloques try catch en un entorno con namespaces hay que +// usar lo siguiente + +try { + // Haz algo +} catch (\Exception $e) { + // Maneja la excepción +} + +// Excepciones personalizadas + +class MiExcepcion extends Exception {} + +try { + + $condicion = true; + + if ($condicion) { + throw new MiExcepcion('Ha pasado algo'); + } + +} catch (MiExcepcion $e) { + // Manejar la excepción +} + +``` + +## Más información + +Visita la [documentación oficial de PHP](http://www.php.net/manual/) para más referencias +y apoyo de la comunidad. + +Si estás interesado en buenas prácticas, visita +[PHP The Right Way](http://www.phptherightway.com/). + +Si vienes de un lenguaje con una buena gestión de paquetes, visita +[Composer](http://getcomposer.org/). + +Para estándares comunes, visita el PHP Framework Interoperability Group +[PSR standards](https://github.com/php-fig/fig-standards). diff --git a/es-es/python3-es.html.markdown b/es-es/python3-es.html.markdown index 1c69481a..05fd7065 100644 --- a/es-es/python3-es.html.markdown +++ b/es-es/python3-es.html.markdown @@ -97,7 +97,7 @@ not False # => True 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 @@ -383,7 +383,7 @@ def keyword_args(**kwargs): keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"} -# You can do both at once, if you like# Puedes hacer ambas a la vez si quieres +# Puedes hacer ambas a la vez si quieres def todos_los_argumentos(*args, **kwargs): print args print kwargs @@ -478,7 +478,7 @@ Humano.roncar() #=> "*roncar*" # Puedes importar módulos import math -print(math.sqrt(16)) #=> 4 +print(math.sqrt(16)) #=> 4.0 # Puedes obtener funciones específicas desde un módulo from math import ceil, floor @@ -511,7 +511,7 @@ def duplicar_numeros(iterable): for i in iterable: yield i + i -# Un generador cera valores sobre la marcha. +# 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. diff --git a/es-es/r-es.html.markdown b/es-es/r-es.html.markdown new file mode 100644 index 00000000..2b710b27 --- /dev/null +++ b/es-es/r-es.html.markdown @@ -0,0 +1,717 @@ +--- +language: R +contributors: + - ["e99n09", "http://github.com/e99n09"] + - ["isomorphismes", "http://twitter.com/isomorphisms"] +translators: + - ["David Hsieh", "http://github.com/deivuh"] +lang: es-es +filename: learnr-es.r +--- + +R es un lenguaje de computación estadística. Tiene muchas librerías para cargar +y limpiar sets de datos, ejecutar procedimientos estadísticos y generar +gráficas. También puedes ejecutar comandos `R` dentro de un documento de +LaTeX. + +```r + +# Los comentariso inician con símbolos numéricos. + +# No puedes hacer comentarios de múltiples líneas +# pero puedes agrupar múltiples comentarios de esta manera. + +# En Windows puedes utilizar CTRL-ENTER para ejecutar una línea. +# En Mac utilizas COMMAND-ENTER + + +############################################################################# +# Cosas que puedes hacer sin entender nada acerca de programación +############################################################################# + +# En esta sección, mostramos algunas cosas chileras / cool que puedes hacer en +# R sin entender nada de programación. No te preocupes en entender nada +# de lo que hace este código. Solo disfruta! + +data() # Examinar sets de datos pre-cargados +data(rivers) # Obtiene este: Lengths of Major North American Rivers" +ls() # Fijarse que "rivers" ahora aparece en el workspace +head(rivers) # Echarle un ojo al set de datos +# 735 320 325 392 524 450 + +length(rivers) # ¿Cuántos ríos fueron medidos? +# 141 +summary(rivers) # ¿Cuáles son algunas estadísticas generales? +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 135.0 310.0 425.0 591.2 680.0 3710.0 + +# Generar una gráfica tallo-y-hoja (Visualización de datos tipo histograma) +stem(rivers) + +# El punto decimal son 2 dígitos a la derecha de | +# +# 0 | 4 +# 2 | 011223334555566667778888899900001111223333344455555666688888999 +# 4 | 111222333445566779001233344567 +# 6 | 000112233578012234468 +# 8 | 045790018 +# 10 | 04507 +# 12 | 1471 +# 14 | 56 +# 16 | 7 +# 18 | 9 +# 20 | +# 22 | 25 +# 24 | 3 +# 26 | +# 28 | +# 30 | +# 32 | +# 34 | +# 36 | 1 + +stem(log(rivers)) # Fijarse que la data no es normal ni log-normal! +# Toma eso, fundamentalistas de la curva de campana! + +# El punto decimal está a 1 dígito a la izquierda del | +# +# 48 | 1 +# 50 | +# 52 | 15578 +# 54 | 44571222466689 +# 56 | 023334677000124455789 +# 58 | 00122366666999933445777 +# 60 | 122445567800133459 +# 62 | 112666799035 +# 64 | 00011334581257889 +# 66 | 003683579 +# 68 | 0019156 +# 70 | 079357 +# 72 | 89 +# 74 | 84 +# 76 | 56 +# 78 | 4 +# 80 | +# 82 | 2 + +# Generar un histograma: +hist(rivers, col="#333333", border="white", breaks=25) # Juega con los estos parámetros +hist(log(rivers), col="#333333", border="white", breaks=25) # Generarás más gráficas después + +# Aquí hay otro set de datos pre-cargado. R tiene bastantes de éstos. +data(discoveries) +plot(discoveries, col="#333333", lwd=3, xlab="Year", + main="Number of important discoveries per year") +plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year", + main="Number of important discoveries per year") + +# En lugar de dejar el orden por defecto (por año), +# podemos ordenar de tal manera que muestre qué es típico: +sort(discoveries) +# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 +# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 +# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 +# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12 + +stem(discoveries, scale=2) +# +# El punto decimal se encuentra en | +# +# 0 | 000000000 +# 1 | 000000000000 +# 2 | 00000000000000000000000000 +# 3 | 00000000000000000000 +# 4 | 000000000000 +# 5 | 0000000 +# 6 | 000000 +# 7 | 0000 +# 8 | 0 +# 9 | 0 +# 10 | 0 +# 11 | +# 12 | 0 + +max(discoveries) +# 12 +summary(discoveries) +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 0.0 2.0 3.0 3.1 4.0 12.0 + +# Tirar los dados varias veces +round(runif(7, min=.5, max=6.5)) +# 1 4 6 1 4 6 4 +# Tus números será diferente de los míos, a menos que tengamos el mismo valor +# de random.seed(31337) + +# Dibuja de un Gaussian 9 veces +rnorm(9) +# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271 +# [7] -0.59975593 0.57629164 1.08455362 + + + +################################################## +# Tipos de datos y aritmética básica +################################################## + +# Ahora para la parte de programación orientada a objetos del tutorial. +# En esta sección conocerás los tipos de datos importantes de R: +# Enteros, numéricos, caracteres, lógicos, y factores. +# Hay otros, pero esos son los que menos necesitas para empezar. + +# ENTEROS +# Enteros de almacenamiento largo son escritos con L +5L # 5 +class(5L) # "integer" +# (Try ?class para más información en la función class().) +# En R, cada valor único, como 5L, es considerado un vector de logitud 1 +length(5L) # 1 +# También puedes tener un vector de enteros con longitud > 1: +c(4L, 5L, 8L, 3L) # 4 5 8 3 +length(c(4L, 5L, 8L, 3L)) # 4 +class(c(4L, 5L, 8L, 3L)) # "integer" + +# NUMÉRICOS +# Un "numérico" es un número de punto flotante de doble precisión. +5 # 5 +class(5) # "numeric" +# Nuevamente, todo en R es un vector; +# puedes hacer un vector numérico con más de un elemento +c(3,3,3,2,2,1) # 3 3 3 2 2 1 +# También puedes utilizar el notación científica +5e4 # 50000 +6.02e23 # Número de Avogadro +1.6e-35 # Logintud Planck +# También puedes tener números infinitamente grandes o pequeños +class(Inf) # "numeric" +class(-Inf) # "numeric" +# Puede que uses "Inf", por ejemplo, en integrate(dnorm, 3, Inf); +# esto obvia las tablas de puntos Z. + +# ARITMÉTICA BÁSICA +# Puedes hacer aritmética con números +# Haciendo aritmética en un mix de enteros y numéricos, te da otro numérico +10L + 66L # 76 # entero mas entero da entero +53.2 - 4 # 49.2 # entero menos entero da numérico +2.0 * 2L # 4 # numérico veces entero da numérico +3L / 4 # 0.75 # entero sobre numérico da numérico +3 %% 2 # 1 # el residuo de dos numéricos es otro numérico +# La aritmética ilegal rinde un "not-a-number" +0 / 0 # NaN +class(NaN) # "numeric" +# Puedes hacer aritmética con dos vectores con longitud mayor a 1, +# siempre que la longitud del vector mayor es un entero múltiplo del menor. +c(1,2,3) + c(1,2,3) # 2 4 6 + +# CARACTERES +# No hay diferencia entre strings y caracteres en R +"Horatio" # "Horatio" +class("Horatio") # "character" +class('H') # "character" +# Ambos eran vectores de caracteres de longitud 1 +# Aquí hay uno más largo: +c('alef', 'bet', 'gimmel', 'dalet', 'he') +# => +# "alef" "bet" "gimmel" "dalet" "he" +length(c("Call","me","Ishmael")) # 3 +# Puedes hacer operaciones regex en vectores de caracteres: +substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis " +gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis." +# R tiene varios vectores predefinidos de caracteres +letters +# => +# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" +# [20] "t" "u" "v" "w" "x" "y" "z" +month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" + +# LÓGICOS +# En R, un "logical" es un boolean +class(TRUE) # "logical" +class(FALSE) # "logical" +# Ese comportamiento es normal +TRUE == TRUE # TRUE +TRUE == FALSE # FALSE +FALSE != FALSE # FALSE +FALSE != TRUE # TRUE +# El dato faltante (NA) es lógico también +class(NA) # "logical" +# Utiliza | y & para operaciones lógicas +# OR +TRUE | FALSE # TRUE +# AND +TRUE & FALSE # FALSE +# Puedes probar si x es TRUE (verdadero) +isTRUE(TRUE) # TRUE +# Aquí tenemos un vector lógico con varios elementos: +c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE +c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE + +# FACTORES +# La clase factor es para datos de categoría +# Los factores pueden ser ordenados (como las calificaciones de los niños) +# o sin orden (como el género) +factor(c("female", "female", "male", NA, "female")) +# female female male <NA> female +# Levels: female male +# Los "levels" son los valores que los datos categóricos pueden tener +# Tomar nota que los datos faltantes no entran a los niveles +levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male" +# Si un vector de factores tiene longitud 1, sus niveles también tendrán +# una longitud de 1 también + +length(factor("male")) # 1 +length(levels(factor("male"))) # 1 +# Los factores son comúnmente vistos en marcos de dato, y una estructura de +# datos que cubriremos después +data(infert) # "Infertility after Spontaneous and Induced Abortion" +levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs" + +# NULL +# "NULL" es uno raro; utilízalo para "limpiar" un vector +class(NULL) # NULL +parakeet = c("beak", "feathers", "wings", "eyes") +parakeet +# => +# [1] "beak" "feathers" "wings" "eyes" +parakeet <- NULL +parakeet +# => +# NULL + +# COERCIÓN DE TIPO +# La coerción de tipos es cuando forzas un valor diferente tipo al que puede tomar. +as.character(c(6, 8)) # "6" "8" +as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE +# Si pones elementos de diferentes tipos en un vector, coerciones raras pasan: +c(TRUE, 4) # 1 4 +c("dog", TRUE, 4) # "dog" "TRUE" "4" +as.numeric("Bilbo") +# => +# [1] NA +# Warning message: +# NAs introduced by coercion + +# También tomar nota: Esos solo eran datos de tipos básicos +# Hay mucho más tipos de datos, como las fechas, series de tiempo, etc. + + +################################################## +# Variables, ciclos, condiciones (if/else) +################################################## + +# A variable is like a box you store a value in for later use. +# We call this "assigning" the value to the variable. +# Having variables lets us write loops, functions, and if/else statements + +# VARIABLES +# Muchas maneras de asignar valores: +x = 5 # esto es posible +y <- "1" # esto es preferido +TRUE -> z # estos funciona pero es raro + +# CICLOS +# Tenemos ciclos 'for' +for (i in 1:4) { + print(i) +} +# Tenemos ciclos 'while' +a <- 10 +while (a > 4) { + cat(a, "...", sep = "") + a <- a - 1 +} +# Ten en mente que los ciclos 'for' y 'while' son lentos en R +# Operaciones con vectores enteros (i.e. una fila o columna completa) +# o tipos de función apply() (que discutiremos después) son preferidos + +# CONDICIONES (IF/ELSE) +# De nuevo, bastante normal +if (4 > 3) { + print("4 is greater than 3") +} else { + print("4 is not greater than 3") +} +# => +# [1] "4 is greater than 3" + +# FUNCIONES +# Definidos de la siguiente manera: +jiggle <- function(x) { + x = x + rnorm(1, sd=.1) #agregar un poco de ruido (controlado) + return(x) +} +# Llamados como cualquier otra función de R +jiggle(5) # 5±ε. luego de set.seed(2716057), jiggle(5)==5.005043 + + + +########################################################################### +# Estructura de datos: Vectores, matrices, marcos da datos y arreglos +########################################################################### + +# UNIDIMENSIONAL + +# Empecemos desde el principio, y con algo que ya conoces: vectores. +vec <- c(8, 9, 10, 11) +vec # 8 9 10 11 +# Preguntamos por elementos específicos poniendo un subconjunto en corchetes +# (Toma nota de que R empieza los conteos desde 1) +vec[1] # 8 +letters[18] # "r" +LETTERS[13] # "M" +month.name[9] # "September" +c(6, 8, 7, 5, 3, 0, 9)[3] # 7 +# También podes buscar por los índices de componentes específicos, +which(vec %% 2 == 0) # 1 3 +# obtener la primera o las últimas entradas de un vector, +head(vec, 1) # 8 +tail(vec, 2) # 10 11 +# o averiguar si cierto valor se encuentra dentro de un vector +any(vec == 10) # TRUE +# Si un índice "se pasa", obtendrás un NA: +vec[6] # NA +# Puedes encontrar la longitud de un vector con length() +length(vec) # 4 +# Puedes realizar operaciones con vectores enteros o con subconjuntos de vectores +vec * 4 # 16 20 24 28 +vec[2:3] * 5 # 25 30 +any(vec[2:3] == 8) # FALSE +# y R tiene muchas funciones pre-definidas para resumir vectores +mean(vec) # 9.5 +var(vec) # 1.666667 +sd(vec) # 1.290994 +max(vec) # 11 +min(vec) # 8 +sum(vec) # 38 +# Otras funciones pre-definidas: +5:15 # 5 6 7 8 9 10 11 12 13 14 15 +seq(from=0, to=31337, by=1337) +# => +# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707 +# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751 + +# BIDIMENCIONAL (TODO EN UNA CLASE) + +# Puedes hacer una matriz de las entradas todos de un mismo tipo como: +mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6)) +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# A diferencia de un vector, una clase matriz es una 'matriz', +# sin importar qué contiene +class(mat) # => "matrix" +# Consulta la primera fila +mat[1,] # 1 4 +# Realiza una operación en la primera columna +3 * mat[,1] # 3 6 9 +# Consulta por una celda específica +mat[3,2] # 6 + +# Transpone una matriz entera +t(mat) +# => +# [,1] [,2] [,3] +# [1,] 1 2 3 +# [2,] 4 5 6 + +# Multiplicación de matrices +mat %*% t(mat) +# => +# [,1] [,2] [,3] +# [1,] 17 22 27 +# [2,] 22 29 36 +# [3,] 27 36 45 + +# cbind() une vectores como columnas para hacer una matriz +mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog")) +mat2 +# => +# [,1] [,2] +# [1,] "1" "dog" +# [2,] "2" "cat" +# [3,] "3" "bird" +# [4,] "4" "dog" +class(mat2) # matrix +# De nuevo, ten en cuenta lo que sucedió +# Debido a que las matrices deben de contener todas las entradas del mismo tipo, +# todo fue convertido a la clase caracter +c(class(mat2[,1]), class(mat2[,2])) + +# rbind() une vectores como filas para hacer una matriz +mat3 <- rbind(c(1,2,4,5), c(6,7,0,4)) +mat3 +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 2 4 5 +# [2,] 6 7 0 4 +# Ah, todo es de la misma clase. No hay coerciones. Mucho mejor. + +# BIDIMENSIONAL (DIFERENTES CLASES) + +# Para columnas de tipos diferentes, utiliza un data frame +# Esta estructura de datos es muy útil para programación estadística, +# una versión de ésta fue agregada a Python en el paquete "pandas". + +students <- data.frame(c("Cedric","Fred","George","Cho","Draco","Ginny"), + c(3,2,2,1,0,-1), + c("H", "G", "G", "R", "S", "G")) +names(students) <- c("name", "year", "house") # name the columns +class(students) # "data.frame" +students +# => +# name year house +# 1 Cedric 3 H +# 2 Fred 2 G +# 3 George 2 G +# 4 Cho 1 R +# 5 Draco 0 S +# 6 Ginny -1 G +class(students$year) # "numeric" +class(students[,3]) # "factor" +# encontrar las dimensiones +nrow(students) # 6 +ncol(students) # 3 +dim(students) # 6 3 +# La función data.frame() convierte vectores de caracteres en vectores +# de factores por defecto; deshabilita este atributo +# stringsAsFactors = FALSE cuando vayas a crear el data.frame +?data.frame + +# Hay otras formas de hacer subconjuntos de data frames +students$year # 3 2 2 1 0 -1 +students[,2] # 3 2 2 1 0 -1 +students[,"year"] # 3 2 2 1 0 -1 + +# Una versión aumentada de la estructura data.frame es el data.table +# Si estás trabajando huge o panel data, o necesitas unificar algunos +# subconjuntos de datos, data.table puede ser una buena elección. +# Aquí un tour: +install.packages("data.table") # Descarga el paquete de CRAN +require(data.table) # Cárgalo +students <- as.data.table(students) +students # Tomar en cuenta la diferencia de la impresión +# => +# name year house +# 1: Cedric 3 H +# 2: Fred 2 G +# 3: George 2 G +# 4: Cho 1 R +# 5: Draco 0 S +# 6: Ginny -1 G +students[name=="Ginny"] # obtener filas con name == "Ginny" +# => +# name year house +# 1: Ginny -1 G +students[year==2] # obtener filas con year == 2 +# => +# name year house +# 1: Fred 2 G +# 2: George 2 G +# data.table hace que la unificación de dos sets de datos sea fácil +# Hagamos otro data.table para unifiar a los estudiantes +founders <- data.table(house=c("G","H","R","S"), + founder=c("Godric","Helga","Rowena","Salazar")) +founders +# => +# house founder +# 1: G Godric +# 2: H Helga +# 3: R Rowena +# 4: S Salazar +setkey(students, house) +setkey(founders, house) +students <- founders[students] # Unifica los dos sets de datos comparando "house" +setnames(students, c("house","houseFounderName","studentName","year")) +students[,order(c("name","year","house","houseFounderName")), with=F] +# => +# studentName year house houseFounderName +# 1: Fred 2 G Godric +# 2: George 2 G Godric +# 3: Ginny -1 G Godric +# 4: Cedric 3 H Helga +# 5: Cho 1 R Rowena +# 6: Draco 0 S Salazar + +# data.table hace que sea fácil obtener resúmenes de las tablas +students[,sum(year),by=house] +# => +# house V1 +# 1: G 3 +# 2: H 3 +# 3: R 1 +# 4: S 0 + +# Para eliminar una columna de un data.frame o data.table, +# asignarle el valor NULL. +students$houseFounderName <- NULL +students +# => +# studentName year house +# 1: Fred 2 G +# 2: George 2 G +# 3: Ginny -1 G +# 4: Cedric 3 H +# 5: Cho 1 R +# 6: Draco 0 S + +# Elimina una fila poniendo un subconjunto +# Usando data.table: +students[studentName != "Draco"] +# => +# house studentName year +# 1: G Fred 2 +# 2: G George 2 +# 3: G Ginny -1 +# 4: H Cedric 3 +# 5: R Cho 1 +# Usando data.frame: +students <- as.data.frame(students) +students[students$house != "G",] +# => +# house houseFounderName studentName year +# 4 H Helga Cedric 3 +# 5 R Rowena Cho 1 +# 6 S Salazar Draco 0 + +# MULTI-DIMENSIONAL (TODOS LOS ELEMENTOS DE UN TIPO) + +# Arreglos crean una tabla de dimensión n +# Todos los elementos deben de ser del mismo tipo +# Puedes hacer una tabla bi-dimensional (como una matriz) +array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4)) +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 4 8 3 +# [2,] 2 5 9 6 +# Puedes utilizar un arreglo para hacer una matriz tri-dimensional también +array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2)) +# => +# , , 1 +# +# [,1] [,2] +# [1,] 2 8 +# [2,] 300 9 +# [3,] 4 0 +# +# , , 2 +# +# [,1] [,2] +# [1,] 5 66 +# [2,] 60 7 +# [3,] 0 847 + +# LISTAS (MULTI-DIMENSIONAL, POSIBLEMENTE DESIGUALES, DE DIFERENTES TIPOS) + +# Finalmente, R tiene listas (de vectores) +list1 <- list(time = 1:40) +list1$price = c(rnorm(40,.5*list1$time,4)) # aleatorio +list1 +# Puedes obtener elementos de una lista de la siguiente manera +list1$time # Una manera +list1[["time"]] # Otra manera +list1[[1]] # Y otra manera +# => +# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 +# [34] 34 35 36 37 38 39 40 +# Puedes crear una lista de subconjuntos como cualquier otro vector +list1$price[4] + +# Las listas no son la estructura de datos más eficiente para trabajar en R; +# a menos de que tengas una buena razón, deberías de quedarte con data.frames +# Las listas son usualmente devueltas por funciones que realizan regresiones +# lineales + +################################################## +# La familia de funciones apply() +################################################## + +# Te recuerdas de mat? +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Utiliza apply(X, MARGIN, FUN) paraaplicar una función FUN a la matriz X +# sobre las filas (MAR = 1) o las columnas (MAR = 2) +# Eso es, R aplica FUN sobre cada fila (o columna) de X, mucho más rápido que +# lo que haría un ciclo 'for' o 'loop' +apply(mat, MAR = 2, jiggle) +# => +# [,1] [,2] +# [1,] 3 15 +# [2,] 7 19 +# [3,] 11 23 +# Otras funciones: ?lapply, ?sapply + +# No te sientas muy intimidado; todos están de acuerdo que son confusas + +# El paquete plyr busca reemplazar (y mejorar) la familiar *apply() +install.packages("plyr") +require(plyr) +?plyr + + + +######################### +# Carga de datos +######################### + +# "pets.csv" es un archivo en internet +# (pero puede ser tan fácil como tener el archivo en tu computadora) +pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv") +pets +head(pets, 2) # primeras dos filas +tail(pets, 1) # última fila + +# Para guardar un data frame o una matriz como un archivo .csv +write.csv(pets, "pets2.csv") # para hacer un nuevo archivo .csv +# definir el directorio de trabajo con setwd(), búscalo con getwd() + +# Prueba ?read.csv ?write.csv para más información + + +######################### +# Gráficas +######################### + +# FUNCIONES PREDEFINIDAS DE GRAFICACIÓN +# Gráficos de dispersión! +plot(list1$time, list1$price, main = "fake data") +# Regresiones! +linearModel <- lm(price ~ time, data = list1) +linearModel # Muestra el resultado de la regresión +# Grafica la línea de regresión +abline(linearModel, col = "red") +# Obtiene una veridad de diagnósticos +plot(linearModel) +# Histogramas! +hist(rpois(n = 10000, lambda = 5), col = "thistle") +# Barras! +barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow")) + +# GGPLOT2 +# Pero éstas no son las gráficas más bonitas de R +# Prueba el paquete ggplot2 para mayor variedad y mejores gráficas +install.packages("ggplot2") +require(ggplot2) +?ggplot2 +pp <- ggplot(students, aes(x=house)) +pp + geom_histogram() +ll <- as.data.table(list1) +pp <- ggplot(ll, aes(x=time,price)) +pp + geom_point() +# ggplot2 tiene una excelente documentación +# (disponible en http://docs.ggplot2.org/current/) + + + +``` + +## ¿Cómo obtengo R? + +* Obtén R y R GUI de [http://www.r-project.org/](http://www.r-project.org/) +* [RStudio](http://www.rstudio.com/ide/) es otro GUI diff --git a/es-es/ruby-es.html.markdown b/es-es/ruby-es.html.markdown index 66a5d0fe..e3e43c18 100644 --- a/es-es/ruby-es.html.markdown +++ b/es-es/ruby-es.html.markdown @@ -5,8 +5,18 @@ contributors: - ["David Underwood", "http://theflyingdeveloper.com"] - ["Joel Walden", "http://joelwalden.net"] - ["Luke Holder", "http://twitter.com/lukeholder"] + - ["Tristan Hume", "http://thume.ca/"] + - ["Nick LaMuro", "https://github.com/NickLaMuro"] + - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"] + - ["Ariel Krakowski", "http://www.learneroo.com"] + - ["Dzianis Dashkevich", "https://github.com/dskecse"] + - ["Levi Bostian", "https://github.com/levibostian"] + - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gabriel Halley", "https://github.com/ghalley"] + - ["Persa Zula", "http://persazula.com"] translators: - ["Camilo Garrido", "http://www.twitter.com/hirohope"] + - ["Erick Bernal", "http://www.twitter.com/billowkib"] lang: es-es --- @@ -19,7 +29,7 @@ Nadie los usa. Tu tampoco deberías =end -# Lo primero y principal: Todo es un objeto +# En primer lugar: Todo es un objeto # Los números son objetos @@ -33,6 +43,8 @@ Tu tampoco deberías 8 - 1 #=> 7 10 * 2 #=> 20 35 / 5 #=> 7 +2**5 #=> 32 +5 % 3 #=> 2 # La aritmética es sólo azúcar sintáctico # para llamar un método de un objeto @@ -55,8 +67,6 @@ false.class #=> FalseClass # Desigualdad 1 != 1 #=> false 2 != 1 #=> true -!true #=> false -!false #=> true # Además de 'false', 'nil' es otro valor falso @@ -70,14 +80,29 @@ false.class #=> FalseClass 2 <= 2 #=> true 2 >= 2 #=> true +# Operadores lógicos +true && false #=> false +true || false #=> true +!true #=> false + +# Existen versiones alternativas de los operadores lógicos con menor prioridad +# 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() + + # Los strings son objetos 'Soy un string'.class #=> String "Soy un string también".class #=> String -referente = "usar interpolacion de strings" +referente = "usar interpolación de strings" "Yo puedo #{referente} usando strings de comillas dobles" -#=> "Yo puedo usar interpolacion de strings usando strings de comillas dobles" +#=> "Yo puedo usar interpolación de strings usando strings de comillas dobles" # Imprime a la salida estándar @@ -103,7 +128,7 @@ ruta = '/mal/nombre/' # Los símbolos (son objetos) # Los símbolos son inmutables, constantes reusables representadas internamente por un -# valor entero. Son usalmente usados en vez de strings para expresar eficientemente +# valor entero. Son normalmente usados en vez de strings para expresar eficientemente # valores específicos y significativos :pendiente.class #=> Symbol @@ -119,18 +144,19 @@ status == :aprovado #=> false # Arreglos # Esto es un arreglo -[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] +arreglo = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] # Arreglos pueden contener elementos de distintos tipos -arreglo = [1, "hola", false] #=> => [1, "hola", false] +[1, "hola", false] #=> => [1, "hola", false] # Arreglos pueden ser indexados # Desde el frente arreglo[0] #=> 1 +arreglo.first #=> 1 arreglo[12] #=> nil -# Tal como la aritmética, el acceso como variable[índice] +# Al igual que en aritmética, el acceso como variable[índice] # es sólo azúcar sintáctica # para llamar el método [] de un objeto arreglo.[] 0 #=> 1 @@ -138,15 +164,25 @@ arreglo.[] 12 #=> nil # Desde el final arreglo[-1] #=> 5 +arreglo.last #=> 5 + +# Con un índice de inicio y longitud +arreglo[2, 3] #=> [3, 4, 5] -# Con un índice de inicio y final -arreglo[2, 4] #=> [3, 4, 5] +# Invertir un arreglo +a = [1, 2, 3] +a.reverse! #=> [3, 2, 1] # O con rango arreglo[1..3] #=> [2, 3, 4] # Añade elementos a un arreglo así arreglo << 6 #=> [1, 2, 3, 4, 5, 6] +# O así +arreglo.push(6) #=> [1, 2, 3, 4, 5, 6] + +#Verifica si un elemento ya existe en ese arreglo +arreglo.include?(1) #=> true # Hashes son los diccionarios principales de Ruby con pares llave/valor. # Hashes se denotan con llaves: @@ -161,17 +197,16 @@ hash['numero'] #=> 5 # Preguntarle a un hash por una llave que no existe retorna 'nil': hash['nada aqui'] #=> nil -# Itera sobre un hash con el método 'each': -hash.each do |k, v| - puts "#{k} is #{v}" -end - # Desde Ruby 1.9, hay una sintaxis especial cuando se usa un símbolo como llave: nuevo_hash = { defcon: 3, accion: true} nuevo_hash.keys #=> [:defcon, :accion] +# Verifica la existencia de llaves y valores en el hash +new_hash.has_key?(:defcon) #=> true +new_hash.has_value?(3) #=> true + # Tip: Tanto los arreglos como los hashes son Enumerable (enumerables) # Comparten muchos métodos útiles tales como 'each', 'map', 'count', y más @@ -194,9 +229,15 @@ end #=> iteracion 4 #=> iteracion 5 -# Aunque -# Nadie usa los ciclos `for` -# Usa `each`, así: +# SIN EMBARGO, nadie usa ciclos `for` +# En su lugar debes usar el método "each" y pasarle un block (bloque). +# Un bloque es un fragmento código que puedes pasar a métodos como `each`. +# Es símilar a las funciones lambda, funciones anónimas o `closures` en otros +# lenguajes de programación. +# +# El método `each` de un Range (rango) ejecuta el bloque una vez por cada elemento. +# Al bloque se le pasa un contador como parametro. +# Usar el método `each` con un bloque se ve así: (1..5).each do |contador| puts "iteracion #{contador}" @@ -207,10 +248,27 @@ end #=> iteracion 4 #=> iteracion 5 -counter = 1 -while counter <= 5 do - puts "iteracion #{counter}" - counter += 1 +# También puedes envolver el bloque entre llaves: +(1..5).each { |counter| puts "iteración #{contador}" } + +#El contenido de las estructuras de datos en ruby puede ser iterado usando `each`. +arreglo.each do |elemento| + puts "#{elemento} es parte del arreglo" +end +hash.each do |llave, valor| + puts "#{llave} es #{valor}" +end + +# Si aún necesitas un índice puedes usar "each_with_index" y definir una variable +# índice. +arreglo.each_with_index do |element, index| + puts "#{element} tiene la posición #{index} en el arreglo" +end + +contador = 1 +while contador <= 5 do + puts "iteracion #{contador}" + contador += 1 end #=> iteracion 1 #=> iteracion 2 @@ -218,6 +276,19 @@ end #=> iteracion 4 #=> iteracion 5 +# Hay una gran variedad de otras funciones iterativas útiles en Ruby, +# por ejemplo `map`, `reduce`, `inject`, entre otras. Map, por ejemplo, +# toma el arreglo sobre el cuál está iterando, le hace cambios +# definidos en el bloque, y retorna un arreglo completamente nuevo. +arreglo = [1,2,3,4,5] +duplicado = array.map do |elemento| + elemento * 2 +end +puts duplicado +#=> [2,4,6,8,10] +puts array +#=> [1,2,3,4,5] + nota = 'B' case nota @@ -234,6 +305,34 @@ when 'F' else puts "Sistema alternativo de notas, ¿eh?" end +#=> "Mejor suerte para la proxima" + +# Los casos también pueden usar rangos +nota = 82 + +case nota +when 90..100 + puts 'Excelente!' +when 80..100 + puts 'Buen trabajo' +else + puts '¡Reprobaste!' +end +#=> "Buen trabajo" + +# Manejo de excepciones +begin + # código que podría causar excepción + raise NoMemoryError, 'Se te acabó la memoria' +rescue NoMemoryError => variable_de_excepcion + puts 'El error NoMemoryError ocurrió', variable_de_excepcion +rescue RuntimeError => otra_variable_de_excepcion + puts 'El error RuntimeError ocurrió' +else + puts 'Esto se ejecuta si ningun error ocurrió' +ensure + puts 'Este código siempre se ejecuta, sin importar que' +end # Funciones @@ -244,7 +343,7 @@ end # Funciones (y todos los bloques) implícitamente retornan el valor de la última instrucción doble(2) #=> 4 -# Paréntesis son opcionales cuando el resultado es ambiguo +# Paréntesis son opcionales cuando el resultado no es ambiguo doble 3 #=> 6 doble doble 3 #=> 12 @@ -259,7 +358,7 @@ suma 3, 4 #=> 7 suma suma(3,4), 5 #=> 12 # yield -# Todos los métodos tienen un parámetro de bloqueo opcional e implícitp +# Todos los métodos tienen un parámetro bloque opcional e implícito # puede llamarse con la palabra clave 'yield' def alrededor @@ -274,6 +373,17 @@ alrededor { puts 'hola mundo' } # hola mundo # } +# Puedes pasar un bloque a una función +# '&' representa una referencia a un bloque +def visitantes(&bloque) + bloque.call +end + +# Puedes pasar una lista de argumentos, que serán convertidos en un arreglo +# Para eso sirve el operador ('*') +def visitantes(*arreglo) + arreglo.each { |visitante| puts visitante } +end # Define una clase con la palabra clave 'class' class Humano @@ -299,16 +409,26 @@ class Humano @nombre end + # La funcionalidad anterior puede ser encapsulada usando el método attr_accessor + # de la siguiente manera + + attr_accessor :name + + # Los métodos de tipo getter y setter también se pueden crear de manera individual + # de la siguiente manera + + attr_reader :name + attr_writer :name + # Un método de clase usa 'self' (sí mismo) para distinguirse de métodos de instancia. # Sólo puede ser llamado en la clase, no por una instancia. def self.decir(mensaje) - puts "#{mensaje}" + puts mensaje end def especie @@especie end - end @@ -328,6 +448,23 @@ dwight.nombre #=> "Dwight K. Schrute" # Llama el método de clase Humano.decir("Hi") #=> "Hi" +# El alcance de las variables es definido por la manera en que las nombramos. +# Las variables que inician con $ tienen un alcance global +$var = "Soy una variable global" +defined? $var #=> "global-variable" + +# Las variables que empiezan con @ tienen un alcance de instancia +@var = "Soy una variable de instancia" +defined? @var #=> "instance-variable" + +# Variables que empiezan con @@ tienen un alcance de clase +@@var = "Soy una variable de clase" +defined? @@var #=> "class variable" + +# Las variables que empiezan con letra mayuscula son constantes +Var = "Soy una constante" +defined? Var #=> "constant" + # Las clases también son un objeto en ruby. Por lo cual, las clases también pueden tener variables de instancia. # Variables de clase son compartidas a través de la clase y todos sus descendientes. @@ -371,7 +508,67 @@ end class Doctor < Humano end -Human.bar # 0 +Humano.bar # 0 Doctor.bar # nil +module ModuloEjemplo + def foo + 'foo' + end +end + +# Al incluir un módulo sus métodos se comparten con las instancias de la clase +# Al extender un módulo sus métodos se comparten con la clase misma + +class Persona + include ModuloEjemplo +end + +class Libro + extend ModuloEjemplo +end + +Persona.foo # => NoMethodError: undefined method `foo' for Persona:Class +Persona.new.foo # => 'foo' +Libro.foo # => 'foo' +Libro.new.foo # => NoMethodError: undefined method `foo' + +# Las llamadas de retorno (callbacks) son ejecutadas cuando se incluye o +# extiende un módulo +module EjemploConcern + def self.incluido(base) + base.extend(MetodosClase) + base.send(:include, MetodosInstancia) + end + + module MetodosClase + def bar + 'bar' + end + end + + module MetodosInstancia + def qux + 'qux' + end + end +end + +class Algo + include EjemploConcern +end + +Algo.bar #=> 'bar' +Algo.qux #=> NoMethodError: undefined method `qux' +Algo.new.bar # => NoMethodError: undefined method `bar' +Algo.new.qux # => 'qux' ``` + +## Recursos adicionales +- [Aprende Ruby Mediante Ejemplo con Ejercicios](http://www.learneroo.com/modules/61/nodes/338) - Una variante de +esta referencia con ejercicios en navegador. +- [Documentación Oficial](http://www.ruby-doc.org/core-2.1.1/) +- [Ruby desde otros lenguajes](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/) +- [Programando Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - Una +[edición antigua](http://ruby-doc.com/docs/ProgrammingRuby/) gratuita disponible en línea. +- [Guía de estilo de Ruby](https://github.com/bbatsov/ruby-style-guide) - Guía de estilo creada por la comunidad. diff --git a/es-es/rust-es.html.markdown b/es-es/rust-es.html.markdown new file mode 100644 index 00000000..b43cb815 --- /dev/null +++ b/es-es/rust-es.html.markdown @@ -0,0 +1,324 @@ +--- +language: rust +contributors: + - ["P1start", "http://p1start.github.io/"] +translators: + - ["Razican", "https://www.razican.com/"] +filename: learnrust-es.rs +lang: es-es +--- + +Rust es un lenguaje de programación desarrollado por Mozzilla Research. Rust +combina el control del rendimiento a bajo nivel con la comodidad del alto nivel +y garantías de seguridad. + +Consigue cumplir estos objetivos sin necesidad de un recolector de basura o +runtime, haciendo posible usar las librerías de Rust como sustituto de C. + +La primera versión de Rust, la 0.1, fue lanzada en enero de 2012, y durante 3 +años el desarrollo fue tan rápido que hasta hace poco el uso de las versiones +estables no era recomendable, y se aconsejaba usar las compilaciones nocturnas. + +El 15 de mayo de 2015 se lanzó Rust 1.0, con una garantía completa de +retrocompatibilidad. A día de hoy los tiempos de compilación han mejorado mucho +desde ese lanzamiento, así como otros aspectos del lenguaje y el compilador. +Rust ha adoptado un modelo de desarrollo por series de publicaciones periódicas, +con lanzamientos cada 6 semanas. Junto con cada lanzamiento, se lanza la beta de +la siguiente versión. + +A pesar de que Rust es un lenguaje relativamente de bajo nivel, tiene conceptos +funcionales que generalmente se encuentran en lenguajes de más alto nivel. Esto +hace que Rust sea rápido y al mismo tiempo fácil y eficiente a la hora de +programar. + +```rust +// Esto es un comentario. Los comentarios de una sola línea se hacen así... +/* ...y los de múltiples líneas así */ + +////////////////////////// +// 1. Conceptos básicos // +////////////////////////// + +// Funciones +// `i32` es el tipo para enteros de 32 bits con signo +fn suma2(x: i32, y: i32) -> i32 { + // Retorno implícito (sin punto y coma) + x + y +} + +// Función principal +fn main() { + // N;umeros // + + // Bindings (variables) inmutables + let x: i32 = 1; + + // Sufijos para enteros / floats + let y: i32 = 13i32; + let f: f64 = 1.3f64; + + // Inferencia de tipos + // La mayor parte del tiempo, el compilador de Rust puede inferir el tipo de + // una variable, por lo que no necesitas escribir una anotación de tipo + // explícita. A lo largo de este tutorial, los tipos están anotados + // explícitamente en varios sitios, pero solo con propósito demostrativo. La + // inferencia de tipos puede manejar esto por ti la mayor parte del tiempo. + let x_implicita = 1; + let f_implicita = 1.3; + + // Aritmética + let sum = x + y + 13; + + // Variable mutable + let mut mutable = 1; + mutable = 4; + mutable += 2; + + // Strings (cadenas de caracteres) // + + // Strings literales + let x: &str = "hola mundo!"; + + // Impresión por consola + println!("{} {}", f, x); // 1.3 hola mundo! + + // Un `String` – una cadena en memoria dinámica (heap) + let s: String = "hola mundo".to_string(); + + // Una porión de cadena (slice) – una vista inmutable a otra cadena + // Esto es básicamente un puntero inmutable a un string string – en realidad + // no contiene los caracteres de la cadena, solo un puntero a algo que los + // tiene (en este caso, `s`) + let s_slice: &str = &s; + + println!("{} {}", s, s_slice); // hola mundo hola mundo + + // Vectores/arrays // + + // A fixed-size array + let cuatro_enteros: [i32; 4] = [1, 2, 3, 4]; + + // Un array dinámico (vector) + let mut vector: Vec<i32> = vec![1, 2, 3, 4]; + vector.push(5); + + // Una porción (slice) – una vista inmutable a un vector o array + // Esto es parecido a un slice de un string, pero para vectores + let slice: &[i32] = &vector; + + // Usa `{:?}` para imprimir algo en estilo debug + println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] + + // Tuplas // + + // Una tupla es un conjunto de tamaño fijo de valores. Pueden ser de diferente tipo. + let x: (i32, &str, f64) = (1, "hola", 3.4); + + // Desestructurando `let` + let (a, b, c) = x; + println!("{} {} {}", a, b, c); // 1 hola 3.4 + + // Indexando + println!("{}", x.1); // hola + + ////////////// + // 2. Tipos // + ////////////// + + // Estructuras + struct Punto { + x: i32, + y: i32, + } + + let origen: Punto = Punto { x: 0, y: 0 }; + + // Una estructura con campos sin nombre, una ‘estructura de tupla’ + struct Punto2(i32, i32); + + let origen2 = Punto2(0, 0); + + // Enums básicos como en C + enum Direccion { + Izquierda, + Derecha, + Arriba, + Abajo, + } + + let arriba = Direccion::Arriba; + + // Enum con campos + enum OpcionalI32 { + UnI32(i32), + Nada, + } + + let dos: OpcionalI32 = OpcionalI32::UnI32(2); + let nada = OpcionalI32::Nada; + + // Genéricos // + + struct Foo<T> { bar: T } + + // Esto está definido en la librería estándar como `Option` + enum Opcional<T> { + AlgunVal(T), + SinVal, + } + + // Métodos // + + impl<T> Foo<T> { + // Los métodos reciben un parámetro explícito `self` + fn get_bar(self) -> T { + self.bar + } + } + + let un_foo = Foo { bar: 1 }; + println!("{}", un_foo.get_bar()); // 1 + + // Traits (conocidos como interfaces o typeclasses en otros lenguajes) // + + trait Frobnicate<T> { + fn frobnicate(self) -> Option<T>; + } + + impl<T> Frobnicate<T> for Foo<T> { + fn frobnicate(self) -> Option<T> { + Some(self.bar) + } + } + + let otro_foo = Foo { bar: 1 }; + println!("{:?}", otro_foo.frobnicate()); // Some(1) + + ///////////////////////////////// + // 3. Comparación con patrones // + ///////////////////////////////// + + let foo = OpcionalI32::UnI32(1); + match foo { + OpcionalI32::UnI32(n) => println!("es un i32: {}", n), + OpcionalI32::Nada => println!("no es nada!"), + } + + // comparación de patrones avanzada + struct FooBar { x: i32, y: OpcionalI32 } + let bar = FooBar { x: 15, y: OpcionalI32::UnI32(32) }; + + match bar { + FooBar { x: 0, y: OpcionalI32::UnI32(0) } => + println!("Los números son cero!"), + FooBar { x: n, y: OpcionalI32::UnI32(m) } if n == m => + println!("Los números son iguales"), + FooBar { x: n, y: OpcionalI32::UnI32(m) } => + println!("Números diferentes: {} {}", n, m), + FooBar { x: _, y: OpcionalI32::Nada } => + println!("El segudo número no es nada!"), + } + + ///////////////////////// + // 4. Flujo de control // + ///////////////////////// + + // bucles `for` + let array = [1, 2, 3]; + for i in array.iter() { + println!("{}", i); + } + + // Rangos + for i in 0u32..10 { + print!("{} ", i); + } + println!(""); + // imprime `0 1 2 3 4 5 6 7 8 9 ` + + // `if` + if 1 == 1 { + println!("Las matemáticas funcionan!"); + } else { + println!("Oh no..."); + } + + // `if` como una expresión + let valor = if true { + "bueno" + } else { + "malo" + }; + + // bucle `while` + while 1 == 1 { + println!("El universo está funcionando correctamente."); + } + + // Bucle infinito + loop { + println!("Hola!"); + } + + //////////////////////////////////////// + // 5. Seguridad de memoria y punteros // + //////////////////////////////////////// + + // Posesión de punteros – solo uno puede ‘poseer’ un puntero en cada momento + // Esto significa que cuando la `Box` queda fuera del ámbito, puede ser + // liberada automáticamente de manera segura. + let mut mio: Box<i32> = Box::new(3); + *mio = 5; // dereferenciar + // Aquí, `ahora_es_mio`, toma posesión de `mio`. En otras palabras, `mio` se + // mueve. + let mut ahora_es_mio = mio; + *ahora_es_mio += 2; + + println!("{}", ahora_es_mio); // 7 + // println!("{}", mio); // esto no compilaría, porque `now_its_mine` es el + // que posee el puntero + + // Referencia – un puntero inmutable que referencia a otro dato + // Cuando se crea una referencia a un valor, decimos que el valor ha sido + // ‘tomado prestado’. + // Mientras un valor está prestado como inmutable, no puede ser modificado o + // movido. + // Una prestación dura hasta el fin del ámbito en el que se creó. + let mut var = 4; + var = 3; + let ref_var: &i32 = &var; + + println!("{}", var); // A diferencia de `mio`, `var` se puede seguir usando + println!("{}", *ref_var); + // var = 5; // esto no compilaría, porque `var` está prestada + // *ref_var = 6; // esto tampoco, porque `ref_var` es una referencia + // inmutable + + // Referencia mutable + // Mientras que un valor está prestado como mutable, no puede ser accedido + // desde ningún otro sitio. + let mut var2 = 4; + let ref_var2: &mut i32 = &mut var2; + *ref_var2 += 2; // '*' se usa para apuntar al var2 prestado como mutable + + println!("{}", *ref_var2); // 6 , //var2 no compilaría. //ref_var2 es de + // tipo &mut i32, por lo que guarda una + // referencia a un i32 no el valor. + // var2 = 2; // esto no compilaría porque `var2` está prestado +} +``` + +## Lectura adicional + +Rust es mucho más que esto. Esto es solo lo más básico para que puedas entender +las cosas más importantes. Para aprender más sobre Rust, lee [The Rust +Programming Language](http://doc.rust-lang.org/book/index.html) y echa un +vistazo al subreddit [/r/rust](http://reddit.com/r/rust). Los compañeros en el +canal #rust en irc.mozilla.org también son muy buenos con los recien llegados. +También puedes acceder a [Rust users](https://users.rust-lang.org/) a pedir +ayuda o a [Rust internals](https://internals.rust-lang.org/) para aprender más +sobre el lenguaje y colaborar en su desarrollo. + +También puedes probar Rust con un compilador online en el oficial [Rust +playpen](http://play.rust-lang.org) o en la [web principal de +Rust](http://rust-lang.org). diff --git a/es-es/swift-es.html.markdown b/es-es/swift-es.html.markdown new file mode 100644 index 00000000..c04ab02b --- /dev/null +++ b/es-es/swift-es.html.markdown @@ -0,0 +1,596 @@ +--- +language: swift +contributors: + - ["Grant Timmerman", "http://github.com/grant"] + - ["Christopher Bess", "http://github.com/cbess"] + - ["Joey Huang", "http://github.com/kamidox"] + - ["Anthony Nguyen", "http://github.com/anthonyn60"] +translators: + - ["David Hsieh", "http://github.com/deivuh"] +lang: es-es +filename: learnswift-es.swift +--- + +Swift es un lenguaje de programación para el desarrollo en iOS y OS X 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. + +Véase también la guía oficial de Apple, [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/), el cual tiene un completo tutorial de Swift. + + +```swift +// Importar un módulo +import UIKit + +// +// MARK: Básicos +// + +// XCode soporta referencias para anotar tu código y agregarlos a lista de la +// barra de saltos. +// MARK: Marca de sección +// TODO: Hacer algo pronto +// FIXME: Arreglar este código + +// En Swift 2, println y print fueron combinados en un solo método print. +// Print añade una nueva línea automáticamente. +print("Hola, mundo") // println ahora es print +print("Hola, mundo", appendNewLine: false) // print sin agregar nueva línea + +// Valores de variables (var) pueden cambiar después de ser asignados +// Valores de constrantes (let) no pueden cambiarse después de ser asignados + +var myVariable = 42 +let øπΩ = "value" // nombres de variable unicode +let π = 3.1415926 +let convenience = "keyword" // nombre de variable contextual +// Las declaraciones pueden ser separadas por punto y coma (;) +let weak = "keyword"; let override = "another keyword" +// Los acentos abiertos (``) permiten utilizar palabras clave como nombres de +// variable +let `class` = "keyword" +let explicitDouble: Double = 70 +let intValue = 0007 // 7 +let largeIntValue = 77_000 // 77000 +let label = "some text " + String(myVariable) // Conversión (casting) +let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Interpolación de string + +// Valores específicos de la compilación (build) +// utiliza la configuración -D +#if false + print("No impreso") + let buildValue = 3 +#else + let buildValue = 7 +#endif +print("Build value: \(buildValue)") // Build value: 7 + +/* + Las opcionales son un aspecto del lenguaje Swift que permite el + almacenamiento de un valor `Some` (algo) o `None` (nada). + + Debido a que Swift requiere que cada propiedad tenga un valor, + hasta un valor 'nil' debe de ser explicitamente almacenado como un + valor opcional. + + Optional<T> es un enum. +*/ +var someOptionalString: String? = "opcional" // Puede ser nil +// Al igual que lo anterior, pero ? es un operador postfix (sufijo) +var someOptionalString2: Optional<String> = "opcional" + +if someOptionalString != nil { + // No soy nil + if someOptionalString!.hasPrefix("opt") { + print("Tiene el prefijo") + } + + let empty = someOptionalString?.isEmpty +} +someOptionalString = nil + +// Opcional implícitamente desenvuelto +var unwrappedString: String! = "Un valor esperado." +// Al igual que lo anterior, pero ! es un operador postfix (sufijo) +var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Un valor esperado." + +if let someOptionalStringConstant = someOptionalString { + // tiene valor `Some` (algo), no nil + if !someOptionalStringConstant.hasPrefix("ok") { + // No tiene el prefijo + } +} + +// Swift tiene soporte de almacenamiento para cualquier tipo de valor. +// AnyObject == id +// A diferencia de Objective-C `id`, AnyObject funciona con cualquier +// valor (Class, Int, struct, etc) +var anyObjectVar: AnyObject = 7 +anyObjectVar = "Cambiado a un valor string, no es buena práctica, pero posible." + +/* + Comentar aquí + + /* + Comentarios anidados también son soportados + */ +*/ + +// +// MARK: Colecciones +// + +/* + Tipos Array (arreglo) y Dictionary (diccionario) son structs (estructuras). + Así que `let` y `var` también indican si son mudables (var) o + inmutables (let) durante la declaración de sus tipos. +*/ + +// Array (arreglo) +var shoppingList = ["catfish", "water", "lemons"] +shoppingList[1] = "bottle of water" +let emptyArray = [String]() // let == inmutable +let emptyArray2 = Array<String>() // igual que lo anterior +var emptyMutableArray = [String]() // var == mudable + + +// Dictionary (diccionario) +var occupations = [ + "Malcolm": "Captain", + "kaylee": "Mechanic" +] +occupations["Jayne"] = "Public Relations" +let emptyDictionary = [String: Float]() // let == inmutable +let emptyDictionary2 = Dictionary<String, Float>() // igual que lo anterior +var emptyMutableDictionary = [String: Float]() // var == mudable + + +// +// MARK: Flujo de control +// + +// Ciclo for (array) +let myArray = [1, 1, 2, 3, 5] +for value in myArray { + if value == 1 { + print("Uno!") + } else { + print("No es uno!") + } +} + +// Ciclo for (dictionary) +var dict = ["uno": 1, "dos": 2] +for (key, value) in dict { + print("\(key): \(value)") +} + +// Ciclo for (range) +for i in -1...shoppingList.count { + print(i) +} +shoppingList[1...2] = ["steak", "peacons"] +// Utilizar ..< para excluir el último valor + +// Ciclo while +var i = 1 +while i < 1000 { + i *= 2 +} + +// Ciclo do-while +do { + print("Hola") +} while 1 == 2 + +// Switch +// Muy potente, se puede pensar como declaraciones `if` con _azúcar sintáctico_ +// Soportan String, instancias de objetos, y primitivos (Int, Double, etc) +let vegetable = "red pepper" +switch vegetable { +case "celery": + let vegetableComment = "Add some raisins and make ants on a log." +case "cucumber", "watercress": + let vegetableComment = "That would make a good tea sandwich." +case let localScopeValue where localScopeValue.hasSuffix("pepper"): + let vegetableComment = "Is it a spicy \(localScopeValue)?" +default: // obligatorio (se debe cumplir con todos los posibles valores de entrada) + let vegetableComment = "Everything tastes good in soup." +} + + +// +// MARK: Funciones +// + +// Funciones son un tipo de primera-clase, quiere decir que pueden ser anidados +// en funciones y pueden ser pasados como parámetros + +// Función en documentación de cabeceras Swift (formato reStructedText) + +/** + Una operación de saludo + + - Una viñeta en la documentación + - Otra viñeta en la documentación + + :param: name Un nombre + :param: day Un día + :returns: Un string que contiene el valor de name y day +*/ +func greet(name: String, day: String) -> String { + return "Hola \(name), hoy es \(day)." +} +greet("Bob", "Martes") + +// Similar a lo anterior, a excepción del compartamiento de los parámetros +// de la función +func greet2(requiredName: String, externalParamName localParamName: String) -> String { + return "Hola \(requiredName), hoy es el día \(localParamName)" +} +greet2(requiredName:"John", externalParamName: "Domingo") + +// Función que devuelve múltiples valores en una tupla +func getGasPrices() -> (Double, Double, Double) { + return (3.59, 3.69, 3.79) +} +let pricesTuple = getGasPrices() +let price = pricesTuple.2 // 3.79 +// Ignorar tupla (u otros) valores utilizando _ (guión bajo) +let (_, price1, _) = pricesTuple // price1 == 3.69 +print(price1 == pricesTuple.1) // true +print("Gas price: \(price)") + +// Cantidad variable de argumentos +func setup(numbers: Int...) { + // Es un arreglo + let number = numbers[0] + let argCount = numbers.count +} + +// Pasando y devolviendo funciones +func makeIncrementer() -> (Int -> Int) { + func addOne(number: Int) -> Int { + return 1 + number + } + return addOne +} +var increment = makeIncrementer() +increment(7) + +// Pasando como referencia +func swapTwoInts(inout a: Int, inout b: Int) { + let tempA = a + a = b + b = tempA +} +var someIntA = 7 +var someIntB = 3 +swapTwoInts(&someIntA, &someIntB) +print(someIntB) // 7 + + +// +// MARK: Closures (Clausuras) +// +var numbers = [1, 2, 6] + +// Las funciones son un caso especial de closure ({}) + +// Ejemplo de closure. +// `->` Separa los argumentos del tipo de retorno +// `in` Separa la cabecera del cuerpo del closure +numbers.map({ + (number: Int) -> Int in + let result = 3 * number + return result +}) + +// Cuando se conoce el tipo, como en lo anterior, se puede hacer esto +numbers = numbers.map({ number in 3 * number }) +// o esto +//numbers = numbers.map({ $0 * 3 }) + +print(numbers) // [3, 6, 18] + +// Closure restante +numbers = sorted(numbers) { $0 > $1 } + +print(numbers) // [18, 6, 3] + +// Bastante corto, debido a que el operador < infiere los tipos + +numbers = sorted(numbers, < ) + +print(numbers) // [3, 6, 18] + +// +// MARK: Estructuras +// + +// Las estructuras y las clases tienen capacidades similares +struct NamesTable { + let names = [String]() + + // Subscript personalizado + subscript(index: Int) -> String { + return names[index] + } +} + +// Las estructuras tienen un inicializador designado autogenerado (implícitamente) +let namesTable = NamesTable(names: ["Me", "Them"]) +let name = namesTable[1] +print("Name is \(name)") // Name is Them + +// +// MARK: Clases +// + +// Las clases, las estructuras y sus miembros tienen tres niveles de control de acceso +// Éstos son: internal (predeterminado), public, private + +public class Shape { + public func getArea() -> Int { + return 0; + } +} + +// Todos los métodos y las propiedades de una clase son public (públicas) +// Si solo necesitas almacenar datos en un objecto estructurado, +// debes de utilizar `struct` + +internal class Rect: Shape { + var sideLength: Int = 1 + + // Getter y setter personalizado + private var perimeter: Int { + get { + return 4 * sideLength + } + set { + // `newValue` es una variable implícita disponible para los setters + sideLength = newValue / 4 + } + } + + // Lazily loading (inicialización bajo demanda) a una propiedad + // subShape queda como nil (sin inicializar) hasta que getter es llamado + lazy var subShape = Rect(sideLength: 4) + + // Si no necesitas un getter y setter personalizado + // pero aún quieres ejecutar código antes y después de hacer get o set + // a una propiedad, puedes utilizar `willSet` y `didSet` + var identifier: String = "defaultID" { + // El argumento `willSet` será el nombre de variable para el nuevo valor + willSet(someIdentifier) { + print(someIdentifier) + } + } + + init(sideLength: Int) { + self.sideLength = sideLength + // Siempre poner super.init de último al momento de inicializar propiedades + // personalizadas + super.init() + } + + func shrink() { + if sideLength > 0 { + --sideLength + } + } + + override func getArea() -> Int { + return sideLength * sideLength + } +} + +// Una clase simple `Square` que extiende de `Rect` +class Square: Rect { + convenience init() { + self.init(sideLength: 5) + } +} + +var mySquare = Square() +print(mySquare.getArea()) // 25 +mySquare.shrink() +print(mySquare.sideLength) // 4 + +// Conversión de tipo de instancia +let aShape = mySquare as Shape + +// Comparar instancias, no es igual a == que compara objetos (equal to) +if mySquare === mySquare { + print("Yep, it's mySquare") +} + +// Inicialización (init) opcional +class Circle: Shape { + var radius: Int + override func getArea() -> Int { + return 3 * radius * radius + } + + // Un signo de interrogación como sufijo después de `init` es un init opcional + // que puede devolver nil + init?(radius: Int) { + self.radius = radius + super.init() + + if radius <= 0 { + return nil + } + } +} + +var myCircle = Circle(radius: 1) +print(myCircle?.getArea()) // Optional(3) +print(myCircle!.getArea()) // 3 +var myEmptyCircle = Circle(radius: -1) +print(myEmptyCircle?.getArea()) // "nil" +if let circle = myEmptyCircle { + // no será ejecutado debido a que myEmptyCircle es nil + print("circle is not nil") +} + + +// +// MARK: Enums +// + + +// Los enums pueden ser opcionalmente de un tipo específico o de su propio tipo +// Al igual que las clases, pueden contener métodos + +enum Suit { + case Spades, Hearts, Diamonds, Clubs + func getIcon() -> String { + switch self { + case .Spades: return "♤" + case .Hearts: return "♡" + case .Diamonds: return "♢" + case .Clubs: return "♧" + } + } +} + +// Los valores de enum permite la sintaxis corta, sin necesidad de poner +// el tipo del enum cuando la variable es declarada de manera explícita +var suitValue: Suit = .Hearts + +// Enums de tipo no-entero requiere asignaciones de valores crudas directas +enum BookName: String { + case John = "John" + case Luke = "Luke" +} +print("Name: \(BookName.John.rawValue)") + +// Enum con valores asociados +enum Furniture { + // Asociación con Int + case Desk(height: Int) + // Asociación con String e Int + case Chair(String, Int) + + func description() -> String { + switch self { + case .Desk(let height): + return "Desk with \(height) cm" + case .Chair(let brand, let height): + return "Chair of \(brand) with \(height) cm" + } + } +} + +var desk: Furniture = .Desk(height: 80) +print(desk.description()) // "Desk with 80 cm" +var chair = Furniture.Chair("Foo", 40) +print(chair.description()) // "Chair of Foo with 40 cm" + + +// +// MARK: Protocolos +// + +// `protocol` puede requerir que los tipos tengan propiedades +// de instancia específicas, métodos de instancia, métodos de tipo, +// operadores, y subscripts + + +protocol ShapeGenerator { + var enabled: Bool { get set } + func buildShape() -> Shape +} + +// Protocolos declarados con @objc permiten funciones opcionales, +// que te permite evaluar conformidad +@objc protocol TransformShape { + optional func reshaped() + optional func canReshape() -> Bool +} + +class MyShape: Rect { + var delegate: TransformShape? + + func grow() { + sideLength += 2 + + // Pon un signo de interrogación después de la propiedad opcional, + // método, o subscript para ignorar un valor nil y devolver nil + // en lugar de tirar un error de tiempo de ejecución + // ("optional chaining") + if let allow = self.delegate?.canReshape?() { + // test for delegate then for method + self.delegate?.reshaped?() + } + } +} + + +// +// MARK: Otros +// + +// `extension`: Agrega funcionalidades a tipos existentes + +// Square ahora se "conforma" al protocolo `Printable` +extension Square: Printable { + var description: String { + return "Area: \(self.getArea()) - ID: \(self.identifier)" + } +} + +print("Square: \(mySquare)") + +// También puedes hacer extend a tipos prefabricados (built-in) +extension Int { + var customProperty: String { + return "This is \(self)" + } + + func multiplyBy(num: Int) -> Int { + return num * self + } +} + +print(7.customProperty) // "This is 7" +print(14.multiplyBy(3)) // 42 + +// Generics: Similar Java y C#. Utiliza la palabra clave `where` para +// especificar los requerimientos de los genéricos. + +func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? { + for (index, value) in enumerate(array) { + if value == valueToFind { + return index + } + } + return nil +} +let foundAtIndex = findIndex([1, 2, 3, 4], 3) +print(foundAtIndex == 2) // true + +// Operadores: +// Operadores personalizados puede empezar con los siguientes caracteres: +// / = - + * % < > ! & | ^ . ~ +// o +// Caracteres unicode: math, symbol, arrow, dingbat, y line/box. +prefix operator !!! {} + +// Un operador prefix que triplica la longitud del lado cuando es utilizado +prefix func !!! (inout shape: Square) -> Square { + shape.sideLength *= 3 + return shape +} + +// Valor actual +print(mySquare.sideLength) // 4 + +// Cambiar la longitud del lado utilizando el operador !!!, +// incrementa el tamaño por 3 +!!!mySquare +print(mySquare.sideLength) // 12 +``` diff --git a/es-es/tmux-es.html.markdown b/es-es/tmux-es.html.markdown new file mode 100644 index 00000000..a7354be1 --- /dev/null +++ b/es-es/tmux-es.html.markdown @@ -0,0 +1,253 @@ +--- +category: tool +tool: tmux +contributors: + - ["mdln", "https://github.com/mdln"] +filename: LearnTmux-es.txt +translators: + - ["Damaso Sanoja", "https://github.com/damasosanoja"] +lang: es-es +--- + + +[tmux](http://tmux.sourceforge.net) +es un terminal multiplexor: habilita la creación, acceso y control +de múltiples terminales controlados desde una sola pantalla. tmux +puede ser separado de una pantalla y continuar corriendo en el fondo +y luego ser insertado nuevamente. + + +``` + + tmux [command] # Corre un comando + # 'tmux' sin comandos creará una nueva sesión + + new # Crea una nueva sesión + -s "Session" # Crea sesión con nombre + -n "Window" # Crea ventana con nombre + -c "/dir" # Comienza en el directorio destino + + attach # Adjunta sesión última/disponible + -t "#" # Adjunta sesión destino + -d # Separa la sesión de otras instancias + + ls # Lista las sesiones abiertas + -a # Lista todas las sesiones abiertas + + lsw # Lista las ventanas + -a # Lista todas las ventanas + -s # Lista todas las ventanas en la sesión + + lsp # Lista los páneles + -a # Lista todos los páneles + -s # Lista todos los páneles de la sesión + -t # Lista los páneles de aplicación en el destino + + kill-window # Cierra la ventana actual + -t "#" # Cierra la ventana destino + -a # Cierra todas las ventanas + -a -t "#" # Cierra todas las ventanas menos el destino + + kill-session # Cierra la sesión actual + -t "#" # Cierra la sesión destino + -a # Cierra todas las sesiones + -a -t "#" # Cierra todas las sesiones menos el destino + +``` + + +### Atajos de Teclado + +El método para controlar una sesión adjunta tmux es mediante +combinaciones de teclas llamadas teclas 'Prefijo'. + +``` +---------------------------------------------------------------------- + (C-b) = Ctrl + b # combinación 'Prefijo' necesaria para usar atajos + + (M-1) = Meta + 1 -o- Alt + 1 +---------------------------------------------------------------------- + + ? # Lista todos los atajos de teclado + : # Entra en la línea de comandos tmux + r # Fuerza el redibujado del cliente adjuntado + c # Crea una nueva ventana + + ! # Separa el panel actual fuera de la ventana. + % # Separa el panel actual en dos, izquierdo y derecho + " # Separa el panel actual en dos, superior e inferior + + n # Cambia a la siguiente ventana + p # Cambia a la ventana previa + { # Intercambia el panel actual con el anterior + } # Intercambia el panel actual con el próximo + + s # Selecciona una nueva sesión para el cliente adjuntado + interactivamente + w # Elegir la ventana actual interactivamente + 0 al 9 # Seleccionar ventanas 0 al 9 + + d # Separa el cliente actual + D # Elige un cliente para separar + + & # Cierra la ventana actual + x # Cierra el panel actual + + Up, Down # Cambia al panel superior, inferior, izquierdo, o derecho + Left, Right + + M-1 to M-5 # Organizar páneles: + # 1) uniformes horizontales + # 2) uniformes verticales + # 3) principal horizontal + # 4) principal vertical + # 5) mozaico + + C-Up, C-Down # Redimensiona el panel actual en pasos de una celda + C-Left, C-Right + + M-Up, M-Down # Redimensiona el panel actual en pasos de cinco celdas + M-Left, M-Right + +``` + + +### Configurando ~/.tmux.conf + +tmux.conf puede usarse para establecer opciones automáticas al arrancar, parecido a como .vimrc o init.el hacen. + +``` +# Ejemplo de tmux.conf +# 2014.10 + + +### General +########################################################################### + +# Habilita UTF-8 +setw -g utf8 on +set-option -g status-utf8 on + +# Fuera de pantalla/Historia límite +set -g history-limit 2048 + +# Comienzo de índice +set -g base-index 1 + +# Ratón +set-option -g mouse-select-pane on + +# Forza recarga de fichero de configuración +unbind r +bind r source-file ~/.tmux.conf + + +### Atajos de teclado +########################################################################### + +# Desvincula C-b como el prefijo por defecto +unbind C-b + +# Establece el nuevo prefijo +set-option -g prefix ` + +# Regresa a la ventana previa cuando el prefijo es accionado dos veces +bind C-a last-window +bind ` last-window + +# Permite intercambiar C-a y ` usando F11/F12 +bind F11 set-option -g prefix C-a +bind F12 set-option -g prefix ` + +# Preferencias de atajos +setw -g mode-keys vi +set-option -g status-keys vi + +# Moviéndose entre paneles con movimientos de teclas vim +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + +# Ciclo/Intercambio de Ventana +bind e previous-window +bind f next-window +bind E swap-window -t -1 +bind F swap-window -t +1 + +# División rápida de paneles +bind = split-window -h +bind - split-window -v +unbind '"' +unbind % + +# Activar sesión mas interna (cuando se anida tmux) para enviar comandos +bind a send-prefix + + +### Temas +########################################################################### + +# Paleta de Colores de la Barra de estado +set-option -g status-justify left +set-option -g status-bg black +set-option -g status-fg white +set-option -g status-left-length 40 +set-option -g status-right-length 80 + +# Paleta de Colores del Borde del Panel +set-option -g pane-active-border-fg green +set-option -g pane-active-border-bg black +set-option -g pane-border-fg white +set-option -g pane-border-bg black + +# Paleta de Colores de Mensajes +set-option -g message-fg black +set-option -g message-bg green + +# Paleta de Colores de la Ventana +setw -g window-status-bg black +setw -g window-status-current-fg green +setw -g window-status-bell-attr default +setw -g window-status-bell-fg red +setw -g window-status-content-attr default +setw -g window-status-content-fg yellow +setw -g window-status-activity-attr default +setw -g window-status-activity-fg yellow + + +### UI +########################################################################### + +# Notificación +setw -g monitor-activity on +set -g visual-activity on +set-option -g bell-action any +set-option -g visual-bell off + +# Establece automáticamente títulos de ventanas +set-option -g set-titles on +set-option -g set-titles-string '#H:#S.#I.#P #W #T' # window number,program name,active (or not) + +# Ajustes de barra de estado +set -g status-left "#[fg=red] #H#[fg=green]:#[fg=white]#S#[fg=green] |#[default]" + +# Muestra indicadores de rendimiento en barra de estado +# Requiere https://github.com/thewtex/tmux-mem-cpu-load/ +set -g status-interval 4 +set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] | #[fg=cyan]%H:%M #[default]" + +``` + + +### Referencias + +[Tmux | Inicio](http://tmux.sourceforge.net) + +[Tmux Manual](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux) + +[Gentoo Wiki](http://wiki.gentoo.org/wiki/Tmux) + +[Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux) + +[Mostrar CPU/MEM % en barra de estado](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux) diff --git a/es-es/yaml-es.html.markdown b/es-es/yaml-es.html.markdown index a5157b5d..cd3143fb 100644 --- a/es-es/yaml-es.html.markdown +++ b/es-es/yaml-es.html.markdown @@ -4,6 +4,7 @@ lang: es-es filename: learnyaml-es.yaml contributors: - ["Adam Brenecki", "https://github.com/adambrenecki"] + - ["Everardo Medina","https://github.com/everblut"] translators: - ["Daniel Zendejas","https://github.com/DanielZendejas"] --- @@ -14,7 +15,7 @@ leído y escrito por humanos. Basa su funcionalidad en JSON, con la adición de líneas nuevas e indentación inspirada en Python. A diferencia de Python, YAML -no permite tabs literales. +no permite tabulaciones literales. ```yaml # Los comentarios en YAML se ven así. @@ -38,97 +39,177 @@ llave con espacios: valor llave: "Un string, entre comillas." "Las llaves tambien pueden estar entre comillas.": "valor entre comillas" -# Los strings de líneas múltiples pueden ser escritos +# Los strings de líneas múltiples pueden ser escritos # como un 'bloque literal' (usando pipes |) # o como un 'bloque doblado' (usando >) bloque_literal: | Este bloque completo de texto será preservado como el valor de la llave 'bloque_literal', incluyendo los saltos de línea. - - Se continúa guardando la literal hasta que se cese la indentación. + + Se continúa guardando la literal hasta que se cese la indentación. Cualquier línea que tenga más indentación, mantendrá los espacios dados (por ejemplo, estas líneas se guardarán con cuatro espacios) -nloque_doblado: > +bloque_doblado: > De la misma forma que el valor de 'bloque_literal', todas estas líneas se guardarán como una sola literal, pero en esta ocasión todos los saltos de línea serán reemplazados por espacio. - Las líneas en blanco, como la anterior, son convertidos a un salto de línea. + Las líneas en blanco, como la anterior, son convertidas a un salto de línea. Las líneas con mayor indentación guardan sus saltos de línea. Esta literal ocuparán dos líneas. -######################## -# TIPOS DE COLECCIONES # -######################## - -# La indentación se usa para anidar. +# La indentación se usa para anidar elementos un_mapa_indentado: llave: valor otra_llave: otro valor otro_mapa_indentado: llave_interna: valor_interno -# Las llaves de los mapas no deben ser strings necesariamente +# Las llaves de los mapas no requieren ser strings necesariamente 0.25: una llave numérica -# Las llaves también pueden ser objetos de multi línea, usando ? para indicar -# el inicio de una llave +# Las llaves también pueden ser objetos de multiples líneas, +# usando ? para indicar el inicio de una llave ? | Esto es una llave que tiene múltiples líneas : y este es su valor -# YAML tambien permite colecciones como llaves, pero muchos lenguajes de +######################## +# TIPOS DE COLECCIONES # +######################## + +# Las colecciones en YAML usan la indentación para delimitar el alcance +# y cada elemento de la colección inicia en su propia línea. +# YAML tambien permite colecciones como llaves, pero muchos lenguajes de # programación se quejarán. # Las secuencias (equivalentes a listas o arreglos) se ven así: -una_secuencia: - - Item 1 - - Item 2 - - 0.5 # las secuencias pueden tener distintos tipos en su contenido. - - Item 4 - - llave: valor - otra_llave: otro_valor +- Amarillo +- Verde +- Azul + +# Se puede usar una secuencia como valor para una llave. +secuencia: + - Elemento 1 + - Elemento 2 + - Elemento 3 + - Elemento 4 + +# Las secuencias pueden contener secuencias como elementos. +- [Uno, Dos, Tres] +- [Domingo, Lunes, Martes] +- [Luna, Marte, Tierra] + +# Las secuencias pueden tener distintos tipos en su contenido. +secuencia_combinada: + - texto + - 5 + - 0.6 + - llave: valor # se convierte en un json dentro de la secuencia - - Esta es una secuencia - ...dentro de otra secuencia -# Dado que todo JSON está incluído dentro de YAML, también puedes escribir -# mapas con la sintaxis de JSON y secuencias: -mapa_de_json: {"llave": "valor"} -secuencia_de_json: [3, 2, 1, "despegue"] +# Dado que todo JSON está incluído dentro de YAML, también puedes escribir +# mapas con la sintaxis de JSON y secuencias: +mapa_de_json_1: {"llave": "valor"} +mapa_de_json_2: + llave: valor + +# Las secuencias tambien se pueden escribir como un arreglo al estilo JSON +secuencia_de_json_1: [3, 2, 1, "despegue"] +secuencia_de_json_2: + - 3 + - 2 + - 1 + - "despegue" + +# YAML también soporta conjuntos usando el simbolo ? +# y se ven de la siguiente forma: +set: + ? item1 + ? item2 + ? item3 + +# Se puede usar el tag !!set +# Al igual que Python, los conjuntos sólo son mapas con valores nulos. +# El ejemplo de arriba es equivalente a: +set2: + item1: null + item2: null + item3: null ################################## # CARACTERÍSTICAS EXTRAS DE YAML # ################################## +# YAML usa tres guiones (---) para diferenciar entre directivas +# y contenido del documento. +# Por otra parte, tres puntos (...) se utilizan para indicar +# el final del documento en casos especiales. + # YAML tiene funciones útiles llamadas 'anchors' (anclas), que te permiten -# duplicar fácilmente contenido a lo largo de tu documento. En el ejemplo -# a continuación, ambas llaves tendrán el mismo valor: -contenido_anclado: &nombre_del_ancla Este string será el valor de las llaves -otra_ancla: *nombre_del_ancla - -# YAML también tiene tags, que puedes usar para declarar tipos explícitamente. -string_explícito: !!str 0.5 -# Algunos parseadores implementar tags específicas del lenguaje, como el +# duplicar fácilmente contenido a lo largo de tu documento. +# El ampersand indica la declaración del ancla, +declara_ancla: &texto texto de la llave +# el asterisco indica el uso de dicha ancla. +usa_ancla: *texto # tendrá el valor "texto de la llave" + +################ +# TAGS EN YAML # +################ + +# En YAML, los nodos que no tienen un tag obtienen su tipo +# según la aplicación que los use, al usar un tag +# se pueden declarar tipos explícitamente. +string_explicito: !!str 0.5 # !!str para declarar un string +integer_explicito: !!int 5 # !!int para declarar un integer +float_explicito: !!float 1.2 # !!float para declarar un float +conjunto_explicito: !!set # !!set para declarar un conjunto + ? Uno + ? Dos + ? Tres +mapa_ordenado_explicito: !!omap # !!omap para declarar un mapa ordenado +- Primero: 1 +- Segundo: 2 +- Tercero: 3 +- Cuarto: 4 + +# Tags para los numeros enteros +llave_canonica: 5222 +llave_decimal: +5222 +llave_octal: 010 +llave_hexadecimal: 0xC + +#Tags para los numeros flotantes +llave_canonica: 1.215e+3 +llave_exponencial: 12.3555e+02 +llave_fija: 12.15 +llave_negativa_infinita: -.inf +llave_numero_invalido: .NaN + +# Tags para las fechas y horas +llave_canonica: 2001-12-15T02:59:43.1Z +llave_iso8601: 2001-12-14t21:59:43.10-05:00 +llave_con_espacios: 2001-12-14 21:59:43.10 -5 +llave_fecha: 2002-12-14 + +# Además existen tags para +null: #valor nulo +booleans: [ true, false ] # Valores booleanos +string: '012345' # Valor en string + + +# Algunos parseadores implementan tags específicas del lenguaje, como el # que se muestra a continuación, encargado de manejar números complejos en # Python: numero_complejo_python: !!python/complex 1+2j -######################## -# TIPOS EXTRAS EN YAML # -######################## - -# Stirngs y números no son los únicos escalares que YAML puede entener. -# YAML también puede parsear fechas en formato ISO . -fechaHora: 2001-12-15T02:59:43.1Z -fechaHora_con_espacios: 2001-12-14 21:59:43.10 -5 -fecha: 2002-12-14 - -# La tag !!binary indica que un string es, en realidad, un blob +# El tag !!binary indica que un string es en realidad un blob # representado en base-64. archivo_gif: !!binary | R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 @@ -136,16 +217,10 @@ archivo_gif: !!binary | +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= -# YAML también tiene un tipo set, que se ve de la siguiente forma: -set: - ? item1 - ? item2 - ? item3 - -# Al igual que Python, los sets sólo son mapas con valores nulos. -# El ejemplo de arriba es equivalente a: -set2: - item1: null - item2: null - item3: null ``` + +### Recursos adicionales + ++ [Sitio oficial de YAML](http://yaml.org/) ++ [Parser en línea de de YAML](http://yaml-online-parser.appspot.com/) ++ [Validador en línea de YAML](http://codebeautify.org/yaml-validator) |